File size: 3,944 Bytes
e054d0c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f68d0a
e054d0c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
"""
FastAPI 应用入口

GPT-SoVITS 音色训练 HTTP API 服务

启动方式:
    uvicorn api_server.app.main:app --host 0.0.0.0 --port 8000 --reload
"""

from contextlib import asynccontextmanager
from typing import AsyncGenerator

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from project_config import settings, ensure_data_dirs
from .api.v1.router import api_router


@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
    """
    应用生命周期管理
    
    启动时:
    - 确保数据目录存在
    - 恢复中断的任务(可选)
    
    关闭时:
    - 清理资源
    """
    # 启动时执行
    print(f"Starting GPT-SoVITS Training API in {settings.DEPLOYMENT_MODE.upper()} mode")
    print(f"  Project Root: {settings.PROJECT_ROOT}")
    print(f"  Data Directory: {settings.DATA_DIR}")
    print(f"  SQLite Path: {settings.SQLITE_PATH}")
    
    # 确保数据目录存在
    ensure_data_dirs()
    
    # 恢复中断的任务(可选)
    if settings.DEPLOYMENT_MODE == "local":
        try:
            from .core.adapters import get_task_queue_adapter
            queue = get_task_queue_adapter()
            # 检查是否有 recover_pending_tasks 方法
            if hasattr(queue, 'recover_pending_tasks'):
                count = await queue.recover_pending_tasks()
                if count > 0:
                    print(f"  Recovered {count} pending tasks")
        except Exception as e:
            print(f"  Warning: Failed to recover tasks: {e}")
    
    print("  API Server ready!")
    print(f"  Docs: http://{settings.API_HOST}:{settings.API_PORT}/docs")
    
    yield
    
    # 关闭时执行
    print("Shutting down GPT-SoVITS Training API...")


# 创建 FastAPI 应用
app = FastAPI(
    title="GPT-SoVITS Training API",
    description="""
GPT-SoVITS 音色训练 HTTP API 服务

## 功能概述

提供两种训练模式:

### Quick Mode(小白用户)
- 上传音频即可训练,系统自动配置所有参数
- 适合个人开发者、快速验证

### Advanced Mode(专家用户)
- 分阶段控制训练流程
- 精细调整每个阶段的参数
- 适合需要深度定制的用户

## API 分组

- **Quick Mode - 任务管理**: `/api/v1/tasks`
- **Advanced Mode - 实验管理**: `/api/v1/experiments`
- **文件管理**: `/api/v1/files`
- **阶段模板**: `/api/v1/stages`
""",
    version="1.0.0",
    lifespan=lifespan,
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json",
)

# 配置 CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 生产环境应该限制来源
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册 API 路由
app.include_router(api_router, prefix=settings.API_V1_PREFIX)


# ============================================================
# 根路由和健康检查
# ============================================================

@app.get("/", tags=["Root"])
async def root():
    """
    根路由
    
    返回 API 基本信息
    """
    return {
        "name": "GPT-SoVITS Training API",
        "version": "1.0.0",
        "mode": settings.DEPLOYMENT_MODE,
        "docs": "/docs",
        "health": "/health",
    }


@app.get("/health", tags=["Health"])
async def health_check():
    """
    健康检查端点
    
    用于容器编排和负载均衡器健康检查
    """
    return {
        "status": "healthy",
        "mode": settings.DEPLOYMENT_MODE,
    }


# ============================================================
# 开发模式直接运行
# ============================================================

if __name__ == "__main__":
    import uvicorn
    
    uvicorn.run(
        "api_server.app.main:app",
        host=settings.API_HOST,
        port=settings.API_PORT,
        reload=True,
        reload_dirs=[str(settings.API_SERVER_ROOT)],
    )