Files
course-agent-od/backend/src/services/image_generation_service.py
T
pengxiao 37c0364e7e refactor: replace print() with structured logging across backend
Replace all print()/stderr logging with Python logging module using
logger = logging.getLogger(__name__) pattern for consistent log levels
and formatting. Extract score conversion to shared score_utils module.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 15:52:44 +08:00

101 lines
3.4 KiB
Python

"""
统一图像生成服务基类
支持硅基流动平台的多种图像生成模型
"""
import base64
import logging
import uuid
from pathlib import Path
from typing import Dict, Any
import httpx
from src.core.config import settings
logger = logging.getLogger(__name__)
class ImageGenerationService:
"""统一的图像生成服务基类"""
def __init__(self):
self.base_url = "https://api.siliconflow.cn/v1/image/generations"
self.api_key = settings.siliconflow_api_key
self.timeout = 60
async def call_api(self, model: str, payload: dict) -> dict:
"""调用硅基流动 API"""
logger.debug(f"调用SiliconFlow API: {self.base_url}")
logger.debug(f"模型: {model}")
logger.debug(f"请求参数: {payload}")
async with httpx.AsyncClient(timeout=self.timeout) as client:
response = await client.post(
self.base_url,
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
},
json={"model": model, **payload}
)
response.raise_for_status()
result = response.json()
logger.debug(f"API响应状态: {response.status_code}")
logger.debug(f"API响应类型: {type(result)}")
logger.debug(f"API响应键: {list(result.keys()) if isinstance(result, dict) else '非字典类型'}")
return result
def save_image(self, image_id: str, base64_data: str) -> str:
"""保存 base64 图像到本地文件系统"""
try:
# 清理base64数据(移除可能的data URL前缀)
if base64_data.startswith('data:image'):
base64_data = base64_data.split(',')[1]
# 移除可能的空白字符
base64_data = base64_data.strip()
logger.debug(f"开始解码base64数据,长度: {len(base64_data)}")
# 解码 base64 数据
image_bytes = base64.b64decode(base64_data)
# 验证是否为有效的图片数据
if len(image_bytes) == 0:
raise Exception("解码后的图像数据为空")
logger.debug(f"图像数据大小: {len(image_bytes)} bytes")
# 确保目录存在
image_dir = Path(settings.generated_images_dir)
image_dir.mkdir(parents=True, exist_ok=True)
# 保存图像文件
image_path = image_dir / f"{image_id}.png"
with open(image_path, "wb") as f:
f.write(image_bytes)
logger.debug(f"图像已保存到: {image_path}")
return str(image_path)
except Exception as e:
logger.error(f"保存图像失败: {str(e)}")
logger.error(f"base64数据长度: {len(base64_data) if base64_data else 0}")
logger.error(f"base64数据前100字符: {base64_data[:100] if base64_data else 'None'}")
raise Exception(f"保存图像失败: {str(e)}")
def generate_image_id(self) -> str:
"""生成唯一的图像ID"""
return str(uuid.uuid4())
def get_image_url(self, image_id: str) -> str:
"""获取图像的访问URL"""
return f"/generated_images/{image_id}.png"