Files
video-gen/video-gen-api/app/services/api_v3/engine_service.py
T
root 0c511f3451 1、增加调用 AI 视频生成能力和虚拟素材库管理的对外api
2、增加后台apikkey管理
3、增加apikey单独的模型定价
4、增加apikey调用情况
5、完善所有数据的注释增加
2026-08-06 13:13:28 +08:00

133 lines
4.1 KiB
Python

import json
import logging
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.image_engine import ImageEngine
from app.models.video_engine import VideoEngine
logger = logging.getLogger("videogen")
async def resolve_video_engine(
db: AsyncSession,
engine_id: str,
callable_models: list[dict],
) -> VideoEngine:
"""根据 engine_id 解析视频引擎,并验证是否在 api-key 的可调用列表中。"""
# 验证授权
allowed = {m["engine_id"] for m in callable_models if m.get("engine_type") == "video"}
if engine_id not in allowed:
from fastapi import HTTPException, status
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"该 API Key 无权使用引擎 {engine_id}",
)
result = await db.execute(
select(VideoEngine).where(
VideoEngine.id == engine_id,
VideoEngine.is_active == True,
VideoEngine.deleted_at.is_(None),
).limit(1)
)
engine = result.scalar_one_or_none()
if not engine:
from fastapi import HTTPException, status
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"视频引擎 {engine_id} 不存在或未启用",
)
return engine
async def resolve_image_engine(
db: AsyncSession,
engine_id: str,
callable_models: list[dict],
) -> ImageEngine:
"""根据 engine_id 解析图片引擎,并验证是否在 api-key 的可调用列表中。"""
allowed = {m["engine_id"] for m in callable_models if m.get("engine_type") == "image"}
if engine_id not in allowed:
from fastapi import HTTPException, status
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"该 API Key 无权使用引擎 {engine_id}",
)
result = await db.execute(
select(ImageEngine).where(
ImageEngine.id == engine_id,
ImageEngine.is_active == True,
ImageEngine.deleted_at.is_(None),
).limit(1)
)
engine = result.scalar_one_or_none()
if not engine:
from fastapi import HTTPException, status
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"图片引擎 {engine_id} 不存在或未启用",
)
return engine
def build_engine_snapshot(engine: VideoEngine | ImageEngine) -> dict:
"""构建引擎配置快照。"""
snapshot = {
"id": str(engine.id),
"name": str(engine.name),
"provider": str(getattr(engine, "provider", "")),
"api_base": str(engine.api_base),
"model_name": str(engine.model_name),
}
# 可选字段
for field in [
"supported_ratios", "supported_resolutions", "supported_durations",
"default_size", "multi_generation_enabled", "max_generation_count",
]:
val = getattr(engine, field, None)
if val is not None:
if isinstance(val, str):
try:
val = json.loads(val)
except (json.JSONDecodeError, TypeError):
pass
snapshot[field] = val
return snapshot
async def resolve_engine_by_model_name(
db: AsyncSession,
model_name: str,
callable_models: list[dict],
engine_type: str,
) -> tuple[str, VideoEngine | ImageEngine]:
"""根据模型名称查找对应的引擎。
Returns:
(engine_id, engine 对象)
"""
# 在 callable_models 中查找
target = None
for m in callable_models:
if m.get("model_name") == model_name and m.get("engine_type") == engine_type:
target = m
break
if not target:
from fastapi import HTTPException, status
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=f"该 API Key 无权使用模型 {model_name}",
)
engine_id = target["engine_id"]
if engine_type == "video":
engine = await resolve_video_engine(db, engine_id, callable_models)
else:
engine = await resolve_image_engine(db, engine_id, callable_models)
return engine_id, engine