TraceStudio/server/main.py
2026-01-12 21:51:45 +08:00

122 lines
4.0 KiB
Python

"""
TraceStudio 主启动文件
规范化架构 v2.0
"""
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import uvicorn
import yaml
from pathlib import Path
from server.app.api import endpoints_graph, endpoints_upload
from server.app.core.user_manager import init_base_structure
from server.app.core.node_loader import reload_custom_nodes
from server.app.core.cache_manager import CacheManager
import tempfile
import asyncio
# 加载系统配置
def load_config():
config_path = Path(__file__).parent / "system_config.yaml"
if config_path.exists():
with open(config_path, 'r', encoding='utf-8') as f:
return yaml.safe_load(f)
return {
"server": {
"host": "0.0.0.0",
"port": 8000,
"reload": True
},
"security": {
"allowed_ips": ["*"]
}
}
config = load_config()
# 创建 FastAPI 应用
app = FastAPI(
title="TraceStudio Server",
description="Unreal Insights 数据分析后端 - 规范化架构",
version="2.0.0"
)
# 配置 CORS
allow_origins = config.get("security", {}).get("allowed_ips", ["*"])
if "*" in allow_origins:
allow_origins = ["*"]
app.add_middleware(
CORSMiddleware,
allow_origins=allow_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 注册路由
app.include_router(endpoints_graph.router, prefix="/api", tags=["Graph"])
app.include_router(endpoints_upload.router, prefix="/api", tags=["Files"])
# app.include_router(endpoints_custom_nodes.router, tags=["Custom Nodes"]) # 暂时禁用
@app.on_event("startup")
async def startup_event():
"""应用启动事件"""
# 加载自定义节点
result = reload_custom_nodes()
print(f"🔌 自定义节点: {result['loaded']}/{result['total']} 个已加载")
init_base_structure()
# 在应用启动阶段异步初始化缓存以避免阻塞启动(尤其在 reload/子进程场景)
try:
print("🗂️ 调度缓存初始化任务(内存 + 磁盘)...")
disk_dir = Path(tempfile.gettempdir()) / "tracestudio_cache"
mem_task = asyncio.create_task(asyncio.to_thread(CacheManager.init_memory_cache, 100, None))
disk_task = asyncio.create_task(asyncio.to_thread(CacheManager.init_disk_cache, disk_dir, None))
async def _watch_init(m_t, d_t, d_path):
try:
await m_t
print("🗂️ 内存缓存初始化完成")
except Exception as e:
print("⚠️ 内存缓存初始化失败:", e)
try:
await d_t
print(f"🗂️ 磁盘缓存初始化完成,目录: {d_path}")
except Exception as e:
print("⚠️ 磁盘缓存初始化失败:", e)
asyncio.create_task(_watch_init(mem_task, disk_task, disk_dir))
print(f"🗂️ 缓存初始化任务已调度,磁盘缓存目录: {disk_dir}")
except Exception as e:
print("⚠️ 缓存初始化任务调度失败:", e)
print("🚀 TraceStudio Server v2.0 启动完成")
print(f"📡 服务地址: http://{config['server']['host']}:{config['server']['port']}")
print(f"📖 API 文档: http://{config['server']['host']}:{config['server']['port']}/docs")
@app.get("/")
async def root():
"""健康检查"""
return {
"status": "running",
"service": "TraceStudio Server",
"version": "2.0.0",
"architecture": "normalized"
}
if __name__ == "__main__":
print("🚀 启动 TraceStudio 服务器...")
# 当直接运行 main.py 时也初始化缓存(保持向后兼容)
try:
CacheManager.init_memory_cache(max_size=100, ttl=None)
CacheManager.init_disk_cache(Path(tempfile.gettempdir()) / "tracestudio_cache", ttl=None)
except Exception:
pass
uvicorn.run(
"main:app",
host=config["server"]["host"],
port=config["server"]["port"],
reload=config["server"]["reload"]
)