update main.py

This commit is contained in:
Hossein 2025-11-30 19:46:29 +03:30
parent 5d9e9f286b
commit 78a0579039

64
main.py
View File

@ -102,7 +102,9 @@ async def try_on(
if AUTH_KEY: if AUTH_KEY:
client_key = request.headers.get("X-AIFIT-Key") client_key = request.headers.get("X-AIFIT-Key")
if not client_key or client_key != AUTH_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 ---- # ---- Read files ----
user_bytes = await user_photo.read() user_bytes = await user_photo.read()
@ -124,7 +126,9 @@ async def try_on(
metadata_text = json.dumps(meta, indent=2, ensure_ascii=False) metadata_text = json.dumps(meta, indent=2, ensure_ascii=False)
# Try common key names for the UUID # 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 ---- # ---- Dynamic behavior based on bottom/top type ----
extra_sections = [] extra_sections = []
@ -151,8 +155,12 @@ SPECIAL RULE FOR SHORTS (INSANELY STRICT, ZERO TOLERANCE DO NOT IGNORE):
) )
# Top: t-shirt / tee / short-sleeve # Top: t-shirt / tee / short-sleeve
# We try a few common keys: "top", "upper", "outer_layer" top = (
top = meta.get("top") or meta.get("upper") or meta.get("outer_layer") or {} meta.get("top")
or meta.get("upper")
or meta.get("outer_layer")
or {}
)
top_type = (top.get("type") or "").lower() top_type = (top.get("type") or "").lower()
if any( if any(
@ -184,7 +192,7 @@ SPECIAL RULE FOR T-SHIRT / TOP (EXTREMELY STRICT, ZERO TOLERANCE):
except Exception: except Exception:
metadata_text = metadata.strip() metadata_text = metadata.strip()
# ---- Build Prompt (new, strict, merged version) ---- # ---- Build Prompt (new, ultra strict version) ----
prompt = f""" 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. 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) 🚨 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. - 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: - You MUST keep the FIRST image person's:
@ -204,24 +212,29 @@ These identity rules are STRONGER than all other instructions:
identity identity
skin tone skin tone
facial structure 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 body proportions
pose pose
EXACTLY as they are. EXACTLY as they are.
ABSOLUTE FACE LOCK (READ-ONLY REGION): 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, - You MUST NOT re-render, redraw, regenerate, beautify, smooth, reshape, de-age, re-gender,
or otherwise alter the face in any way. or otherwise alter the face in any way.
- You MUST preserve: - You MUST NOT change:
exact facial geometry beard thickness or shape
exact expression moustache presence or shape
exact lighting on the face hairline or hairstyle
exact shadows and contrast on the face skin texture or tone on the face
exact skin texture and tone on the face teeth alignment or smile shape
- The face region in the final image must be **indistinguishable from the original**, - The face region in the final image must be **indistinguishable** from the original FIRST image,
except for areas physically occluded by clothing (e.g. collar at the neck). except for tiny unavoidable differences at the clothing boundaries (e.g. collar touching neck).
IDENTITY FAILURE CONDITION: IDENTITY FAILURE CONDITION:
@ -238,7 +251,8 @@ IDENTITY FAILURE CONDITION:
beautify, smooth, reshape, de-age, re-gender, or re-style the face, beautify, smooth, reshape, de-age, re-gender, or re-style the face,
swap the person with someone else, swap the person with someone else,
blend or mix the FIRST and SECOND person, 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: If there is ANY conflict between clothing instructions and identity protection:
YOU MUST PROTECT THE FIRST PERSON'S IDENTITY and only adjust clothing areas. 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 must treat the SECOND person as a "clothing mannequin" ONLY.
- You are **STRICTLY FORBIDDEN** from copying: - You are **STRICTLY FORBIDDEN** from copying:
their face their face
their moustache or beard
their skin tone their skin tone
their hair their hair
their body shape their body shape
@ -441,7 +456,11 @@ SECOND image = outfit_photo (outfit reference).
) )
except Exception as e: except Exception as e:
error_msg = str(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( raise HTTPException(
status_code=401, status_code=401,
detail=( detail=(
@ -450,6 +469,7 @@ SECOND image = outfit_photo (outfit reference).
), ),
) )
import traceback import traceback
print(f"[ERROR] Gemini API error: {error_msg}") print(f"[ERROR] Gemini API error: {error_msg}")
print(traceback.format_exc()) print(traceback.format_exc())
raise HTTPException(status_code=502, detail=f"Gemini error: {error_msg}") 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)}") print(f"[DEBUG] Safety ratings: {getattr(cand, 'safety_ratings', None)}")
if hasattr(cand, "content") and getattr(cand.content, "parts", 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): for i, part in enumerate(cand.content.parts):
part_type = type(part).__name__ part_type = type(part).__name__
print(f" Part {i}: type={part_type}") print(f" Part {i}: type={part_type}")
@ -480,7 +502,9 @@ SECOND image = outfit_photo (outfit reference).
if inline: if inline:
data_size = len(getattr(inline, "data", b"")) data_size = len(getattr(inline, "data", b""))
mime = getattr(inline, "mime_type", "unknown") 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"): if hasattr(part, "blob"):
blob = part.blob blob = part.blob