From 9f0b0922b054ee59d707c3101d17e688699e3f05 Mon Sep 17 00:00:00 2001 From: jlightner Date: Fri, 3 Apr 2026 04:24:58 +0000 Subject: [PATCH] feat: add GET /api/v1/stats endpoint with technique and creator counts --- backend/main.py | 3 ++- backend/routers/stats.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 backend/routers/stats.py diff --git a/backend/main.py b/backend/main.py index 0f5ac1f..c1202d8 100644 --- a/backend/main.py +++ b/backend/main.py @@ -12,7 +12,7 @@ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from config import get_settings -from routers import creators, health, ingest, pipeline, reports, search, techniques, topics, videos +from routers import creators, health, ingest, pipeline, reports, search, stats, techniques, topics, videos def _setup_logging() -> None: @@ -83,6 +83,7 @@ app.include_router(ingest.router, prefix="/api/v1") app.include_router(pipeline.router, prefix="/api/v1") app.include_router(reports.router, prefix="/api/v1") app.include_router(search.router, prefix="/api/v1") +app.include_router(stats.router, prefix="/api/v1") app.include_router(techniques.router, prefix="/api/v1") app.include_router(topics.router, prefix="/api/v1") app.include_router(videos.router, prefix="/api/v1") diff --git a/backend/routers/stats.py b/backend/routers/stats.py new file mode 100644 index 0000000..74f6944 --- /dev/null +++ b/backend/routers/stats.py @@ -0,0 +1,29 @@ +"""Public stats endpoints for Chrysopedia.""" + +import logging + +from fastapi import APIRouter, Depends +from sqlalchemy import func, select +from sqlalchemy.ext.asyncio import AsyncSession + +from database import get_session +from models import Creator, TechniquePage + +logger = logging.getLogger("chrysopedia.stats") + +router = APIRouter(tags=["stats"]) + + +@router.get("/stats") +async def get_stats(db: AsyncSession = Depends(get_session)) -> dict: + """Return aggregate counts for the knowledge base.""" + technique_count = await db.scalar( + select(func.count()).select_from(TechniquePage) + ) + creator_count = await db.scalar( + select(func.count()).select_from(Creator) + ) + return { + "technique_count": technique_count or 0, + "creator_count": creator_count or 0, + }