feat: 接入 Agnes Image 2.1 Flash 文生图/图生图 API,新增 multipart 上传端点
- utils/t2i.py 重命名为 utils/mm_api_t2i.py(内容不变) - 新增 utils/agnes_image.py: Agnes 文生图/图生图/多图合成,含 size+ratio 解析、URL/Data URI下载、指数退避重试 - main.py: 修复 utils.t2i import 路径;新增 POST /agnes/images/generations(JSON 版)和 /agnes/images/generations/upload(multipart 版) - SKILL.md: 同步新端点、可调用模型、调用示例、multipart form 字段说明 - requirements.txt: 新增 python-multipart(UploadFile 依赖) - .env.example / .env: 新增 AGNES_API_KEY / AGNES_API_BASE_URL - .gitignore: 忽略 test/ 目录 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4,8 +4,9 @@
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
from fastapi import FastAPI
|
||||
import base64
|
||||
import re
|
||||
from fastapi import FastAPI, File, Form, HTTPException, UploadFile
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
@@ -97,6 +98,46 @@ def agnes_generate_images_endpoint(request: AgnesImageGenerationRequest):
|
||||
return AgnesImageGenerationResponse(**result)
|
||||
|
||||
|
||||
_ALLOWED_IMAGE_TYPES = {"image/png", "image/jpeg", "image/jpg", "image/webp"}
|
||||
|
||||
|
||||
@app.post("/agnes/images/generations/upload", response_model=AgnesImageGenerationResponse)
|
||||
def agnes_generate_images_upload_endpoint(
|
||||
prompt: str = Form(..., description="图片提示词"),
|
||||
profile_name: str = Form(..., description="调用方标识(必填)"),
|
||||
size: str = Form(default="1K", description="输出尺寸档位: 1K / 2K / 3K / 4K"),
|
||||
ratio: str | None = Form(default=None, description=f"宽高比,支持 {sorted(VALID_RATIOS)}"),
|
||||
images: list[UploadFile] = File(default=[], description="参考图像文件,可传多个"),
|
||||
):
|
||||
"""multipart/form-data 版图生图:上传本地图片文件直接测试,无需 base64。"""
|
||||
if not prompt.strip():
|
||||
raise HTTPException(status_code=422, detail="prompt 不能为空")
|
||||
if not re.match(r"^[\w-]+$", profile_name):
|
||||
raise HTTPException(status_code=422, detail="profile_name 只能包含字母数字下划线和短横线")
|
||||
if not images or all(not f.filename for f in images):
|
||||
raise HTTPException(status_code=422, detail="必须至少上传一张参考图 images")
|
||||
|
||||
data_uris: list[str] = []
|
||||
for f in images:
|
||||
if f.content_type and f.content_type not in _ALLOWED_IMAGE_TYPES:
|
||||
raise HTTPException(status_code=400, detail=f"不支持的图片类型: {f.content_type}")
|
||||
raw = f.file.read()
|
||||
if not raw:
|
||||
raise HTTPException(status_code=400, detail=f"上传的图片 {f.filename} 为空")
|
||||
mime = f.content_type or "image/png"
|
||||
b64 = base64.b64encode(raw).decode("ascii")
|
||||
data_uris.append(f"data:{mime};base64,{b64}")
|
||||
|
||||
result = agnes_generate_images(
|
||||
prompt=prompt,
|
||||
size=size,
|
||||
ratio=ratio,
|
||||
images=data_uris,
|
||||
profile_name=profile_name,
|
||||
)
|
||||
return AgnesImageGenerationResponse(**result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
|
||||
|
||||
Reference in New Issue
Block a user