From 0dd640586027afaf240cada6a7a77082a08a5407 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Fri, 27 Mar 2026 15:24:04 -0700 Subject: [PATCH] Add routers to our fastapi app for testing --- sample-apps/fastapi-postgres-uvicorn/app.py | 5 ++ .../routers/__init__.py | 0 .../fastapi-postgres-uvicorn/routers/admin.py | 33 +++++++++++ .../fastapi-postgres-uvicorn/routers/dogs.py | 59 +++++++++++++++++++ .../routers/health.py | 14 +++++ 5 files changed, 111 insertions(+) create mode 100644 sample-apps/fastapi-postgres-uvicorn/routers/__init__.py create mode 100644 sample-apps/fastapi-postgres-uvicorn/routers/admin.py create mode 100644 sample-apps/fastapi-postgres-uvicorn/routers/dogs.py create mode 100644 sample-apps/fastapi-postgres-uvicorn/routers/health.py diff --git a/sample-apps/fastapi-postgres-uvicorn/app.py b/sample-apps/fastapi-postgres-uvicorn/app.py index 5afc07eb9..c70507439 100644 --- a/sample-apps/fastapi-postgres-uvicorn/app.py +++ b/sample-apps/fastapi-postgres-uvicorn/app.py @@ -8,6 +8,7 @@ from fastapi.templating import Jinja2Templates from fastapi.middleware.cors import CORSMiddleware from aikido_zen.middleware import AikidoFastAPIMiddleware +from routers import dogs, admin, health templates = Jinja2Templates(directory="templates") @@ -23,6 +24,10 @@ ) app.add_middleware(AikidoFastAPIMiddleware) +app.include_router(dogs.router) +app.include_router(admin.router) +app.include_router(health.router) + async def get_db_connection(): return await asyncpg.connect( host="localhost", diff --git a/sample-apps/fastapi-postgres-uvicorn/routers/__init__.py b/sample-apps/fastapi-postgres-uvicorn/routers/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/sample-apps/fastapi-postgres-uvicorn/routers/admin.py b/sample-apps/fastapi-postgres-uvicorn/routers/admin.py new file mode 100644 index 000000000..bec6e0b2a --- /dev/null +++ b/sample-apps/fastapi-postgres-uvicorn/routers/admin.py @@ -0,0 +1,33 @@ +import asyncpg +from fastapi import APIRouter +from fastapi.responses import JSONResponse + +router = APIRouter(prefix="/admin", tags=["admin"]) + + +async def get_db_connection(): + return await asyncpg.connect( + host="localhost", + database="db", + user="user", + password="password", + ) + + +@router.get("/dogs") +async def list_admin_dogs(): + conn = await get_db_connection() + dogs = await conn.fetch("SELECT * FROM dogs WHERE isAdmin = TRUE") + await conn.close() + return JSONResponse({"admin_dogs": [dict(d) for d in dogs]}) + + +@router.delete("/dogs/{dog_id}") +async def delete_dog(dog_id: int): + conn = await get_db_connection() + result = await conn.execute("DELETE FROM dogs WHERE id = $1", dog_id) + await conn.close() + deleted = int(result.split()[-1]) + if deleted == 0: + return JSONResponse({"error": "Dog not found"}, status_code=404) + return JSONResponse({"message": f"Dog {dog_id} deleted"}) diff --git a/sample-apps/fastapi-postgres-uvicorn/routers/dogs.py b/sample-apps/fastapi-postgres-uvicorn/routers/dogs.py new file mode 100644 index 000000000..c7f3ce098 --- /dev/null +++ b/sample-apps/fastapi-postgres-uvicorn/routers/dogs.py @@ -0,0 +1,59 @@ +import asyncpg +from fastapi import APIRouter, HTTPException, Request +from fastapi.responses import HTMLResponse, JSONResponse +from fastapi.templating import Jinja2Templates + +router = APIRouter(prefix="/dogs", tags=["dogs"]) + +templates = Jinja2Templates(directory="templates") + + +async def get_db_connection(): + return await asyncpg.connect( + host="localhost", + database="db", + user="user", + password="password", + ) + + +@router.get("/", response_class=HTMLResponse) +async def list_dogs(request: Request): + conn = await get_db_connection() + dogs = await conn.fetch("SELECT * FROM dogs") + await conn.close() + return templates.TemplateResponse( + "index.html", {"request": request, "title": "Dogs", "dogs": dogs} + ) + + +@router.get("/{dog_id}", response_class=HTMLResponse) +async def get_dog(request: Request, dog_id: int): + conn = await get_db_connection() + dog = await conn.fetchrow("SELECT * FROM dogs WHERE id = $1", dog_id) + await conn.close() + if dog is None: + raise HTTPException(status_code=404, detail="Dog not found") + return templates.TemplateResponse( + "dogpage.html", + {"request": request, "title": "Dog", "dog": dog, "isAdmin": "Yes" if dog[2] else "No"}, + ) + + +@router.post("/") +async def create_dog(request: Request): + data = await request.form() + dog_name = data.get("dog_name") + + if not dog_name: + return JSONResponse({"error": "dog_name is required"}, status_code=400) + + conn = await get_db_connection() + try: + await conn.execute( + "INSERT INTO dogs (dog_name, isAdmin) VALUES ($1, FALSE)", dog_name + ) + finally: + await conn.close() + + return JSONResponse({"message": f"Dog {dog_name} created successfully"}, status_code=201) diff --git a/sample-apps/fastapi-postgres-uvicorn/routers/health.py b/sample-apps/fastapi-postgres-uvicorn/routers/health.py new file mode 100644 index 000000000..694713a44 --- /dev/null +++ b/sample-apps/fastapi-postgres-uvicorn/routers/health.py @@ -0,0 +1,14 @@ +from fastapi import APIRouter +from fastapi.responses import JSONResponse + +router = APIRouter(prefix="/health", tags=["health"]) + + +@router.get("/") +async def health(): + return JSONResponse({"status": "ok"}) + + +@router.get("/ping") +async def ping(): + return JSONResponse({"ping": "pong"})