| Server IP : 3.147.158.171 / Your IP : 216.73.216.229 Web Server : Apache/2.4.67 (Amazon Linux) OpenSSL/3.5.5 System : Linux ip-172-31-2-178.us-east-2.compute.internal 6.1.172-216.329.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed May 20 06:31:34 UTC 2026 x86_64 User : ec2-user ( 1000) PHP Version : 8.4.21 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /tsai/www/html/api.turmansolutions.ai/scripts/ |
Upload File : |
"""
Suggest and Create WordPress Categories
Reads characters for a site from Drupal, uses an LLM to suggest relevant
WordPress categories based on character data and a site description, then
creates the accepted categories in WordPress.
Usage:
cd api
python scripts/suggest_categories.py --site jpt --description "A blog about AI and technology"
python scripts/suggest_categories.py --env production --site tsai --description "..." --max-categories 20
"""
import argparse
import os
import sys
from pathlib import Path
# Parse args BEFORE any app imports so TSAI_ENV is set correctly
parser = argparse.ArgumentParser(description='Suggest and create WordPress categories for a site')
parser.add_argument(
'--env',
choices=['development', 'production', 'scike_ai'],
default=os.getenv('TSAI_ENV', 'development'),
help='Environment (default: TSAI_ENV or development)'
)
parser.add_argument('--site', required=True, help='Site slug (e.g. jpt, tsai, scike)')
parser.add_argument('--description', required=True, help='Brief description of the site\'s purpose')
parser.add_argument('--max-categories', type=int, default=15, help='Max categories to suggest (default: 15)')
args = parser.parse_args()
os.environ['TSAI_ENV'] = args.env
from dotenv import load_dotenv
API_DIR = Path(__file__).resolve().parent.parent
load_dotenv(dotenv_path=API_DIR / '.env')
os.environ['TSAI_ENV'] = args.env
sys.path.insert(0, str(API_DIR))
import logging
import requests as http_requests
from app.services.site_config_service import SiteConfigService
from app.services.wp import WpService
logging.basicConfig(level=logging.WARNING, format='%(levelname)s: %(message)s')
API_BASE = 'http://localhost:8000/api/v1'
def main():
site_config_service = SiteConfigService()
wp_service = WpService()
site = site_config_service.get_site_by_slug(args.site)
if not site:
print(f'Error: site "{args.site}" not found in {args.env} config.')
sys.exit(1)
print(f'\nFetching category suggestions for site: {site.slug} ({site.wp_host})')
print(f'Site description: {args.description}')
print(f'Requesting up to {args.max_categories} categories...\n')
origin = site.cb_host if site.cb_host.startswith('http') else f'https://{site.cb_host}'
response = http_requests.post(
f'{API_BASE}/cms/suggest-categories/',
json={'site_description': args.description, 'max_categories': args.max_categories},
headers={'Origin': origin},
timeout=60,
)
if response.status_code != 200:
print(f'Error from API: {response.status_code} {response.text}')
sys.exit(1)
categories: list[str] = response.json().get('categories', [])
if not categories:
print('No categories returned.')
sys.exit(0)
print('Suggested categories:')
for i, name in enumerate(categories, 1):
print(f' {i:2}. {name}')
print('\nEnter numbers to create (comma-separated), "all" to create all, or "q" to quit:')
choice = input('> ').strip().lower()
if choice == 'q' or choice == '':
print('Aborted.')
sys.exit(0)
if choice == 'all':
selected = categories
else:
indices = []
for part in choice.split(','):
part = part.strip()
if part.isdigit():
idx = int(part) - 1
if 0 <= idx < len(categories):
indices.append(idx)
else:
print(f' Skipping invalid number: {part}')
else:
print(f' Skipping invalid input: {part}')
selected = [categories[i] for i in indices]
if not selected:
print('Nothing selected.')
sys.exit(0)
print(f'\nCreating {len(selected)} categories in WordPress...')
created = 0
failed = 0
for name in selected:
result = wp_service.create_category(site, name)
if result:
print(f' ✓ {name}')
created += 1
else:
print(f' ✗ {name} (failed — may already exist)')
failed += 1
print(f'\nDone: {created} created, {failed} failed.')
if __name__ == '__main__':
main()