122 lines
4.0 KiB
Python
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, endpoints_custom_nodes
|
|
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": "127.0.0.1",
|
|
"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"]
|
|
)
|