Spaces:
Running
Running
| """图片修正测试端点:POST /v1/xtc/image/fix/test | |
| 输入:image (data URL 或 URL) + mode | |
| 输出:处理后的图片二进制(PNG) | |
| """ | |
| from __future__ import annotations | |
| import base64 | |
| import io | |
| from typing import Optional | |
| import httpx | |
| from fastapi import APIRouter, Depends | |
| from fastapi.responses import Response | |
| from pydantic import BaseModel | |
| from ..auth import require_access_key | |
| from ..errors import HttpError | |
| from ..media.imagefix import VALID_MODES, fix_image_bytes, parse_data_url | |
| from ._common import CORS_HEADERS | |
| router = APIRouter(prefix="/v1/xtc/image/fix", tags=["image-fix"]) | |
| class FixTestBody(BaseModel): | |
| image: str | |
| mode: str | |
| camera_facing: Optional[str] = None | |
| async def fix_test( | |
| body: FixTestBody, | |
| _key: str = Depends(require_access_key), | |
| ) -> Response: | |
| if body.mode not in VALID_MODES: | |
| raise HttpError( | |
| f"invalid mode, must be one of {sorted(VALID_MODES)}", | |
| status=400, | |
| code="bad_request", | |
| ) | |
| image_url = body.image | |
| if image_url.startswith("data:"): | |
| _, raw = parse_data_url(image_url) | |
| if not raw: | |
| raise HttpError("invalid data URL", status=400, code="bad_request") | |
| else: | |
| # 拉取远程图片 | |
| try: | |
| async with httpx.AsyncClient(timeout=30.0) as c: | |
| resp = await c.get(image_url) | |
| resp.raise_for_status() | |
| raw = resp.content | |
| except httpx.HTTPError as e: | |
| raise HttpError(f"failed to fetch image: {e}", status=502, code="bad_gateway") from e | |
| try: | |
| out = fix_image_bytes(raw, body.mode) | |
| except Exception as e: | |
| raise HttpError(f"image fix failed: {e}", status=500, code="internal_error") from e | |
| return Response( | |
| content=out, | |
| media_type="image/png", | |
| headers={ | |
| **CORS_HEADERS, | |
| "Cache-Control": "no-store", | |
| "x-xtc-image-fix-mode": body.mode, | |
| }, | |
| ) | |