main.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import os
  2. import sys
  3. import re
  4. from typing import Optional
  5. from fastapi import FastAPI, HTTPException
  6. from pydantic import BaseModel, Field
  7. from dotenv import load_dotenv
  8. from openai import OpenAI
  9. # 加载环境变量
  10. load_dotenv()
  11. app = FastAPI(title="GPT Image 2 API", version="1.0.0")
  12. # 初始化 OpenAI 客户端,使用 apiyi 平台
  13. api_key = os.getenv("APIYI_KEY")
  14. if not api_key:
  15. raise ValueError("APIYI_KEY environment variable is required")
  16. client = OpenAI(
  17. api_key=api_key,
  18. base_url="https://api.apiyi.com/v1"
  19. )
  20. def extract_url_from_content(text: str) -> Optional[str]:
  21. """从 API 返回内容中提取图片 URL(可能是 markdown 格式)"""
  22. # 匹配 ![image](url) 或 ![...](url) 格式
  23. match = re.search(r'!\[.*?\]\((https?://[^\)]+)\)', text)
  24. if match:
  25. return match.group(1)
  26. # 如果不是 markdown 格式,尝试直接作为 URL
  27. stripped = text.strip()
  28. if stripped.startswith("http"):
  29. return stripped
  30. return None
  31. class ImageRequest(BaseModel):
  32. prompt: str = Field(..., description="图像生成提示词,可包含尺寸描述如'1024x1024 方图'")
  33. class ImageResponse(BaseModel):
  34. status: str
  35. image_url: Optional[str] = None
  36. error: Optional[str] = None
  37. @app.post("/generate", response_model=ImageResponse)
  38. async def generate_image(request: ImageRequest):
  39. """生成图像 - 使用 gpt-image-2-all 模型"""
  40. try:
  41. # 使用 chat/completions 接口调用 gpt-image-2-all
  42. response = client.chat.completions.create(
  43. model="gpt-image-2-all",
  44. messages=[
  45. {"role": "user", "content": request.prompt}
  46. ],
  47. extra_body={"response_format": {"type": "url"}}
  48. )
  49. if response.choices and len(response.choices) > 0:
  50. content = response.choices[0].message.content
  51. image_url = extract_url_from_content(content)
  52. if image_url:
  53. return ImageResponse(status="success", image_url=image_url)
  54. else:
  55. return ImageResponse(
  56. status="error",
  57. error=f"Could not extract URL from response: {content}"
  58. )
  59. else:
  60. return ImageResponse(status="error", error="No content returned from API")
  61. except Exception as e:
  62. return ImageResponse(status="error", error=str(e))
  63. @app.get("/health")
  64. async def health_check():
  65. return {"status": "ok", "service": "gpt-image-2"}
  66. if __name__ == "__main__":
  67. import uvicorn
  68. port = 5000
  69. if "--port" in sys.argv:
  70. try:
  71. port_idx = sys.argv.index("--port")
  72. port = int(sys.argv[port_idx + 1])
  73. except (IndexError, ValueError):
  74. pass
  75. uvicorn.run(app, host="0.0.0.0", port=port)