mirror of
https://github.com/simonw/datasette.git
synced 2025-12-10 16:51:24 +01:00
await Request(scope, receive).post_vars() method, closes #700
Needed for #698
This commit is contained in:
parent
7e357abbc3
commit
a000c80d50
2 changed files with 37 additions and 4 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import json
|
import json
|
||||||
from datasette.utils import RequestParameters
|
from datasette.utils import RequestParameters
|
||||||
from mimetypes import guess_type
|
from mimetypes import guess_type
|
||||||
from urllib.parse import parse_qs, urlunparse
|
from urllib.parse import parse_qs, urlunparse, parse_qsl
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from html import escape
|
from html import escape
|
||||||
import re
|
import re
|
||||||
|
|
@ -13,8 +13,9 @@ class NotFound(Exception):
|
||||||
|
|
||||||
|
|
||||||
class Request:
|
class Request:
|
||||||
def __init__(self, scope):
|
def __init__(self, scope, receive):
|
||||||
self.scope = scope
|
self.scope = scope
|
||||||
|
self.receive = receive
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def method(self):
|
def method(self):
|
||||||
|
|
@ -66,6 +67,18 @@ class Request:
|
||||||
def raw_args(self):
|
def raw_args(self):
|
||||||
return {key: value[0] for key, value in self.args.items()}
|
return {key: value[0] for key, value in self.args.items()}
|
||||||
|
|
||||||
|
async def post_vars(self):
|
||||||
|
body = []
|
||||||
|
body = b""
|
||||||
|
more_body = True
|
||||||
|
while more_body:
|
||||||
|
message = await self.receive()
|
||||||
|
assert message["type"] == "http.request", message
|
||||||
|
body += message.get("body", b"")
|
||||||
|
more_body = message.get("more_body", False)
|
||||||
|
|
||||||
|
return dict(parse_qsl(body.decode("utf-8")))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fake(cls, path_with_query_string, method="GET", scheme="http"):
|
def fake(cls, path_with_query_string, method="GET", scheme="http"):
|
||||||
"Useful for constructing Request objects for tests"
|
"Useful for constructing Request objects for tests"
|
||||||
|
|
@ -79,7 +92,7 @@ class Request:
|
||||||
"scheme": scheme,
|
"scheme": scheme,
|
||||||
"type": "http",
|
"type": "http",
|
||||||
}
|
}
|
||||||
return cls(scope)
|
return cls(scope, None)
|
||||||
|
|
||||||
|
|
||||||
class AsgiRouter:
|
class AsgiRouter:
|
||||||
|
|
@ -171,7 +184,7 @@ class AsgiView:
|
||||||
# that were already tucked into scope["url_route"]["kwargs"] by
|
# that were already tucked into scope["url_route"]["kwargs"] by
|
||||||
# the router, similar to how Django Channels works:
|
# the router, similar to how Django Channels works:
|
||||||
# https://channels.readthedocs.io/en/latest/topics/routing.html#urlrouter
|
# https://channels.readthedocs.io/en/latest/topics/routing.html#urlrouter
|
||||||
request = Request(scope)
|
request = Request(scope, receive)
|
||||||
self = view.view_class(*class_args, **class_kwargs)
|
self = view.view_class(*class_args, **class_kwargs)
|
||||||
response = await self.dispatch_request(
|
response = await self.dispatch_request(
|
||||||
request, **scope["url_route"]["kwargs"]
|
request, **scope["url_route"]["kwargs"]
|
||||||
|
|
|
||||||
|
|
@ -423,3 +423,23 @@ def test_check_connection_spatialite_raises():
|
||||||
def test_check_connection_passes():
|
def test_check_connection_passes():
|
||||||
conn = sqlite3.connect(":memory:")
|
conn = sqlite3.connect(":memory:")
|
||||||
utils.check_connection(conn)
|
utils.check_connection(conn)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_request_post_vars():
|
||||||
|
scope = {
|
||||||
|
"http_version": "1.1",
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/",
|
||||||
|
"raw_path": b"/",
|
||||||
|
"query_string": b"",
|
||||||
|
"scheme": "http",
|
||||||
|
"type": "http",
|
||||||
|
"headers": [[b"content-type", b"application/x-www-form-urlencoded"]],
|
||||||
|
}
|
||||||
|
|
||||||
|
async def receive():
|
||||||
|
return {"type": "http.request", "body": b"foo=bar&baz=1", "more_body": False}
|
||||||
|
|
||||||
|
request = Request(scope, receive)
|
||||||
|
assert {"foo": "bar", "baz": "1"} == await request.post_vars()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue