import requests import json import urllib.parse from concurrent.futures import ThreadPoolExecutor BASE_URL = "http://localhost:7890" def process_avatar(char): name = char.get("name") if name in ["Marcian", "Nyrilla", "Arthag", "Lysandra", "Darrag", "Himgi"]: return # Skip ones we already fixed perfectly char_id = urllib.parse.quote(char["id"]) sheet = char.get("sheet") or {} if isinstance(sheet, str): try: sheet = json.loads(sheet) except: sheet = {} phys = sheet.get('physical', '') cloth = sheet.get('clothing', '') # Strict Portrait Prompt to defeat Flux's tendency to draw turnaround sheets portrait_prompt = f"A beautiful tight headshot portrait of {name}. Physical traits: {phys}. Clothing: {cloth}. Style: high quality painterly fantasy illustration, single face facing forward. Plain neutral parchment background. ONLY ONE PERSON, close-up on face and shoulders, NO MULTIPLE VIEWS, NO concept art sheet." print(f"[{name}] Starting avatar fix...") # Generate Portrait try: resp_img = requests.post(f"{BASE_URL}/api/character-generate-image", json={"prompt": portrait_prompt}) if resp_img.ok: char["image"] = resp_img.json().get("image") sheet["image_prompt"] = portrait_prompt char["sheet"] = sheet resp_put = requests.put(f"{BASE_URL}/api/characters/{char_id}", json=char) print(f"[{name}] Finished. Status: {resp_put.status_code}") else: print(f"[{name}] Failed to generate: {resp_img.text}") except Exception as e: print(f"Error portrait {name}: {e}") def main(): resp = requests.get(f"{BASE_URL}/api/characters") characters = resp.json().get("characters", []) to_process = [c for c in characters if c.get("name") not in ["Marcian", "Nyrilla", "Arthag", "Lysandra", "Darrag", "Himgi"]] print(f"Processing {len(to_process)} avatars...") # Use 1 worker to avoid rate limits with ThreadPoolExecutor(max_workers=1) as executor: executor.map(process_avatar, to_process) if __name__ == "__main__": main()