Files
Kris Ka dc0cf66159 完成项目问题修复和优化
主要改进:
1. 清理重复文件和冗余代码
   - 删除重复的API文件 (upload_backup.py, upload_new.py等)
   - 删除旧版本的B站服务文件 (bilibili_upload_v2.py到v6.py)
   - 统一B站服务接口

2. 优化数据存储架构
   - 创建OptimizedStorageService解决双重存储问题
   - 数据库只存储元数据,文件系统存储实际文件
   - 提供数据迁移脚本和一致性检查工具

3. 统一错误处理机制
   - 创建统一错误处理中间件
   - 提供错误处理装饰器和上下文管理器
   - 统一错误响应格式

4. 完善配置管理
   - 创建UnifiedConfig统一配置系统
   - 整合所有配置源(环境变量、配置文件、默认值)
   - 提供配置迁移脚本

5. 增强进度系统
   - 创建EnhancedProgressService
   - 支持Redis缓存、数据库持久化和内存缓存
   - 提供完整的进度跟踪和状态管理

新增文件:
- backend/services/optimized_storage_service.py
- backend/core/error_middleware.py
- backend/core/unified_config.py
- backend/services/enhanced_progress_service.py
- scripts/migrate_to_optimized_storage.py
- scripts/check_data_consistency.py
- scripts/migrate_config.py
- docs/ERROR_HANDLING_GUIDE.md
- docs/PROGRESS_SYSTEM_GUIDE.md

修复文件:
- backend/services/bilibili_service.py (统一上传接口)
- backend/main.py (使用新的错误处理中间件)
2025-09-15 12:07:09 +08:00

166 lines
5.1 KiB
Python

"""FastAPI应用入口点"""
import logging
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
# 导入配置管理
from .core.config import settings, get_logging_config, get_api_key
# 配置日志
logging_config = get_logging_config()
logging.basicConfig(
level=getattr(logging, logging_config["level"]),
format=logging_config["format"],
handlers=[
logging.StreamHandler(), # 输出到控制台
logging.FileHandler(logging_config["file"]) # 输出到文件
]
)
logger = logging.getLogger(__name__)
# 使用统一的API路由注册
from .api.v1 import api_router
from .core.database import engine
from .models.base import Base
# Create FastAPI app
app = FastAPI(
title="AutoClip API",
description="AI视频切片处理API",
version="1.0.0",
docs_url="/docs",
redoc_url="/redoc"
)
# Create database tables
@app.on_event("startup")
async def startup_event():
logger.info("启动AutoClip API服务...")
# 导入所有模型以确保表被创建
from .models.bilibili import BilibiliAccount, UploadRecord
Base.metadata.create_all(bind=engine)
logger.info("数据库表创建完成")
# 加载API密钥到环境变量
api_key = get_api_key()
if api_key:
import os
os.environ["DASHSCOPE_API_KEY"] = api_key
logger.info("API密钥已加载到环境变量")
else:
logger.warning("未找到API密钥配置")
# 启动WebSocket网关服务 - 已禁用,使用新的简化进度系统
# from .services.websocket_gateway_service import websocket_gateway_service
# await websocket_gateway_service.start()
# logger.info("WebSocket网关服务已启动")
logger.info("WebSocket网关服务已禁用,使用新的简化进度系统")
@app.on_event("shutdown")
async def shutdown_event():
"""应用关闭事件"""
logger.info("正在关闭AutoClip API服务...")
# WebSocket网关服务已禁用
# from .services.websocket_gateway_service import websocket_gateway_service
# await websocket_gateway_service.stop()
# logger.info("WebSocket网关服务已停止")
logger.info("WebSocket网关服务已禁用")
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Configure appropriately for production
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Include unified API routes
app.include_router(api_router, prefix="/api/v1")
# 添加独立的video-categories端点
@app.get("/api/v1/video-categories")
async def get_video_categories():
"""获取视频分类配置."""
return {
"categories": [
{
"value": "default",
"name": "默认",
"description": "通用视频内容处理",
"icon": "🎬",
"color": "#4facfe"
},
{
"value": "knowledge",
"name": "知识科普",
"description": "科学、技术、历史、文化等知识类内容",
"icon": "📚",
"color": "#52c41a"
},
{
"value": "entertainment",
"name": "娱乐",
"description": "游戏、音乐、电影等娱乐内容",
"icon": "🎮",
"color": "#722ed1"
},
{
"value": "business",
"name": "商业",
"description": "商业、创业、投资等商业内容",
"icon": "💼",
"color": "#fa8c16"
},
{
"value": "experience",
"name": "经验分享",
"description": "个人经历、生活感悟等经验内容",
"icon": "🌟",
"color": "#eb2f96"
},
{
"value": "opinion",
"name": "观点评论",
"description": "时事评论、观点分析等评论内容",
"icon": "💭",
"color": "#13c2c2"
},
{
"value": "speech",
"name": "演讲",
"description": "公开演讲、讲座等演讲内容",
"icon": "🎤",
"color": "#f5222d"
}
]
}
# 导入统一错误处理中间件
from .core.error_middleware import global_exception_handler
# 注册全局异常处理器
app.add_exception_handler(Exception, global_exception_handler)
if __name__ == "__main__":
import uvicorn
import sys
# 默认端口
port = 8000
# 检查命令行参数
if len(sys.argv) > 1:
for i, arg in enumerate(sys.argv):
if arg == "--port" and i + 1 < len(sys.argv):
try:
port = int(sys.argv[i + 1])
except ValueError:
logger.error(f"无效的端口号: {sys.argv[i + 1]}")
port = 8000
logger.info(f"启动服务器,端口: {port}")
uvicorn.run(app, host="0.0.0.0", port=port)