fix(ports): docker 默认对外8502并修复空DB连接串回退

This commit is contained in:
Tony Zhang
2025-12-17 10:35:14 +08:00
parent 81a4faabf5
commit e365a94dd1
5 changed files with 333 additions and 4 deletions

138
api/main.py Normal file
View File

@@ -0,0 +1,138 @@
"""
Video Flow API - FastAPI Backend
前后端分离架构的后端服务
端口8000与 Streamlit 8503 共存8502 为历史 runtime/素材目录标识)
"""
import os
import sys
import logging
from pathlib import Path
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
# 确保项目根目录在 path 中
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT))
import config
from api.routes import projects, editor, assets, compose
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用生命周期管理"""
logger.info("Video Flow API 启动中...")
logger.info(f"项目根目录: {PROJECT_ROOT}")
logger.info(f"输出目录: {config.OUTPUT_DIR}")
logger.info(f"临时目录: {config.TEMP_DIR}")
yield
logger.info("Video Flow API 关闭中...")
# 创建 FastAPI 应用
app = FastAPI(
title="Video Flow API",
description="视频工作流后端 API - 支持项目管理、素材处理、视频编辑与合成",
version="1.0.0",
lifespan=lifespan,
docs_url="/api/docs",
redoc_url="/api/redoc",
openapi_url="/api/openapi.json"
)
# CORS 配置 - 允许 React 前端访问
app.add_middleware(
CORSMiddleware,
allow_origins=[
"http://localhost:3000", # React dev server
"http://localhost:5173", # Vite dev server
"http://127.0.0.1:3000",
"http://127.0.0.1:5173",
],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 挂载静态文件目录(用于访问生成的视频/图片)
app.mount("/static/output", StaticFiles(directory=str(config.OUTPUT_DIR)), name="output")
app.mount("/static/temp", StaticFiles(directory=str(config.TEMP_DIR)), name="temp")
app.mount("/static/assets", StaticFiles(directory=str(config.ASSETS_DIR)), name="assets")
# Legacy mounts8502 runtime 产物,宿主机目录通过 docker-compose 挂载到容器内)
try:
app.mount("/static/legacy-temp", StaticFiles(directory="/legacy/temp"), name="legacy-temp")
app.mount("/static/legacy-output", StaticFiles(directory="/legacy/output"), name="legacy-output")
except Exception:
# 本地非 docker 环境可能不存在这些目录
pass
# 注册路由
app.include_router(projects.router, prefix="/api/projects", tags=["Projects"])
app.include_router(editor.router, prefix="/api/editor", tags=["Editor"])
app.include_router(assets.router, prefix="/api/assets", tags=["Assets"])
app.include_router(compose.router, prefix="/api/compose", tags=["Compose"])
@app.get("/api/health")
async def health_check():
"""健康检查"""
return {
"status": "ok",
"service": "video-flow-api",
"version": "1.0.0"
}
@app.get("/api/config")
async def get_config():
"""获取前端所需的配置信息"""
return {
"video_settings": config.VIDEO_SETTINGS,
"available_voices": [
{"id": config.VOLC_TTS_DEFAULT_VOICE, "name": "三通永 (默认)"},
{"id": "zh_female_meilinvyou_saturn_bigtts", "name": "美丽女友"},
],
"available_bgm": _list_bgm_files(),
}
def _list_bgm_files():
"""列出可用的 BGM 文件"""
bgm_dir = config.ASSETS_DIR / "bgm"
if not bgm_dir.exists():
return []
bgm_files = []
for f in bgm_dir.iterdir():
if f.suffix.lower() in ['.mp3', '.mp4', '.m4a', '.wav']:
bgm_files.append({
"id": f.name,
"name": f.stem,
"path": f"/static/assets/bgm/{f.name}"
})
return bgm_files
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"api.main:app",
host="0.0.0.0",
port=8000,
reload=True,
log_level="info"
)