feat(api): Finished initial route collection.

This commit is contained in:
2025-06-10 13:00:37 +10:00
parent 94bc8b6c21
commit dc551b34a9
9 changed files with 1430 additions and 10 deletions

View File

@@ -3,6 +3,7 @@
- `/documents/{document_id}` with `GET`, `PATCH`, `DELETE`
- `/documents/{document_id}/stamps` which is passed to `/stamps` with `document_id` set.
"""
import logging
from datetime import datetime
from typing import Any, NamedTuple, Optional, Self, TypedDict, Unpack, reveal_type, List
from aiohttp import web
@@ -14,6 +15,7 @@ from .lib import ModelField, datamodelsv
from .stamps import Stamp, StampCreateParams, StampEditParams, StampPayload
routes = web.RouteTableDef()
logger = logging.getLogger(__name__)
class DocPayload(TypedDict):
@@ -61,6 +63,13 @@ class Document:
self.data = app[datamodelsv]
self.row = row
@classmethod
async def validate_create_params(cls, params):
if extra := next((key for key in params if key not in create_fields), None):
raise web.HTTPBadRequest(text=f"Invalid key '{extra}' passed to document creation.")
if missing := next((key for key in req_fields if key not in params), None):
raise web.HTTPBadRequest(text=f"Document params missing required key '{missing}'")
@classmethod
async def fetch_from_id(cls, app: web.Application, document_id: int) -> Optional[Self]:
data = app[datamodelsv]
@@ -222,10 +231,7 @@ class DocumentsView(web.View):
if key in request:
params.setdefault(key, request[key])
if extra := next((key for key in params if key not in create_fields), None):
raise web.HTTPBadRequest(text=f"Invalid key '{extra}' passed to document creation.")
if missing := next((key for key in req_fields if key not in params), None):
raise web.HTTPBadRequest(text=f"Document params missing required key '{missing}'")
await Document.validate_create_params(params)
document = await Document.create(self.request.app, **params)
payload = await document.prepare()
@@ -276,15 +282,18 @@ class DocumentView(web.View):
@routes.route('*', "/documents/{document_id}{tail:/stamps}")
@routes.route('*', "/documents/{document_id}{tail:/stamps/.*}")
async def document_stamps_route(request: web.Request):
document_id = request.match_info['document_id']
document = await Document.fetch_from_id(request.app, int(document_id))
document_id = int(request.match_info['document_id'])
document = await Document.fetch_from_id(request.app, document_id)
if document is None:
raise web.HTTPNotFound(text="No document exists with the given ID.")
new_path = request.match_info['tail']
logger.info(f"Redirecting {request=} to {new_path=} and setting {document_id=}")
new_request = request.clone(rel_url=new_path)
new_request['document_id'] = document_id
match_info = await request.app.router.resolve(new_request)
match_info.current_app = request.app
new_request._match_info = match_info
if match_info.handler:
return await match_info.handler(new_request)
else: