"""FastAPI 应用入口。""" import logging import os from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from app.config import settings from app.database import engine from app.models import init_db from app.routes.admin import router as admin_router from app.routes.pages import router as pages_router from app.routes.search import router as search_router from app.routes.user import router as user_router logging.basicConfig( level=logging.DEBUG if settings.APP_DEBUG else logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", ) logger = logging.getLogger(__name__) def create_app() -> FastAPI: app = FastAPI( title="HF Daily Papers", description="HuggingFace Daily Papers — 中文论文导览站", version="0.1.0", ) # 确保数据目录存在 os.makedirs(settings.db_path.parent, exist_ok=True) # 初始化数据库 init_db(engine) logger.info("Database initialized at %s", settings.db_path) # 安全警告 if settings.ADMIN_TOKEN == "change-me": logger.warning("⚠️ ADMIN_TOKEN is the default value 'change-me'. Please change it in .env!") if settings.APP_HOST not in ("127.0.0.1", "localhost", "::1"): logger.warning( "⚠️ APP_HOST=%s is not localhost. " "Ensure ADMIN_TOKEN is properly set and access is restricted.", settings.APP_HOST, ) # 静态文件 app.mount("/static", StaticFiles(directory="app/static"), name="static") # 路由 app.include_router(pages_router) app.include_router(admin_router) app.include_router(search_router) app.include_router(user_router) # 调度器(Phase 4) @app.on_event("startup") async def _start_scheduler(): from app.services.scheduler import start_scheduler start_scheduler() @app.on_event("shutdown") async def _stop_scheduler(): from app.services.scheduler import stop_scheduler stop_scheduler() return app app = create_app() if __name__ == "__main__": import uvicorn uvicorn.run( "app.main:app", host=settings.APP_HOST, port=settings.APP_PORT, reload=settings.APP_DEBUG, )