Merge pull request 'Utilisation de async pour la base de données et les routes (#2)' (#3) from feature-async-routes into main

Reviewed-on: #3
This commit is contained in:
Barbagus 2023-11-08 20:14:51 +00:00
commit fb2b36b22c
6 changed files with 52 additions and 40 deletions

View File

@ -1,24 +0,0 @@
// cSpell Settings
{
// Version of the setting file. Always 0.2
"version": "0.2",
// language - current active spelling language
"language": "en",
// words - list of words to be always considered correct
"words": [
"executemany",
"executescript",
"GTFS",
"headsign"
],
// flagWords - list of words to be always considered incorrect
// This is useful for offensive words and common spelling errors.
// For example "hte" should be "the"
"flagWords": [],
"overrides": [
{
"language": "fr-FR",
"filename": "**.md"
}
]
}

View File

@ -10,6 +10,7 @@ dependencies = [
"pydantic-settings", "pydantic-settings",
"jinja2", "jinja2",
"jinja2-fragments", "jinja2-fragments",
"aiosqlite",
] ]
requires-python = ">=3.11" requires-python = ">=3.11"

View File

@ -11,6 +11,8 @@ class Settings(BaseSettings):
TEMPLATE_DIR: str = path.join(APP_DIR, "templates") TEMPLATE_DIR: str = path.join(APP_DIR, "templates")
DATA_DIR: str = path.join(path.dirname(APP_DIR), "data") DATA_DIR: str = path.join(path.dirname(APP_DIR), "data")
SQLITE_URI: str = f"file:{path.join(DATA_DIR, 'db.sqlite')}?mode=ro"
FASTAPI_PROPERTIES: dict = { FASTAPI_PROPERTIES: dict = {
"title": "TER", "title": "TER",
"description": "", "description": "",

View File

@ -1,16 +1,32 @@
import sqlite3 from typing import Any
import os.path as path from collections.abc import Sequence, Iterable
import contextlib as ctx
import aiosqlite
from ter.config import Settings from ter.config import Settings
settings = Settings() settings = Settings()
def connect_db(): class Database:
return ctx.closing( Params = Sequence[Any] | dict[str, Any]
sqlite3.connect(
f"file:{path.join(settings.DATA_DIR, 'db.sqlite')}?mode=ro", def __init__(self, uri: str) -> None:
uri=True, self._uri: str = uri
) self._connection: aiosqlite.Connection | None = None
)
async def connect(self):
self._connection = await aiosqlite.connect(self._uri, uri=True)
async def disconnect(self):
await self._connection.close()
self._connection = None
async def execute(self, sql: str, params: Params = ()):
return await self._connection.execute(sql, params)
async def executemany(self, sql: str, params: Iterable[Params]):
return await self._connection.executemany(sql, params)
database = Database(settings.SQLITE_URI)

View File

@ -1,15 +1,32 @@
import contextlib as ctx
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from ter.config import Settings from ter.config import Settings
from ter.helpers import database
from ter.routes import router from ter.routes import router
settings = Settings() settings = Settings()
@ctx.asynccontextmanager
async def lifespan(app: FastAPI):
await database.connect()
yield
await database.disconnect()
def get_app() -> FastAPI: def get_app() -> FastAPI:
app = FastAPI(**settings.FASTAPI_PROPERTIES) app = FastAPI(
app.mount("/static", StaticFiles(directory=settings.STATIC_DIR), name="static") **settings.FASTAPI_PROPERTIES,
lifespan=lifespan,
)
app.mount(
"/static",
StaticFiles(directory=settings.STATIC_DIR),
name="static",
)
app.include_router(router) app.include_router(router)
return app return app

View File

@ -3,7 +3,7 @@ from jinja2_fragments.fastapi import Jinja2Blocks
from ter.config import Settings from ter.config import Settings
from ter.helpers import connect_db from ter.helpers import database
settings = Settings() settings = Settings()
router = APIRouter() router = APIRouter()
@ -11,11 +11,11 @@ templates = Jinja2Blocks(settings.TEMPLATE_DIR)
@router.get("/") @router.get("/")
def index(request: Request): async def index(request: Request):
"""Home page.""" """Home page."""
with connect_db() as db: cursor = await database.execute("SELECT * FROM agency")
agencies = db.execute("SELECT * FROM agency").fetchall() agencies = await cursor.fetchall()
context = {"request": request, "agencies": agencies} context = {"request": request, "agencies": agencies}