Add query_params support

This commit is contained in:
Tom Christie 2019-05-08 12:43:06 +01:00
parent 211bef130b
commit faededae59
4 changed files with 56 additions and 12 deletions

View File

@ -87,14 +87,14 @@ Additionally, credit is due to for `urllib3` for plenty of design inspiration.
```
* `def __init__([ssl], [timeout], [pool_limits], [max_redirects])`
* `async def .request(method, url, [content], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .get(url, [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .options(url, [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .head(url, [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .post(url, [content], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .put(url, [content], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .patch(url, [content], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .delete(url, [content], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .request(method, url, [content], [query_params], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .get(url, [query_params], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .options(url, [query_params], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .head(url, [query_params], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .post(url, [content], [query_params], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .put(url, [content], [query_params], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .patch(url, [content], [query_params], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `async def .delete(url, [content], [query_params], [headers], [stream], [allow_redirects], [ssl], [timeout])`
* `def .prepare_request(request)`
* `async def .send(request, [stream], [allow_redirects], [ssl], [timeout])`
* `async def .close()`

View File

@ -15,7 +15,15 @@ from .config import (
TimeoutConfig,
)
from .dispatch.connection_pool import ConnectionPool
from .models import URL, ByteOrByteStream, HeaderTypes, Request, Response, URLTypes
from .models import (
URL,
ByteOrByteStream,
HeaderTypes,
QueryParamTypes,
Request,
Response,
URLTypes,
)
class Client:
@ -42,13 +50,16 @@ class Client:
url: URLTypes,
*,
content: ByteOrByteStream = b"",
query_params: QueryParamTypes = None,
headers: HeaderTypes = None,
stream: bool = False,
allow_redirects: bool = True,
ssl: SSLConfig = None,
timeout: TimeoutConfig = None,
) -> Response:
request = Request(method, url, headers=headers, content=content)
request = Request(
method, url, query_params=query_params, headers=headers, content=content
)
self.prepare_request(request)
response = await self.send(
request,
@ -63,6 +74,7 @@ class Client:
self,
url: URLTypes,
*,
query_params: QueryParamTypes = None,
headers: HeaderTypes = None,
stream: bool = False,
allow_redirects: bool = True,
@ -72,6 +84,7 @@ class Client:
return await self.request(
"GET",
url,
query_params=query_params,
headers=headers,
stream=stream,
allow_redirects=allow_redirects,
@ -83,6 +96,7 @@ class Client:
self,
url: URLTypes,
*,
query_params: QueryParamTypes = None,
headers: HeaderTypes = None,
stream: bool = False,
allow_redirects: bool = True,
@ -92,6 +106,7 @@ class Client:
return await self.request(
"OPTIONS",
url,
query_params=query_params,
headers=headers,
stream=stream,
allow_redirects=allow_redirects,
@ -103,6 +118,7 @@ class Client:
self,
url: URLTypes,
*,
query_params: QueryParamTypes = None,
headers: HeaderTypes = None,
stream: bool = False,
allow_redirects: bool = False, #  Note: Differs to usual default.
@ -112,6 +128,7 @@ class Client:
return await self.request(
"HEAD",
url,
query_params=query_params,
headers=headers,
stream=stream,
allow_redirects=allow_redirects,
@ -124,6 +141,7 @@ class Client:
url: URLTypes,
*,
content: ByteOrByteStream = b"",
query_params: QueryParamTypes = None,
headers: HeaderTypes = None,
stream: bool = False,
allow_redirects: bool = True,
@ -134,6 +152,7 @@ class Client:
"POST",
url,
content=content,
query_params=query_params,
headers=headers,
stream=stream,
allow_redirects=allow_redirects,
@ -146,6 +165,7 @@ class Client:
url: URLTypes,
*,
content: ByteOrByteStream = b"",
query_params: QueryParamTypes = None,
headers: HeaderTypes = None,
stream: bool = False,
allow_redirects: bool = True,
@ -156,6 +176,7 @@ class Client:
"PUT",
url,
content=content,
query_params=query_params,
headers=headers,
stream=stream,
allow_redirects=allow_redirects,
@ -168,6 +189,7 @@ class Client:
url: URLTypes,
*,
content: ByteOrByteStream = b"",
query_params: QueryParamTypes = None,
headers: HeaderTypes = None,
stream: bool = False,
allow_redirects: bool = True,
@ -178,6 +200,7 @@ class Client:
"PATCH",
url,
content=content,
query_params=query_params,
headers=headers,
stream=stream,
allow_redirects=allow_redirects,
@ -190,6 +213,7 @@ class Client:
url: URLTypes,
*,
content: ByteOrByteStream = b"",
query_params: QueryParamTypes = None,
headers: HeaderTypes = None,
stream: bool = False,
allow_redirects: bool = True,
@ -200,6 +224,7 @@ class Client:
"DELETE",
url,
content=content,
query_params=query_params,
headers=headers,
stream=stream,
allow_redirects=allow_redirects,

View File

@ -49,7 +49,10 @@ ByteOrByteStream = typing.Union[bytes, typing.AsyncIterator[bytes]]
class URL:
def __init__(
self, url: URLTypes, allow_relative: bool = False, params: QueryParamTypes = None
self,
url: URLTypes,
allow_relative: bool = False,
query_params: QueryParamTypes = None,
) -> None:
if isinstance(url, rfc3986.uri.URIReference):
self.components = url
@ -67,6 +70,11 @@ class URL:
# Normalize scheme and domain name.
self.components = self.components.normalize()
# Add any query parameters.
if query_params:
query_string = str(QueryParams(query_params))
self.components = self.components.copy_with(query=query_string)
# Enforce absolute URLs by default.
if not allow_relative:
if not self.scheme:
@ -444,11 +452,12 @@ class Request:
method: str,
url: typing.Union[str, URL],
*,
query_params: QueryParamTypes = None,
headers: HeaderTypes = None,
content: ByteOrByteStream = b"",
):
self.method = method.upper()
self.url = URL(url) if isinstance(url, str) else url
self.url = URL(url, query_params=query_params)
if isinstance(content, bytes):
self.is_streaming = False
self.content = content

View File

@ -23,3 +23,13 @@ def test_url():
new = url.copy_with(scheme="http")
assert new == URL("http://example.org:123/path/to/somewhere?abc=123#anchor")
assert new.scheme == "http"
def test_url_query_params():
url = URL("https://example.org:123/path/to/somewhere", query_params={"a": "123"})
assert str(url) == "https://example.org:123/path/to/somewhere?a=123"
url = URL(
"https://example.org:123/path/to/somewhere?b=456", query_params={"a": "123"}
)
assert str(url) == "https://example.org:123/path/to/somewhere?a=123"