Starlette + AioSQLite Application

Expose SQLSpec data through Starlette routes backed by AioSQLite.

uv run python docs/examples/frameworks/starlette/aiosqlite_app.py

Source

 1"""Starlette routes serving SQLSpec-backed AioSQLite data."""
 2
 3import asyncio
 4
 5from starlette.applications import Starlette
 6from starlette.requests import Request
 7from starlette.responses import JSONResponse
 8from starlette.routing import Route
 9
10from docs.examples.shared.configs import aiosqlite_registry
11from docs.examples.shared.data import ARTICLES, CREATE_ARTICLES
12from sqlspec.core import SQL
13
14__all__ = ("list_articles", "main", "seed_database")
15
16
17registry, config = aiosqlite_registry()
18
19
20async def seed_database() -> None:
21    """Create tables and seed rows for the Starlette example."""
22    async with config.provide_session() as session:
23        await session.execute(CREATE_ARTICLES)
24        for row in ARTICLES:
25            await session.execute(
26                SQL(
27                    """
28                    INSERT OR REPLACE INTO articles (id, title, body)
29                    VALUES (:id, :title, :body)
30                    """
31                ),
32                row,
33            )
34
35
36async def list_articles(_request: "Request") -> "JSONResponse":
37    """Return JSON payload describing the article dataset."""
38    async with config.provide_session() as session:
39        result = await session.execute(SQL("SELECT id, title, body FROM articles ORDER BY id"))
40        return JSONResponse(result.all())
41
42
43routes = [Route("/articles", list_articles)]
44app = Starlette(debug=True, routes=routes, on_startup=[seed_database])
45
46
47def main() -> None:
48    """Seed the database outside of ASGI startup."""
49    asyncio.run(seed_database())
50
51
52if __name__ == "__main__":
53    main()