diff --git a/datasette/views/base.py b/datasette/views/base.py index 9db8cc76..69c0ba16 100644 --- a/datasette/views/base.py +++ b/datasette/views/base.py @@ -49,7 +49,68 @@ class DatasetteError(Exception): self.messagge_is_html = messagge_is_html -class BaseView(HTTPMethodView): +class AsgiRouter: + def __init__(self, routes=None): + routes = routes or [] + self.routes = [ + # Compile any strings to regular expressions + (re.compile(pattern) if isinstance(pattern, str) else pattern, view) + for pattern, view in routes + ] + + async def __call__(self, scope, receive, send): + for regex, view in self.routes: + match = regex.match(scope["path"]) + if match is not None: + new_scope = dict(scope, url_route={"kwargs": match.groupdict()}) + return await view(new_scope, receive, send) + return await self.handle_404(scope, receive, send) + + async def handle_404(self, scope, receive, send): + await send( + { + "type": "http.response.start", + "status": 404, + "headers": [[b"content-type", b"text/html"]], + } + ) + await send({"type": "http.response.body", "body": b"