From 1c57bd202fb1f82e14c47dfca63454352999732c Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Fri, 10 Nov 2017 11:05:57 -0800 Subject: [PATCH] Replaced app_factory with new Datasette class This should make it easier to add unit tests. --- datasette/app.py | 83 ++++++++++++++++++++++++++---------------------- datasette/cli.py | 4 +-- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/datasette/app.py b/datasette/app.py index dca741ff..86a466d7 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -69,10 +69,10 @@ def ensure_build_metadata(files, regenerate=False): class BaseView(HTTPMethodView): template = None - def __init__(self, files, jinja, executor): - self.files = files - self.jinja = jinja - self.executor = executor + def __init__(self, datasette): + self.files = datasette.files + self.jinja = datasette.jinja + self.executor = datasette.executor def redirect(self, request, path): if request.query_string: @@ -185,10 +185,10 @@ class BaseView(HTTPMethodView): class IndexView(HTTPMethodView): - def __init__(self, files, jinja, executor): - self.files = files - self.jinja = jinja - self.executor = executor + def __init__(self, datasette): + self.files = datasette.files + self.jinja = datasette.jinja + self.executor = datasette.executor async def get(self, request): databases = [] @@ -460,36 +460,43 @@ def sqlite_timelimit(conn, ms): conn.set_progress_handler(None, 10000) -def app_factory(files, num_threads=3): - app = Sanic(__name__) - executor = futures.ThreadPoolExecutor(max_workers=num_threads) - jinja = SanicJinja2( - app, - loader=FileSystemLoader([ - str(app_root / 'datasette' / 'templates') - ]) - ) - app.add_route(IndexView.as_view(files, jinja, executor), '/') - # TODO: /favicon.ico and /-/static/ deserve far-future cache expires - app.add_route(favicon, '/favicon.ico') - app.static('/-/static/', str(app_root / 'datasette' / 'static')) - app.add_route( - DatabaseView.as_view(files, jinja, executor), - '/' - ) - app.add_route( - DatabaseDownload.as_view(files, jinja, executor), - '/' - ) - app.add_route( - TableView.as_view(files, jinja, executor), - '//' - ) - app.add_route( - RowView.as_view(files, jinja, executor), - '///' - ) - return app +class Datasette: + def __init__(self, files, num_threads=3): + self.files = files + self.num_threads = num_threads + self.executor = futures.ThreadPoolExecutor( + max_workers=num_threads + ) + + def app(self): + app = Sanic(__name__) + self.jinja = SanicJinja2( + app, + loader=FileSystemLoader([ + str(app_root / 'datasette' / 'templates') + ]) + ) + app.add_route(IndexView.as_view(self), '/') + # TODO: /favicon.ico and /-/static/ deserve far-future cache expires + app.add_route(favicon, '/favicon.ico') + app.static('/-/static/', str(app_root / 'datasette' / 'static')) + app.add_route( + DatabaseView.as_view(self), + '/' + ) + app.add_route( + DatabaseDownload.as_view(self), + '/' + ) + app.add_route( + TableView.as_view(self), + '//' + ) + app.add_route( + RowView.as_view(self), + '///' + ) + return app class InvalidSql(Exception): diff --git a/datasette/cli.py b/datasette/cli.py index 4131b52b..9284e867 100644 --- a/datasette/cli.py +++ b/datasette/cli.py @@ -1,6 +1,6 @@ import click from click_default_group import DefaultGroup -from .app import app_factory, ensure_build_metadata +from .app import Datasette, ensure_build_metadata @click.group(cls=DefaultGroup, default='serve', default_if_no_args=True) @@ -29,5 +29,5 @@ def serve(files, host, port, debug, reload): hupper.start_reloader('datasette.cli.serve') click.echo('Serve! files={} on port {}'.format(files, port)) - app = app_factory(files) + app = Datasette(files).app() app.run(host=host, port=port, debug=debug)