await request.post_body() method, closes #897

pull/902/head
Simon Willison 2020-07-17 13:12:35 -07:00
rodzic c5f06bc356
commit 1f6a134369
3 zmienionych plików z 37 dodań i 3 usunięć

Wyświetl plik

@ -90,8 +90,7 @@ class Request:
def actor(self):
return self.scope.get("actor", None)
async def post_vars(self):
body = []
async def post_body(self):
body = b""
more_body = True
while more_body:
@ -99,7 +98,10 @@ class Request:
assert message["type"] == "http.request", message
body += message.get("body", b"")
more_body = message.get("more_body", False)
return body
async def post_vars(self):
body = await self.post_body()
return dict(parse_qsl(body.decode("utf-8"), keep_blank_values=True))
@classmethod

Wyświetl plik

@ -48,11 +48,14 @@ The request object is passed to various plugin hooks. It represents an incoming
``.actor`` - dictionary (str -> Any) or None
The currently authenticated actor (see :ref:`actors <authentication_actor>`), or ``None`` if the request is unauthenticated.
The object also has one awaitable method:
The object also has two awaitable methods:
``await request.post_vars()`` - dictionary
Returns a dictionary of form variables that were submitted in the request body via ``POST``. Don't forget to read about :ref:`internals_csrf`!
``await request.post_body()`` - bytes
Returns the un-parsed body of a request submitted by ``POST`` - useful for things like incoming JSON data.
.. _internals_multiparams:
The MultiParams class

Wyświetl plik

@ -1,4 +1,5 @@
from datasette.utils.asgi import Request
import json
import pytest
@ -26,6 +27,34 @@ async def test_request_post_vars():
assert {"foo": "bar", "baz": "1", "empty": ""} == await request.post_vars()
@pytest.mark.asyncio
async def test_request_post_body():
scope = {
"http_version": "1.1",
"method": "POST",
"path": "/",
"raw_path": b"/",
"query_string": b"",
"scheme": "http",
"type": "http",
"headers": [[b"content-type", b"application/json"]],
}
data = {"hello": "world"}
async def receive():
return {
"type": "http.request",
"body": json.dumps(data, indent=4).encode("utf-8"),
"more_body": False,
}
request = Request(scope, receive)
body = await request.post_body()
assert isinstance(body, bytes)
assert data == json.loads(body)
def test_request_args():
request = Request.fake("/foo?multi=1&multi=2&single=3")
assert "1" == request.args.get("multi")