Files
signalscout-backend/app/main.py
T

58 lines
1.8 KiB
Python

import sys
from contextlib import asynccontextmanager
from collections.abc import AsyncIterator
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
# Direct IDE runs should not leave Python bytecode caches in the project tree.
sys.dont_write_bytecode = True
from app.agent.scheduler import build_scheduler # noqa: E402
from app.api.routes import router # noqa: E402
from app.core.config import get_settings # noqa: E402
from app.core.log_setup import configure_logging # noqa: E402
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
# 测试环境不启动后台采集,避免接口测试触发真实外部请求。
settings = get_settings()
if settings.env == "test":
yield
return
# 调度器随Web进程常驻,负责自动周期性整理情报。
scheduler = build_scheduler(settings)
scheduler.start()
app.state.scheduler = scheduler
try:
yield
finally:
scheduler.shutdown(wait=False)
def create_app() -> FastAPI:
# App factory keeps tests and production startup on the same initialization path.
settings = get_settings()
configure_logging(settings.log_file)
app = FastAPI(title=settings.app_name, lifespan=lifespan)
# The separate Vite frontend runs on 5173 during local development.
app.add_middleware(
CORSMiddleware,
allow_origins=["http://127.0.0.1:5173", "http://localhost:5173"],
allow_credentials=False,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(router)
return app
app = create_app()
if __name__ == "__main__":
# Direct execution is for IDE/local development; deployment can still call uvicorn explicitly.
uvicorn.run("app.main:app", host="127.0.0.1", port=8010, reload=False)