diff --git a/main.py b/main.py index a47d6b7..9dc3835 100644 --- a/main.py +++ b/main.py @@ -102,7 +102,9 @@ async def try_on( if AUTH_KEY: client_key = request.headers.get("X-AIFIT-Key") if not client_key or client_key != AUTH_KEY: - raise HTTPException(status_code=401, detail="Invalid or missing authentication key") + raise HTTPException( + status_code=401, detail="Invalid or missing authentication key" + ) # ---- Read files ---- user_bytes = await user_photo.read() @@ -124,7 +126,9 @@ async def try_on( metadata_text = json.dumps(meta, indent=2, ensure_ascii=False) # Try common key names for the UUID - request_id = meta.get("request_id") or meta.get("id") or meta.get("uuid") + request_id = ( + meta.get("request_id") or meta.get("id") or meta.get("uuid") + ) # ---- Dynamic behavior based on bottom/top type ---- extra_sections = [] @@ -151,8 +155,12 @@ SPECIAL RULE FOR SHORTS (INSANELY STRICT, ZERO TOLERANCE – DO NOT IGNORE): ) # Top: t-shirt / tee / short-sleeve - # We try a few common keys: "top", "upper", "outer_layer" - top = meta.get("top") or meta.get("upper") or meta.get("outer_layer") or {} + top = ( + meta.get("top") + or meta.get("upper") + or meta.get("outer_layer") + or {} + ) top_type = (top.get("type") or "").lower() if any( @@ -184,7 +192,7 @@ SPECIAL RULE FOR T-SHIRT / TOP (EXTREMELY STRICT, ZERO TOLERANCE): except Exception: metadata_text = metadata.strip() - # ---- Build Prompt (new, strict, merged version) ---- + # ---- Build Prompt (new, ultra strict version) ---- prompt = f""" You are performing a **strict outfit replacement operation** on the FIRST image using the clothing and accessories from the SECOND image and the metadata provided. @@ -196,7 +204,7 @@ You are performing a **strict outfit replacement operation** on the FIRST image ----------------------------------------------------- 🚨 ULTRA-HARD IDENTITY LOCK (ABSOLUTE, NON-NEGOTIABLE RULES) -These identity rules are STRONGER than all other instructions: +These identity rules are STRONGER than all other instructions. If you cannot follow them, you MUST NOT output an image. - The person in the FIRST image is the ONLY person you are allowed to show in the final image. - You MUST keep the FIRST image person's: @@ -204,24 +212,29 @@ These identity rules are STRONGER than all other instructions: • identity • skin tone • facial structure - • hair style and color + • jawline and chin shape + • nose shape + • lips and mouth shape + • facial hair (beard / moustache) style and density + • hair style and hairline + • ears • body proportions • pose EXACTLY as they are. ABSOLUTE FACE LOCK (READ-ONLY REGION): -- Treat the entire face, head, and visible neck area of the FIRST image as a **READ-ONLY REGION**. +- Treat the entire face, head, ears, and visible neck area of the FIRST image as a **READ-ONLY REGION**. - You MUST NOT re-render, redraw, regenerate, beautify, smooth, reshape, de-age, re-gender, or otherwise alter the face in any way. -- You MUST preserve: - • exact facial geometry - • exact expression - • exact lighting on the face - • exact shadows and contrast on the face - • exact skin texture and tone on the face -- The face region in the final image must be **indistinguishable from the original**, - except for areas physically occluded by clothing (e.g. collar at the neck). +- You MUST NOT change: + • beard thickness or shape + • moustache presence or shape + • hairline or hairstyle + • skin texture or tone on the face + • teeth alignment or smile shape +- The face region in the final image must be **indistinguishable** from the original FIRST image, + except for tiny unavoidable differences at the clothing boundaries (e.g. collar touching neck). IDENTITY FAILURE CONDITION: @@ -238,7 +251,8 @@ IDENTITY FAILURE CONDITION: • beautify, smooth, reshape, de-age, re-gender, or re-style the face, • swap the person with someone else, • blend or mix the FIRST and SECOND person, - • recreate a new face that only "resembles" the original. + • recreate a new face that only "resembles" the original, + • copy the second person's moustache, beard, jawline, nose, or hairstyle. If there is ANY conflict between clothing instructions and identity protection: YOU MUST PROTECT THE FIRST PERSON'S IDENTITY and only adjust clothing areas. @@ -251,6 +265,7 @@ If identity cannot be preserved, DO NOT generate an image. - You must treat the SECOND person as a "clothing mannequin" ONLY. - You are **STRICTLY FORBIDDEN** from copying: • their face + • their moustache or beard • their skin tone • their hair • their body shape @@ -441,7 +456,11 @@ SECOND image = outfit_photo (outfit reference). ) except Exception as e: error_msg = str(e) - if "API key" in error_msg or "INVALID_ARGUMENT" in error_msg or "API_KEY" in error_msg: + if ( + "API key" in error_msg + or "INVALID_ARGUMENT" in error_msg + or "API_KEY" in error_msg + ): raise HTTPException( status_code=401, detail=( @@ -450,6 +469,7 @@ SECOND image = outfit_photo (outfit reference). ), ) import traceback + print(f"[ERROR] Gemini API error: {error_msg}") print(traceback.format_exc()) raise HTTPException(status_code=502, detail=f"Gemini error: {error_msg}") @@ -466,7 +486,9 @@ SECOND image = outfit_photo (outfit reference). print(f"[DEBUG] Safety ratings: {getattr(cand, 'safety_ratings', None)}") if hasattr(cand, "content") and getattr(cand.content, "parts", None): - print(f"[DEBUG] Parts in first candidate ({len(cand.content.parts)} total):") + print( + f"[DEBUG] Parts in first candidate ({len(cand.content.parts)} total):" + ) for i, part in enumerate(cand.content.parts): part_type = type(part).__name__ print(f" Part {i}: type={part_type}") @@ -480,7 +502,9 @@ SECOND image = outfit_photo (outfit reference). if inline: data_size = len(getattr(inline, "data", b"")) mime = getattr(inline, "mime_type", "unknown") - print(f" INLINE_DATA: mime={mime}, size={data_size} bytes") + print( + f" INLINE_DATA: mime={mime}, size={data_size} bytes" + ) if hasattr(part, "blob"): blob = part.blob