Compare commits

...

4 commits

Author SHA1 Message Date
Simon Willison
f1c3cc362d
Upgrade to starlette==0.1.15
Fixes this bug: https://github.com/encode/starlette/issues/32
2018-07-26 06:50:51 -07:00
Simon Willison
2302b76a2e
New dependencies: starlette and uvicorn 2018-07-26 06:10:34 -07:00
Simon Willison
563fab27cc
Mostly working index, database and table pages 2018-07-26 06:07:24 -07:00
Simon Willison
13ed3069f2
Started trying to get --asgi mode working 2018-07-26 05:29:31 -07:00
4 changed files with 95 additions and 3 deletions

View file

@ -430,8 +430,46 @@ class Datasette:
self.executor, sql_operation_in_thread
)
def app(self):
app = Sanic(__name__)
def asgi_app(self):
self.configure_jinja()
from starlette.routing import Router, Path, PathPrefix
from starlette.staticfiles import StaticFile, StaticFiles
return Router([
Path(
'/(?P<as_format>\.jsono?)?$',
app=IndexView(self).asgi_app(),
methods=['GET']
),
Path(
'/favicon.ico',
app=StaticFile(
path=str(app_root / "datasette" / "static" / "favicon.ico")
)
),
PathPrefix(
'/-/static/',
app=StaticFiles(
directory=str(app_root / "datasette" / "static")
)
),
Path(
"/(?P<db_name>[^/]+?)(?P<as_format>(\.jsono?|\.csv))?$",
app=DatabaseView(self).asgi_app(),
),
Path(
"/(?P<db_name>[^/]+?)/(?P<table_and_format>[^/]+?)$",
app=TableView(self).asgi_app(),
),
])
# app.add_route(
# DatabaseView.as_view(self), "/<db_name:[^/]+?><as_format:(\.jsono?|\.csv)?$>"
# )
# app.add_route(
# TableView.as_view(self),
# "/<db_name:[^/]+>/<table_and_format:[^/]+?$>",
# )
def configure_jinja(self):
default_templates = str(app_root / "datasette" / "templates")
template_paths = []
if self.template_dir:
@ -459,6 +497,10 @@ class Datasette:
self.jinja_env.filters["escape_sqlite"] = escape_sqlite
self.jinja_env.filters["to_css_class"] = to_css_class
pm.hook.prepare_jinja2_environment(env=self.jinja_env)
def app(self):
app = Sanic(__name__)
self.configure_jinja()
app.add_route(IndexView.as_view(self), "/<as_format:(\.jsono?)?$>")
# TODO: /favicon.ico and /-/static/ deserve far-future cache expires
app.add_route(favicon, "/favicon.ico")

View file

@ -256,6 +256,9 @@ def package(
"-h", "--host", default="127.0.0.1", help="host for server, defaults to 127.0.0.1"
)
@click.option("-p", "--port", default=8001, help="port for server, defaults to 8001")
@click.option(
"--asgi", is_flag=True, help="Run in ASGI mode"
)
@click.option(
"--debug", is_flag=True, help="Enable debug mode - useful for development"
)
@ -316,6 +319,7 @@ def serve(
files,
host,
port,
asgi,
debug,
reload,
cors,
@ -372,4 +376,9 @@ def serve(
)
# Force initial hashing/table counting
ds.inspect()
if asgi:
import uvicorn
app = ds.asgi_app()
uvicorn.run(app, host, port, log_level="info")
else:
ds.app().run(host=host, port=port, debug=debug)

View file

@ -12,6 +12,8 @@ from sanic import response
from sanic.exceptions import NotFound
from sanic.views import HTTPMethodView
from starlette import asgi_application, Response
from datasette import __version__
from datasette.utils import (
CustomJSONEncoder,
@ -43,8 +45,45 @@ class DatasetteError(Exception):
self.messagge_is_html = messagge_is_html
class RequestWrapper:
# Implements the subset of the Sanic request that my code uses
def __init__(self, starlette_request):
self._request = starlette_request
@property
def path(self):
return self._request.url.path
@property
def query_string(self):
return str(self._request._scope["query_string"])
@property
def args(self):
# Key/list-of-values
# There's probably a better way to do this:
d = {}
for key, value in self._request.query_params:
d.setdefault(key, []).append(value)
return d
@property
def raw_args(self):
# Flat key/first-value dictionary
return dict(self.args)
class RenderMixin(HTTPMethodView):
def asgi_app(self):
@asgi_application
async def app(request):
sanic_response = await self.get(
RequestWrapper(request), **request["kwargs"]
)
return Response(sanic_response.body)
return app
def render(self, templates, **context):
template = self.ds.jinja_env.select_template(templates)
select_templates = [

View file

@ -41,6 +41,8 @@ setup(
'hupper==1.0',
'pint==0.8.1',
'pluggy>=0.1.0,<1.0',
'starlette==0.1.15',
'uvicorn==0.2.21',
],
entry_points='''
[console_scripts]