auto-save 2026-05-13 09:54 (~3)
This commit is contained in:
90
api/main.py
90
api/main.py
@@ -660,7 +660,7 @@ def generate_image(job_id: str, idx: int, req: GenerateReq) -> Job:
|
||||
if req.extra_prompt.strip():
|
||||
full_prompt = f"{full_prompt}. Include: {req.extra_prompt.strip()}"
|
||||
if req.negative_prompt.strip():
|
||||
full_prompt = f"{full_prompt}. Do NOT include: {req.negative_prompt.strip()}. Output must be clean without any watermark, username text, or platform logo."
|
||||
full_prompt = f"{full_prompt}. Avoid: {req.negative_prompt.strip()}"
|
||||
if not full_prompt:
|
||||
raise HTTPException(400, "prompt required")
|
||||
|
||||
@@ -669,42 +669,66 @@ def generate_image(job_id: str, idx: int, req: GenerateReq) -> Job:
|
||||
|
||||
import base64 as b64lib
|
||||
import time as _time
|
||||
import httpx
|
||||
|
||||
try:
|
||||
if req.mode == "edit":
|
||||
# image-to-image:用 generations 端点带 image 参数
|
||||
img_b64 = b64lib.b64encode(frame_path.read_bytes()).decode("ascii")
|
||||
data_uri = f"data:image/jpeg;base64,{img_b64}"
|
||||
# OpenAI SDK 不直接支持 image 参数,用底层 httpx
|
||||
import httpx
|
||||
with httpx.Client(timeout=120) as client:
|
||||
r = client.post(
|
||||
f"{LLM_BASE_URL}/images/generations",
|
||||
headers={
|
||||
"Authorization": f"Bearer {LLM_API_KEY}",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
json={
|
||||
"model": model,
|
||||
"prompt": full_prompt,
|
||||
"image": data_uri,
|
||||
"n": 1,
|
||||
},
|
||||
)
|
||||
r.raise_for_status()
|
||||
resp_data = r.json()
|
||||
else:
|
||||
# text-only
|
||||
resp = llm().images.generate(model=model, prompt=full_prompt, n=1)
|
||||
resp_data = resp.model_dump() if hasattr(resp, "model_dump") else {"data": [{"b64_json": resp.data[0].b64_json}]}
|
||||
except httpx.HTTPStatusError as e:
|
||||
raise HTTPException(500, f"image gen HTTP {e.response.status_code}: {e.response.text[:300]}")
|
||||
except Exception as e:
|
||||
raise HTTPException(500, f"image gen failed: {e}")
|
||||
img_b64: str | None = None
|
||||
if req.mode == "edit":
|
||||
img_b64 = b64lib.b64encode(frame_path.read_bytes()).decode("ascii")
|
||||
|
||||
MAX_ATTEMPTS = 3
|
||||
resp_data: dict = {}
|
||||
last_err = ""
|
||||
for attempt in range(MAX_ATTEMPTS):
|
||||
try:
|
||||
if req.mode == "edit":
|
||||
data_uri = f"data:image/jpeg;base64,{img_b64}"
|
||||
# OpenAI SDK 不直接支持 image 参数,用底层 httpx
|
||||
with httpx.Client(timeout=120) as client:
|
||||
r = client.post(
|
||||
f"{LLM_BASE_URL}/images/generations",
|
||||
headers={
|
||||
"Authorization": f"Bearer {LLM_API_KEY}",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
json={
|
||||
"model": model,
|
||||
"prompt": full_prompt,
|
||||
"image": data_uri,
|
||||
"n": 1,
|
||||
},
|
||||
)
|
||||
r.raise_for_status()
|
||||
resp_data = r.json()
|
||||
else:
|
||||
# text-only
|
||||
resp = llm().images.generate(model=model, prompt=full_prompt, n=1)
|
||||
resp_data = resp.model_dump() if hasattr(resp, "model_dump") else {"data": [{"b64_json": resp.data[0].b64_json}]}
|
||||
|
||||
if resp_data.get("data"):
|
||||
break
|
||||
err_obj = resp_data.get("error") or {}
|
||||
last_err = f"empty data · {err_obj.get('code', '')} · {str(err_obj.get('message', ''))[:200]}"
|
||||
except httpx.HTTPStatusError as e:
|
||||
body = e.response.text
|
||||
transient = (
|
||||
e.response.status_code >= 500
|
||||
or "incomplete_generation" in body
|
||||
or "rate_limit" in body
|
||||
or "timeout" in body.lower()
|
||||
)
|
||||
last_err = f"HTTP {e.response.status_code}: {body[:200]}"
|
||||
if not transient:
|
||||
raise HTTPException(500, f"image gen HTTP {e.response.status_code}: {body[:300]}")
|
||||
except Exception as e:
|
||||
last_err = f"{type(e).__name__}: {e}"
|
||||
|
||||
if attempt < MAX_ATTEMPTS - 1:
|
||||
print(f"[image gen retry {attempt + 1}/{MAX_ATTEMPTS}] {last_err}", flush=True)
|
||||
_time.sleep(1.5 * (attempt + 1))
|
||||
|
||||
data_arr = resp_data.get("data", [])
|
||||
if not data_arr:
|
||||
raise HTTPException(500, "image gen returned no data")
|
||||
raise HTTPException(500, f"image gen failed after {MAX_ATTEMPTS} attempts: {last_err}")
|
||||
|
||||
item = data_arr[0]
|
||||
b64 = item.get("b64_json")
|
||||
|
||||
Reference in New Issue
Block a user