from __future__ import annotations import logging from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.config import DATA_DIR, WIKI_DIR from app.engine import DuckDBEngine from app.git_sync import GitSyncManager from app.routes.dashboard import router as dashboard_router from app.routes.entities import router as entities_router from app.routes.events import router as events_router from app.routes.query import router as query_router from app.routes.system import router as system_router logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s") logger = logging.getLogger("duckdb_backend") @asynccontextmanager async def lifespan(app: FastAPI): logger.info("Initializing DuckDB Backend...") if getattr(app.state, "git_sync", None) is None or getattr(app.state, "engine", None) is None: git_sync = GitSyncManager( wiki_dir=WIKI_DIR, on_data_pulled=lambda: app.state.engine.reload_all() if hasattr(app.state, "engine") else None, ) git_sync.ensure_repo() app.state.git_sync = git_sync engine = DuckDBEngine(data_dir=DATA_DIR, git_sync_manager=git_sync) app.state.engine = engine await git_sync.start_periodic_sync() logger.info("DuckDB Backend is ready to serve queries.") try: yield finally: logger.info("Shutting down DuckDB Backend...") await git_sync.stop_periodic_sync() else: yield app = FastAPI( title="DuckDB Backend for Knowledge Wiki", version="1.0.0", description="HTTP-based analytical and transactional backend for personal logging data powered by DuckDB", lifespan=lifespan, ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # API v1 prefix v1_router = FastAPI() app.include_router(dashboard_router, prefix="/duckdb-api/v1") app.include_router(query_router, prefix="/duckdb-api/v1") app.include_router(events_router, prefix="/duckdb-api/v1") app.include_router(entities_router, prefix="/duckdb-api/v1") app.include_router(system_router, prefix="/duckdb-api/v1") # Direct root health probes for Kubernetes app.include_router(system_router)