[diffusion] http-server: relax openai image endpoint's strict content_type limit (#15717)
This commit is contained in:
@@ -104,14 +104,15 @@ curl -sS -X POST "http://localhost:30010/v1/images/generations" \
|
|||||||
|
|
||||||
**Endpoint:** `POST /v1/images/edits`
|
**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):**
|
**Curl Example (b64_json response):**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sS -X POST "http://localhost:30010/v1/images/edits" \
|
curl -sS -X POST "http://localhost:30010/v1/images/edits" \
|
||||||
-H "Authorization: Bearer sk-proj-1234567890" \
|
-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 "prompt=A calico cat playing a piano on stage" \
|
||||||
-F "size=1024x1024" \
|
-F "size=1024x1024" \
|
||||||
-F "response_format=b64_json"
|
-F "response_format=b64_json"
|
||||||
@@ -122,7 +123,8 @@ curl -sS -X POST "http://localhost:30010/v1/images/edits" \
|
|||||||
```bash
|
```bash
|
||||||
curl -sS -X POST "http://localhost:30010/v1/images/edits" \
|
curl -sS -X POST "http://localhost:30010/v1/images/edits" \
|
||||||
-H "Authorization: Bearer sk-proj-1234567890" \
|
-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 "prompt=A calico cat playing a piano on stage" \
|
||||||
-F "size=1024x1024" \
|
-F "size=1024x1024" \
|
||||||
-F "response_format=url"
|
-F "response_format=url"
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ async def _save_upload_to_path(upload: UploadFile, target_path: str) -> str:
|
|||||||
return target_path
|
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):
|
if not isinstance(img_url, str):
|
||||||
return None
|
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)
|
os.makedirs(os.path.dirname(target_path), exist_ok=True)
|
||||||
|
|
||||||
try:
|
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 = await client.get(image_url, timeout=10.0)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
# Determine file extension from content type or URL after downloading
|
# Determine file extension from content type or URL after downloading
|
||||||
if not os.path.splitext(target_path)[1]:
|
if not os.path.splitext(target_path)[1]:
|
||||||
content_type = response.headers.get("content-type", "")
|
content_type = response.headers.get("content-type", "").lower()
|
||||||
if not content_type.startswith("image/"):
|
|
||||||
|
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(
|
raise ValueError(
|
||||||
f"URL does not point to an image. Content-Type: {content_type}"
|
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}"
|
target_path = f"{target_path}{ext}"
|
||||||
|
|
||||||
with open(target_path, "wb") as f:
|
with open(target_path, "wb") as f:
|
||||||
|
|||||||
Reference in New Issue
Block a user