kopia lustrzana https://github.com/simonw/datasette
Support non-async view functions, closes #867
rodzic
1bb33dab49
commit
4b142862f2
|
@ -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)
|
||||
|
||||
|
|
|
@ -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>`__
|
||||
|
|
|
@ -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),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Ładowanie…
Reference in New Issue