100 lines
2.8 KiB
Python
100 lines
2.8 KiB
Python
"""FastAPI 应用入口。"""
|
||
|
||
import logging
|
||
import os
|
||
|
||
from fastapi import FastAPI
|
||
from fastapi.staticfiles import StaticFiles
|
||
from starlette.staticfiles import StaticFiles as StarletteStaticFiles
|
||
|
||
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.compare import router as compare_router
|
||
from app.routes.pages import router as pages_router
|
||
from app.routes.search import router as search_router
|
||
from app.routes.trends import router as trends_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")
|
||
|
||
# Phase 5: 论文图片静态服务
|
||
papers_images_dir = os.path.join("data", "papers")
|
||
os.makedirs(papers_images_dir, exist_ok=True)
|
||
app.mount("/papers", StaticFiles(directory=papers_images_dir), name="papers")
|
||
|
||
# 路由
|
||
app.include_router(pages_router)
|
||
app.include_router(admin_router)
|
||
app.include_router(search_router)
|
||
app.include_router(user_router)
|
||
app.include_router(trends_router)
|
||
app.include_router(compare_router)
|
||
|
||
# 调度器(Phase 4)
|
||
@app.on_event("startup")
|
||
async def _start_scheduler():
|
||
from app.services.scheduler import start_scheduler
|
||
start_scheduler()
|
||
|
||
# Phase 5: 初始化 ChromaDB
|
||
@app.on_event("startup")
|
||
async def _init_chroma():
|
||
from app.services.embedder import init_chroma
|
||
init_chroma()
|
||
|
||
@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,
|
||
)
|