# app/main.py """FastAPI application factory for pagepiper.""" from __future__ import annotations import logging from contextlib import asynccontextmanager from fastapi import FastAPI from app.config import DB_PATH from app.services.bm25_index import BM25Index logger = logging.getLogger("pagepiper") # Module-level BM25 singleton — shared across all requests _bm25 = BM25Index() def _apply_migrations() -> None: from scripts.db_migrate import migrate migrate(DB_PATH) @asynccontextmanager async def lifespan(app: FastAPI): _apply_migrations() _bm25.mark_dirty() # will rebuild on first search yield app = FastAPI(title="Pagepiper", lifespan=lifespan) # Wire BM25 dirty callback into library router from app.api import library as _lib_module # noqa: E402 _lib_module._mark_bm25_dirty = _bm25.mark_dirty # Register routers from app.api.library import router as library_router # noqa: E402 from app.api.ingest import router as ingest_router # noqa: E402 from app.api.search import router as search_router # noqa: E402 from app.api.chat import router as chat_router # noqa: E402 app.include_router(library_router) app.include_router(ingest_router) app.include_router(search_router) app.include_router(chat_router)