[diffusion] http-server: relax openai image endpoint's strict content_type limit (#15717)

This commit is contained in:
Mick
2025-12-24 13:26:13 +08:00
committed by GitHub
parent 9665574937
commit dfb5357448
2 changed files with 28 additions and 15 deletions

View File

@@ -104,14 +104,15 @@ curl -sS -X POST "http://localhost:30010/v1/images/generations" \
**Endpoint:** `POST /v1/images/edits`
This endpoint accepts a multipart form upload with an input image and a text prompt. The server can return either a base64-encoded image or a URL to download the image.
This endpoint accepts a multipart form upload with input images and a text prompt. The server can return either a base64-encoded image or a URL to download the image.
**Curl Example (b64_json response):**
```bash
curl -sS -X POST "http://localhost:30010/v1/images/edits" \
-H "Authorization: Bearer sk-proj-1234567890" \
-F "image=@input.png" \
-F "image=@local_input_image.png" \
-F "url=image_url.jpg" \
-F "prompt=A calico cat playing a piano on stage" \
-F "size=1024x1024" \
-F "response_format=b64_json"
@@ -122,7 +123,8 @@ curl -sS -X POST "http://localhost:30010/v1/images/edits" \
```bash
curl -sS -X POST "http://localhost:30010/v1/images/edits" \
-H "Authorization: Bearer sk-proj-1234567890" \
-F "image=@input.png" \
-F "image=@local_input_image.png" \
-F "url=image_url.jpg" \
-F "prompt=A calico cat playing a piano on stage" \
-F "size=1024x1024" \
-F "response_format=url"

View File

@@ -64,7 +64,7 @@ async def _save_upload_to_path(upload: UploadFile, target_path: str) -> str:
return target_path
async def _maybe_url_image(img_url: str, target_path: str) -> str:
async def _maybe_url_image(img_url: str, target_path: str) -> str | None:
if not isinstance(img_url, str):
return None
@@ -86,25 +86,36 @@ async def _save_url_image_to_path(image_url: str, target_path: str) -> str:
os.makedirs(os.path.dirname(target_path), exist_ok=True)
try:
async with httpx.AsyncClient() as client:
async with httpx.AsyncClient(follow_redirects=True) as client:
response = await client.get(image_url, timeout=10.0)
response.raise_for_status()
# Determine file extension from content type or URL after downloading
if not os.path.splitext(target_path)[1]:
content_type = response.headers.get("content-type", "")
if not content_type.startswith("image/"):
content_type = response.headers.get("content-type", "").lower()
url_path = image_url.split("?")[0]
_, url_ext = os.path.splitext(url_path)
url_ext = url_ext.lower()
if url_ext in {".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp"}:
ext = ".jpg" if url_ext == ".jpeg" else url_ext
elif content_type.startswith("image/"):
if "jpeg" in content_type or "jpg" in content_type:
ext = ".jpg"
elif "png" in content_type:
ext = ".png"
elif "webp" in content_type:
ext = ".webp"
else:
ext = ".jpg" # Default to jpg
elif content_type == "application/octet-stream":
# for octet-stream, if we couldn't get it from URL, default to jpg
ext = ".jpg"
else:
raise ValueError(
f"URL does not point to an image. Content-Type: {content_type}"
)
if "jpeg" in content_type or "jpg" in content_type:
ext = ".jpg"
elif "png" in content_type:
ext = ".png"
elif "webp" in content_type:
ext = ".webp"
else:
ext = ".jpg" # Default to jpg
target_path = f"{target_path}{ext}"
with open(target_path, "wb") as f: