Support non-async view functions, closes #867

pull/868/head
Simon Willison 2020-06-27 11:30:34 -07:00
rodzic 1bb33dab49
commit 4b142862f2
4 zmienionych plików z 33 dodań i 10 usunięć

Wyświetl plik

@ -3,6 +3,7 @@ import asgi_csrf
import collections
import datetime
import hashlib
import inspect
import itertools
import json
import os
@ -40,6 +41,7 @@ from .database import Database, QueryInterrupted
from .utils import (
async_call_with_supported_arguments,
call_with_supported_arguments,
escape_css_string,
escape_sqlite,
format_bytes,
@ -1056,14 +1058,24 @@ def _cleaner_task_str(task):
def wrap_view(view_fn, datasette):
async def asgi_view_fn(scope, receive, send):
response = await async_call_with_supported_arguments(
view_fn,
scope=scope,
receive=receive,
send=send,
request=Request(scope, receive),
datasette=datasette,
)
if inspect.iscoroutinefunction(view_fn):
response = await async_call_with_supported_arguments(
view_fn,
scope=scope,
receive=receive,
send=send,
request=Request(scope, receive),
datasette=datasette,
)
else:
response = call_with_supported_arguments(
view_fn,
scope=scope,
receive=receive,
send=send,
request=Request(scope, receive),
datasette=datasette,
)
if response is not None:
await response.asgi_send(send)

Wyświetl plik

@ -514,7 +514,7 @@ register_routes()
Register additional view functions to execute for specified URL routes.
Return a list of ``(regex, async_view_function)`` pairs, something like this:
Return a list of ``(regex, view_function)`` pairs, something like this:
.. code-block:: python
@ -554,6 +554,8 @@ The optional view function arguments are as follows:
``receive`` - function
The ASGI receive function.
The view function can be a regular function or an ``async def`` function, depending on if it needs to use any ``await`` APIs.
The function can either return a :ref:`internals_response` or it can return nothing and instead respond directly to the request using the ASGI ``send`` function (for advanced uses only).
Examples: `datasette-auth-github <https://github.com/simonw/datasette-auth-github>`__, `datasette-psutil <https://github.com/simonw/datasette-psutil>`__

Wyświetl plik

@ -187,12 +187,16 @@ def register_routes():
await datasette.render_template("csrftoken_form.html", request=request)
)
def not_async():
return Response.html("This was not async")
return [
(r"/one/$", one),
(r"/two/(?P<name>.*)$", two),
(r"/three/$", three),
(r"/post/$", post),
(r"/csrftoken-form/$", csrftoken_form),
(r"/not-async/$", not_async),
]

Wyświetl plik

@ -565,7 +565,12 @@ def test_actor_json(app_client):
@pytest.mark.parametrize(
"path,body", [("/one/", "2"), ("/two/Ray?greeting=Hail", "Hail Ray"),]
"path,body",
[
("/one/", "2"),
("/two/Ray?greeting=Hail", "Hail Ray"),
("/not-async/", "This was not async"),
],
)
def test_register_routes(app_client, path, body):
response = app_client.get(path)