Docs + unit tests for Response, closes #821

pull/809/head
Simon Willison 2020-06-08 20:32:10 -07:00
rodzic f5e79adf26
commit db660db463
4 zmienionych plików z 86 dodań i 1 usunięć

Wyświetl plik

@ -405,6 +405,15 @@ class Response:
content_type="text/plain; charset=utf-8",
)
@classmethod
def json(cls, body, status=200, headers=None):
return cls(
json.dumps(body),
status=status,
headers=headers,
content_type="application/json; charset=utf-8",
)
@classmethod
def redirect(cls, path, status=302, headers=None):
headers = headers or {}

Wyświetl plik

@ -80,6 +80,54 @@ Consider the querystring ``?foo=1&foo=2&bar=3`` - with two values for ``foo`` an
``len(request.args)`` - integer
Returns the number of keys.
.. _internals_response:
Response class
~~~~~~~~~~~~~~
The ``Response`` class can be returned from view functions that have been registered using the :ref:`plugin_register_routes` hook.
The ``Response()`` constructor takes the following arguments:
``body`` - string
The body of the response.
``status`` - integer (optional)
The HTTP status - defaults to 200.
``headers`` - dictionary (optional)
A dictionary of extra HTTP headers, e.g. ``{"x-hello": "world"}``.
``content_type`` - string (optional)
The content-type for the response. Defaults to ``text/plain``.
For example:
.. code-block:: python
from datasette.utils.asgi import Response
response = Response(
"<xml>This is XML</xml>",
content_type="application/xml; charset=utf-8"
)
The easiest way to create responses is using the ``Response.text(...)``, ``Response.html(...)``, ``Response.json(...)`` or ``Response.redirect(...)`` helper methods:
.. code-block:: python
from datasette.utils.asgi import Response
html_response = Response.html("This is HTML")
json_response = Response.json({"this_is": "json"})
text_response = Response.text("This will become utf-8 encoded text")
# Redirects are served as 302, unless you pass status=301:
redirect_response = Response.redirect("https://latest.datasette.io/")
Each of these responses will use the correct corresponding content-type - ``text/html; charset=utf-8``, ``application/json; charset=utf-8`` or ``text/plain; charset=utf-8`` respectively.
Each of the helper methods take optional ``status=`` and ``headers=`` arguments, documented above.
.. _internals_datasette:
Datasette class

Wyświetl plik

@ -882,7 +882,7 @@ The optional view function arguments are as follows:
``receive`` - function
The ASGI receive function.
The function can either return a ``Response`` or it can return nothing and instead respond directly to the request using the ASGI ``receive`` function (for advanced uses only).
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).
.. _plugin_register_facet_classes:

Wyświetl plik

@ -0,0 +1,28 @@
from datasette.utils.asgi import Response
def test_response_html():
response = Response.html("Hello from HTML")
assert 200 == response.status
assert "Hello from HTML" == response.body
assert "text/html; charset=utf-8" == response.content_type
def test_response_text():
response = Response.text("Hello from text")
assert 200 == response.status
assert "Hello from text" == response.body
assert "text/plain; charset=utf-8" == response.content_type
def test_response_json():
response = Response.json({"this_is": "json"})
assert 200 == response.status
assert '{"this_is": "json"}' == response.body
assert "application/json; charset=utf-8" == response.content_type
def test_response_redirect():
response = Response.redirect("/foo")
assert 302 == response.status
assert "/foo" == response.headers["Location"]