Files
rssKeeper/backend/main.py
T

67 lines
1.8 KiB
Python
Raw Normal View History

"""rssKeeper - FastAPI 入口"""
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from starlette.middleware.cors import CORSMiddleware
from database import init_db, SessionLocal
from scheduler import init_feed_jobs, stop_scheduler
from routers import feeds, articles, dashboard, external_api
import config
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用生命周期管理"""
# 启动时:初始化数据库 + 注册定时任务
init_db()
db = SessionLocal()
try:
init_feed_jobs(db)
finally:
db.close()
yield
# 关闭时:停止调度器
stop_scheduler()
app = FastAPI(
title="rssKeeper",
description="RSS 抓取、管理与检索系统",
version="1.0.0",
lifespan=lifespan,
)
2026-06-11 14:31:29 +08:00
# CORS — 仅允许同源和开发环境
app.add_middleware(
CORSMiddleware,
2026-06-11 14:31:29 +08:00
allow_origins=[
"http://localhost:7329",
"http://localhost:7330",
"http://127.0.0.1:7329",
],
allow_credentials=False,
allow_methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["Content-Type", "Authorization", "X-API-Key"],
)
# API 路由
app.include_router(feeds.router, prefix=config.API_PREFIX)
app.include_router(articles.router, prefix=config.API_PREFIX)
app.include_router(dashboard.router, prefix=config.API_PREFIX)
app.include_router(external_api.router, prefix=config.EXTERNAL_API_PREFIX)
@app.get("/api/health")
def health_check():
"""健康检查"""
return {"status": "ok", "service": "rssKeeper"}
# 静态文件服务(前端构建产物)— 必须放在最后,API 路由优先匹配
static_dir = os.path.join(config.BASE_DIR, "static")
if os.path.exists(static_dir):
app.mount("/", StaticFiles(directory=static_dir, html=True), name="static")