* Prefer httpx.Client over httpx.AsyncClient in test cases, unless required.
* Prefer httpx.Client in test_headers
* Consistent httpx imports and httpx.Client usage
* Use 'import httpx' consistently in tests. Prefer httpx.Client.
from http.cookiejar import Cookie, CookieJar
import httpcore
-import pytest
-from httpx import AsyncClient, Cookies
+import httpx
from httpx._content_streams import ByteStream, ContentStream, JSONStream
return default
-class MockTransport(httpcore.AsyncHTTPTransport):
- async def request(
+class MockTransport(httpcore.SyncHTTPTransport):
+ def request(
self,
method: bytes,
url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes],
headers: typing.List[typing.Tuple[bytes, bytes]] = None,
- stream: httpcore.AsyncByteStream = None,
+ stream: httpcore.SyncByteStream = None,
timeout: typing.Mapping[str, typing.Optional[float]] = None,
) -> typing.Tuple[
bytes, int, bytes, typing.List[typing.Tuple[bytes, bytes]], ContentStream
raise NotImplementedError() # pragma: no cover
-@pytest.mark.asyncio
-async def test_set_cookie() -> None:
+def test_set_cookie() -> None:
"""
Send a request including a cookie.
"""
url = "http://example.org/echo_cookies"
cookies = {"example-name": "example-value"}
- client = AsyncClient(transport=MockTransport())
- response = await client.get(url, cookies=cookies)
+ client = httpx.Client(transport=MockTransport())
+ response = client.get(url, cookies=cookies)
assert response.status_code == 200
assert response.json() == {"cookies": "example-name=example-value"}
-@pytest.mark.asyncio
-async def test_set_cookie_with_cookiejar() -> None:
+def test_set_cookie_with_cookiejar() -> None:
"""
Send a request including a cookie, using a `CookieJar` instance.
"""
)
cookies.set_cookie(cookie)
- client = AsyncClient(transport=MockTransport())
- response = await client.get(url, cookies=cookies)
+ client = httpx.Client(transport=MockTransport())
+ response = client.get(url, cookies=cookies)
assert response.status_code == 200
assert response.json() == {"cookies": "example-name=example-value"}
-@pytest.mark.asyncio
-async def test_setting_client_cookies_to_cookiejar() -> None:
+def test_setting_client_cookies_to_cookiejar() -> None:
"""
Send a request including a cookie, using a `CookieJar` instance.
"""
)
cookies.set_cookie(cookie)
- client = AsyncClient(transport=MockTransport())
+ client = httpx.Client(transport=MockTransport())
client.cookies = cookies # type: ignore
- response = await client.get(url)
+ response = client.get(url)
assert response.status_code == 200
assert response.json() == {"cookies": "example-name=example-value"}
-@pytest.mark.asyncio
-async def test_set_cookie_with_cookies_model() -> None:
+def test_set_cookie_with_cookies_model() -> None:
"""
Send a request including a cookie, using a `Cookies` instance.
"""
url = "http://example.org/echo_cookies"
- cookies = Cookies()
+ cookies = httpx.Cookies()
cookies["example-name"] = "example-value"
- client = AsyncClient(transport=MockTransport())
- response = await client.get(url, cookies=cookies)
+ client = httpx.Client(transport=MockTransport())
+ response = client.get(url, cookies=cookies)
assert response.status_code == 200
assert response.json() == {"cookies": "example-name=example-value"}
-@pytest.mark.asyncio
-async def test_get_cookie() -> None:
+def test_get_cookie() -> None:
url = "http://example.org/set_cookie"
- client = AsyncClient(transport=MockTransport())
- response = await client.get(url)
+ client = httpx.Client(transport=MockTransport())
+ response = client.get(url)
assert response.status_code == 200
assert response.cookies["example-name"] == "example-value"
assert client.cookies["example-name"] == "example-value"
-@pytest.mark.asyncio
-async def test_cookie_persistence() -> None:
+def test_cookie_persistence() -> None:
"""
Ensure that Client instances persist cookies between requests.
"""
- client = AsyncClient(transport=MockTransport())
+ client = httpx.Client(transport=MockTransport())
- response = await client.get("http://example.org/echo_cookies")
+ response = client.get("http://example.org/echo_cookies")
assert response.status_code == 200
assert response.json() == {"cookies": None}
- response = await client.get("http://example.org/set_cookie")
+ response = client.get("http://example.org/set_cookie")
assert response.status_code == 200
assert response.cookies["example-name"] == "example-value"
assert client.cookies["example-name"] == "example-value"
- response = await client.get("http://example.org/echo_cookies")
+ response = client.get("http://example.org/echo_cookies")
assert response.status_code == 200
assert response.json() == {"cookies": "example-name=example-value"}
import httpcore
import pytest
-from httpx import AsyncClient, Headers, Request, __version__
+import httpx
from httpx._content_streams import ContentStream, JSONStream
-class MockTransport(httpcore.AsyncHTTPTransport):
- async def request(
+class MockTransport(httpcore.SyncHTTPTransport):
+ def request(
self,
method: bytes,
url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes],
headers: typing.List[typing.Tuple[bytes, bytes]] = None,
- stream: httpcore.AsyncByteStream = None,
+ stream: httpcore.SyncByteStream = None,
timeout: typing.Mapping[str, typing.Optional[float]] = None,
) -> typing.Tuple[
bytes, int, bytes, typing.List[typing.Tuple[bytes, bytes]], ContentStream
return b"HTTP/1.1", 200, b"OK", [], body
-@pytest.mark.asyncio
-async def test_client_header():
+def test_client_header():
"""
Set a header in the Client.
"""
url = "http://example.org/echo_headers"
headers = {"Example-Header": "example-value"}
- client = AsyncClient(transport=MockTransport(), headers=headers)
- response = await client.get(url)
+ client = httpx.Client(transport=MockTransport(), headers=headers)
+ response = client.get(url)
assert response.status_code == 200
assert response.json() == {
"connection": "keep-alive",
"example-header": "example-value",
"host": "example.org",
- "user-agent": f"python-httpx/{__version__}",
+ "user-agent": f"python-httpx/{httpx.__version__}",
}
}
-@pytest.mark.asyncio
-async def test_header_merge():
+def test_header_merge():
url = "http://example.org/echo_headers"
client_headers = {"User-Agent": "python-myclient/0.2.1"}
request_headers = {"X-Auth-Token": "FooBarBazToken"}
- client = AsyncClient(transport=MockTransport(), headers=client_headers)
- response = await client.get(url, headers=request_headers)
+ client = httpx.Client(transport=MockTransport(), headers=client_headers)
+ response = client.get(url, headers=request_headers)
assert response.status_code == 200
assert response.json() == {
}
-@pytest.mark.asyncio
-async def test_header_merge_conflicting_headers():
+def test_header_merge_conflicting_headers():
url = "http://example.org/echo_headers"
client_headers = {"X-Auth-Token": "FooBar"}
request_headers = {"X-Auth-Token": "BazToken"}
- client = AsyncClient(transport=MockTransport(), headers=client_headers)
- response = await client.get(url, headers=request_headers)
+ client = httpx.Client(transport=MockTransport(), headers=client_headers)
+ response = client.get(url, headers=request_headers)
assert response.status_code == 200
assert response.json() == {
"accept-encoding": "gzip, deflate, br",
"connection": "keep-alive",
"host": "example.org",
- "user-agent": f"python-httpx/{__version__}",
+ "user-agent": f"python-httpx/{httpx.__version__}",
"x-auth-token": "BazToken",
}
}
-@pytest.mark.asyncio
-async def test_header_update():
+def test_header_update():
url = "http://example.org/echo_headers"
- client = AsyncClient(transport=MockTransport())
- first_response = await client.get(url)
+ client = httpx.Client(transport=MockTransport())
+ first_response = client.get(url)
client.headers.update(
{"User-Agent": "python-myclient/0.2.1", "Another-Header": "AThing"}
)
- second_response = await client.get(url)
+ second_response = client.get(url)
assert first_response.status_code == 200
assert first_response.json() == {
"accept-encoding": "gzip, deflate, br",
"connection": "keep-alive",
"host": "example.org",
- "user-agent": f"python-httpx/{__version__}",
+ "user-agent": f"python-httpx/{httpx.__version__}",
}
}
def test_header_does_not_exist():
- headers = Headers({"foo": "bar"})
+ headers = httpx.Headers({"foo": "bar"})
with pytest.raises(KeyError):
del headers["baz"]
-@pytest.mark.asyncio
-async def test_host_with_auth_and_port_in_url():
+def test_host_with_auth_and_port_in_url():
"""
The Host header should only include the hostname, or hostname:port
(for non-default ports only). Any userinfo or default port should not
"""
url = "http://username:password@example.org:80/echo_headers"
- client = AsyncClient(transport=MockTransport())
- response = await client.get(url)
+ client = httpx.Client(transport=MockTransport())
+ response = client.get(url)
assert response.status_code == 200
assert response.json() == {
"accept-encoding": "gzip, deflate, br",
"connection": "keep-alive",
"host": "example.org",
- "user-agent": f"python-httpx/{__version__}",
+ "user-agent": f"python-httpx/{httpx.__version__}",
"authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
}
}
-@pytest.mark.asyncio
-async def test_host_with_non_default_port_in_url():
+def test_host_with_non_default_port_in_url():
"""
If the URL includes a non-default port, then it should be included in
the Host header.
"""
url = "http://username:password@example.org:123/echo_headers"
- client = AsyncClient(transport=MockTransport())
- response = await client.get(url)
+ client = httpx.Client(transport=MockTransport())
+ response = client.get(url)
assert response.status_code == 200
assert response.json() == {
"accept-encoding": "gzip, deflate, br",
"connection": "keep-alive",
"host": "example.org:123",
- "user-agent": f"python-httpx/{__version__}",
+ "user-agent": f"python-httpx/{httpx.__version__}",
"authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
}
}
def test_request_auto_headers():
- request = Request("GET", "https://www.example.org/")
+ request = httpx.Request("GET", "https://www.example.org/")
assert "host" in request.headers
-from httpx import URL, AsyncClient, Cookies, Headers, Timeout
+import httpx
def test_client_base_url():
- client = AsyncClient()
+ client = httpx.Client()
client.base_url = "https://www.example.org/" # type: ignore
- assert isinstance(client.base_url, URL)
- assert client.base_url == URL("https://www.example.org/")
+ assert isinstance(client.base_url, httpx.URL)
+ assert client.base_url == httpx.URL("https://www.example.org/")
def test_client_base_url_without_trailing_slash():
- client = AsyncClient()
+ client = httpx.Client()
client.base_url = "https://www.example.org/path" # type: ignore
- assert isinstance(client.base_url, URL)
- assert client.base_url == URL("https://www.example.org/path/")
+ assert isinstance(client.base_url, httpx.URL)
+ assert client.base_url == httpx.URL("https://www.example.org/path/")
def test_client_base_url_with_trailing_slash():
- client = AsyncClient()
+ client = httpx.Client()
client.base_url = "https://www.example.org/path/" # type: ignore
- assert isinstance(client.base_url, URL)
- assert client.base_url == URL("https://www.example.org/path/")
+ assert isinstance(client.base_url, httpx.URL)
+ assert client.base_url == httpx.URL("https://www.example.org/path/")
def test_client_headers():
- client = AsyncClient()
+ client = httpx.Client()
client.headers = {"a": "b"} # type: ignore
- assert isinstance(client.headers, Headers)
+ assert isinstance(client.headers, httpx.Headers)
assert client.headers["A"] == "b"
def test_client_cookies():
- client = AsyncClient()
+ client = httpx.Client()
client.cookies = {"a": "b"} # type: ignore
- assert isinstance(client.cookies, Cookies)
+ assert isinstance(client.cookies, httpx.Cookies)
mycookies = list(client.cookies.jar)
assert len(mycookies) == 1
assert mycookies[0].name == "a" and mycookies[0].value == "b"
def test_client_timeout():
expected_timeout = 12.0
- client = AsyncClient()
+ client = httpx.Client()
client.timeout = expected_timeout # type: ignore
- assert isinstance(client.timeout, Timeout)
+ assert isinstance(client.timeout, httpx.Timeout)
assert client.timeout.connect == expected_timeout
assert client.timeout.read == expected_timeout
assert client.timeout.write == expected_timeout
],
)
def test_proxies_parameter(proxies, expected_proxies):
- client = httpx.AsyncClient(proxies=proxies)
+ client = httpx.Client(proxies=proxies)
for proxy_key, url in expected_proxies:
pattern = URLPattern(proxy_key)
assert pattern in client._proxies
proxy = client._proxies[pattern]
- assert isinstance(proxy, httpcore.AsyncHTTPProxy)
+ assert isinstance(proxy, httpcore.SyncHTTPProxy)
assert proxy.proxy_origin == url_to_origin(url)
assert len(expected_proxies) == len(client._proxies)
],
)
def test_transport_for_request(url, proxies, expected):
- client = httpx.AsyncClient(proxies=proxies)
+ client = httpx.Client(proxies=proxies)
transport = client._transport_for_url(httpx.URL(url))
if expected is None:
assert transport is client._transport
else:
- assert isinstance(transport, httpcore.AsyncHTTPProxy)
+ assert isinstance(transport, httpcore.SyncHTTPProxy)
assert transport.proxy_origin == url_to_origin(expected)
@pytest.mark.asyncio
async def test_async_proxy_close():
- client = httpx.AsyncClient(proxies={"all://": PROXY_URL})
- await client.aclose()
+ try:
+ client = httpx.AsyncClient(proxies={"all://": PROXY_URL})
+ finally:
+ await client.aclose()
def test_sync_proxy_close():
- client = httpx.Client(proxies={"all://": PROXY_URL})
- client.close()
+ try:
+ client = httpx.Client(proxies={"all://": PROXY_URL})
+ finally:
+ client.close()
def test_unsupported_proxy_scheme():
with pytest.raises(ValueError):
- httpx.AsyncClient(proxies="ftp://127.0.0.1")
+ httpx.Client(proxies="ftp://127.0.0.1")
@pytest.mark.parametrize(
)
def test_for_deprecated_proxy_params(proxies, expected_scheme):
with pytest.deprecated_call() as block:
- httpx.AsyncClient(proxies=proxies)
+ httpx.Client(proxies=proxies)
warning_message = str(block.pop(DeprecationWarning))
import typing
import httpcore
-import pytest
-from httpx import URL, AsyncClient, QueryParams
+import httpx
from httpx._content_streams import ContentStream, JSONStream
-class MockTransport(httpcore.AsyncHTTPTransport):
- async def request(
+class MockTransport(httpcore.SyncHTTPTransport):
+ def request(
self,
method: bytes,
url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes],
headers: typing.List[typing.Tuple[bytes, bytes]] = None,
- stream: httpcore.AsyncByteStream = None,
+ stream: httpcore.SyncByteStream = None,
timeout: typing.Mapping[str, typing.Optional[float]] = None,
) -> typing.Tuple[
bytes, int, bytes, typing.List[typing.Tuple[bytes, bytes]], ContentStream
def test_client_queryparams():
- client = AsyncClient(params={"a": "b"})
- assert isinstance(client.params, QueryParams)
+ client = httpx.Client(params={"a": "b"})
+ assert isinstance(client.params, httpx.QueryParams)
assert client.params["a"] == "b"
def test_client_queryparams_string():
- client = AsyncClient(params="a=b")
- assert isinstance(client.params, QueryParams)
+ client = httpx.Client(params="a=b")
+ assert isinstance(client.params, httpx.QueryParams)
assert client.params["a"] == "b"
- client = AsyncClient()
+ client = httpx.Client()
client.params = "a=b" # type: ignore
- assert isinstance(client.params, QueryParams)
+ assert isinstance(client.params, httpx.QueryParams)
assert client.params["a"] == "b"
-@pytest.mark.asyncio
-async def test_client_queryparams_echo():
+def test_client_queryparams_echo():
url = "http://example.org/echo_queryparams"
client_queryparams = "first=str"
request_queryparams = {"second": "dict"}
- client = AsyncClient(transport=MockTransport(), params=client_queryparams)
- response = await client.get(url, params=request_queryparams)
+ client = httpx.Client(transport=MockTransport(), params=client_queryparams)
+ response = client.get(url, params=request_queryparams)
assert response.status_code == 200
- assert response.url == URL(
+ assert response.url == httpx.URL(
"http://example.org/echo_queryparams?first=str&second=dict"
)
import httpcore
import pytest
-from httpx import (
- URL,
- AsyncClient,
- Client,
- NotRedirectResponse,
- RemoteProtocolError,
- RequestBodyUnavailable,
- TooManyRedirects,
- UnsupportedProtocol,
- codes,
-)
-from httpx._content_streams import AsyncIteratorStream, ByteStream, ContentStream
+import httpx
+from httpx._content_streams import ByteStream, ContentStream, IteratorStream
def get_header_value(headers, key, default=None):
path, _, query = path.partition(b"?")
if path == b"/no_redirect":
- return b"HTTP/1.1", codes.OK, b"OK", [], ByteStream(b"")
+ return b"HTTP/1.1", httpx.codes.OK, b"OK", [], ByteStream(b"")
elif path == b"/redirect_301":
- async def body():
+ def body():
yield b"<a href='https://example.org/'>here</a>"
- status_code = codes.MOVED_PERMANENTLY
+ status_code = httpx.codes.MOVED_PERMANENTLY
headers = [(b"location", b"https://example.org/")]
- stream = AsyncIteratorStream(aiterator=body())
+ stream = IteratorStream(iterator=body())
return b"HTTP/1.1", status_code, b"Moved Permanently", headers, stream
elif path == b"/redirect_302":
- status_code = codes.FOUND
+ status_code = httpx.codes.FOUND
headers = [(b"location", b"https://example.org/")]
return b"HTTP/1.1", status_code, b"Found", headers, ByteStream(b"")
elif path == b"/redirect_303":
- status_code = codes.SEE_OTHER
+ status_code = httpx.codes.SEE_OTHER
headers = [(b"location", b"https://example.org/")]
return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(b"")
elif path == b"/relative_redirect":
- status_code = codes.SEE_OTHER
+ status_code = httpx.codes.SEE_OTHER
headers = [(b"location", b"/")]
return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(b"")
elif path == b"/malformed_redirect":
- status_code = codes.SEE_OTHER
+ status_code = httpx.codes.SEE_OTHER
headers = [(b"location", b"https://:443/")]
return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(b"")
elif path == b"/invalid_redirect":
- status_code = codes.SEE_OTHER
+ status_code = httpx.codes.SEE_OTHER
headers = [(b"location", "https://😇/".encode("utf-8"))]
return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(b"")
elif path == b"/no_scheme_redirect":
- status_code = codes.SEE_OTHER
+ status_code = httpx.codes.SEE_OTHER
headers = [(b"location", b"//example.org/")]
return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(b"")
params = parse_qs(query.decode("ascii"))
count = int(params.get("count", "0")[0])
redirect_count = count - 1
- code = codes.SEE_OTHER if count else codes.OK
+ code = httpx.codes.SEE_OTHER if count else httpx.codes.OK
phrase = b"See Other" if count else b"OK"
location = b"/multiple_redirects"
if redirect_count:
return b"HTTP/1.1", code, phrase, headers, ByteStream(b"")
if path == b"/redirect_loop":
- code = codes.SEE_OTHER
+ code = httpx.codes.SEE_OTHER
headers = [(b"location", b"/redirect_loop")]
return b"HTTP/1.1", code, b"See Other", headers, ByteStream(b"")
elif path == b"/cross_domain":
- code = codes.SEE_OTHER
+ code = httpx.codes.SEE_OTHER
headers = [(b"location", b"https://example.org/cross_domain_target")]
return b"HTTP/1.1", code, b"See Other", headers, ByteStream(b"")
return b"HTTP/1.1", 200, b"OK", [], stream
elif path == b"/redirect_body":
- code = codes.PERMANENT_REDIRECT
+ code = httpx.codes.PERMANENT_REDIRECT
headers = [(b"location", b"/redirect_body_target")]
return b"HTTP/1.1", code, b"Permanent Redirect", headers, ByteStream(b"")
elif path == b"/redirect_no_body":
- code = codes.SEE_OTHER
+ code = httpx.codes.SEE_OTHER
headers = [(b"location", b"/redirect_body_target")]
return b"HTTP/1.1", code, b"See Other", headers, ByteStream(b"")
headers = [(b"location", b"https://www.example.org/cross_subdomain")]
return (
b"HTTP/1.1",
- codes.PERMANENT_REDIRECT,
+ httpx.codes.PERMANENT_REDIRECT,
b"Permanent Redirect",
headers,
ByteStream(b""),
return b"HTTP/1.1", 200, b"OK", [], ByteStream(b"Hello, world!")
elif path == b"/redirect_custom_scheme":
- status_code = codes.MOVED_PERMANENTLY
+ status_code = httpx.codes.MOVED_PERMANENTLY
headers = [(b"location", b"market://details?id=42")]
return (
b"HTTP/1.1",
return self._request(*args, **kwargs)
-@pytest.mark.usefixtures("async_environment")
-async def test_no_redirect():
- client = AsyncClient(transport=AsyncMockTransport())
+def test_no_redirect():
+ client = httpx.Client(transport=SyncMockTransport())
url = "https://example.com/no_redirect"
- response = await client.get(url)
+ response = client.get(url)
assert response.status_code == 200
- with pytest.raises(NotRedirectResponse):
- await response.anext()
+ with pytest.raises(httpx.NotRedirectResponse):
+ response.next()
-@pytest.mark.usefixtures("async_environment")
-async def test_redirect_301():
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.post("https://example.org/redirect_301")
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org/")
+def test_redirect_301():
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.post("https://example.org/redirect_301")
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org/")
assert len(response.history) == 1
-@pytest.mark.usefixtures("async_environment")
-async def test_redirect_302():
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.post("https://example.org/redirect_302")
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org/")
+def test_redirect_302():
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.post("https://example.org/redirect_302")
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org/")
assert len(response.history) == 1
-@pytest.mark.usefixtures("async_environment")
-async def test_redirect_303():
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.get("https://example.org/redirect_303")
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org/")
+def test_redirect_303():
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.get("https://example.org/redirect_303")
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org/")
assert len(response.history) == 1
-@pytest.mark.usefixtures("async_environment")
-async def test_disallow_redirects():
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.post(
- "https://example.org/redirect_303", allow_redirects=False
- )
- assert response.status_code == codes.SEE_OTHER
- assert response.url == URL("https://example.org/redirect_303")
+def test_disallow_redirects():
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.post("https://example.org/redirect_303", allow_redirects=False)
+ assert response.status_code == httpx.codes.SEE_OTHER
+ assert response.url == httpx.URL("https://example.org/redirect_303")
assert response.is_redirect is True
assert len(response.history) == 0
- response = await response.anext()
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org/")
+ response = response.next()
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org/")
assert response.is_redirect is False
assert len(response.history) == 1
-@pytest.mark.asyncio
-async def test_head_redirect():
+def test_head_redirect():
"""
Contrary to Requests, redirects remain enabled by default for HEAD requests.
"""
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.head("https://example.org/redirect_302")
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org/")
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.head("https://example.org/redirect_302")
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org/")
assert response.request.method == "HEAD"
assert len(response.history) == 1
assert response.text == ""
-@pytest.mark.usefixtures("async_environment")
-async def test_relative_redirect():
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.get("https://example.org/relative_redirect")
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org/")
+def test_relative_redirect():
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.get("https://example.org/relative_redirect")
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org/")
assert len(response.history) == 1
-@pytest.mark.usefixtures("async_environment")
-async def test_malformed_redirect():
+def test_malformed_redirect():
# https://github.com/encode/httpx/issues/771
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.get("http://example.org/malformed_redirect")
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org:443/")
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.get("http://example.org/malformed_redirect")
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org:443/")
assert len(response.history) == 1
-@pytest.mark.usefixtures("async_environment")
-async def test_invalid_redirect():
- client = AsyncClient(transport=AsyncMockTransport())
- with pytest.raises(RemoteProtocolError):
- await client.get("http://example.org/invalid_redirect")
+def test_invalid_redirect():
+ client = httpx.Client(transport=SyncMockTransport())
+ with pytest.raises(httpx.RemoteProtocolError):
+ client.get("http://example.org/invalid_redirect")
-@pytest.mark.usefixtures("async_environment")
-async def test_no_scheme_redirect():
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.get("https://example.org/no_scheme_redirect")
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org/")
+def test_no_scheme_redirect():
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.get("https://example.org/no_scheme_redirect")
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org/")
assert len(response.history) == 1
-@pytest.mark.usefixtures("async_environment")
-async def test_fragment_redirect():
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.get("https://example.org/relative_redirect#fragment")
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org/#fragment")
+def test_fragment_redirect():
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.get("https://example.org/relative_redirect#fragment")
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org/#fragment")
assert len(response.history) == 1
-@pytest.mark.usefixtures("async_environment")
-async def test_multiple_redirects():
- client = AsyncClient(transport=AsyncMockTransport())
- response = await client.get("https://example.org/multiple_redirects?count=20")
- assert response.status_code == codes.OK
- assert response.url == URL("https://example.org/multiple_redirects")
+def test_multiple_redirects():
+ client = httpx.Client(transport=SyncMockTransport())
+ response = client.get("https://example.org/multiple_redirects?count=20")
+ assert response.status_code == httpx.codes.OK
+ assert response.url == httpx.URL("https://example.org/multiple_redirects")
assert len(response.history) == 20
- assert response.history[0].url == URL(
+ assert response.history[0].url == httpx.URL(
"https://example.org/multiple_redirects?count=20"
)
- assert response.history[1].url == URL(
+ assert response.history[1].url == httpx.URL(
"https://example.org/multiple_redirects?count=19"
)
assert len(response.history[0].history) == 0
@pytest.mark.usefixtures("async_environment")
async def test_async_too_many_redirects():
- client = AsyncClient(transport=AsyncMockTransport())
- with pytest.raises(TooManyRedirects):
- await client.get("https://example.org/multiple_redirects?count=21")
+ async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+ with pytest.raises(httpx.TooManyRedirects):
+ await client.get("https://example.org/multiple_redirects?count=21")
@pytest.mark.usefixtures("async_environment")
async def test_async_too_many_redirects_calling_next():
- client = AsyncClient(transport=AsyncMockTransport())
- url = "https://example.org/multiple_redirects?count=21"
- response = await client.get(url, allow_redirects=False)
- with pytest.raises(TooManyRedirects):
- while response.is_redirect:
- response = await response.anext()
+ async with httpx.AsyncClient(transport=AsyncMockTransport()) as client:
+ url = "https://example.org/multiple_redirects?count=21"
+ response = await client.get(url, allow_redirects=False)
+ with pytest.raises(httpx.TooManyRedirects):
+ while response.is_redirect:
+ response = await response.anext()
def test_sync_too_many_redirects():
- client = Client(transport=SyncMockTransport())
- with pytest.raises(TooManyRedirects):
+ client = httpx.Client(transport=SyncMockTransport())
+ with pytest.raises(httpx.TooManyRedirects):
client.get("https://example.org/multiple_redirects?count=21")
def test_sync_too_many_redirects_calling_next():
- client = Client(transport=SyncMockTransport())
+ client = httpx.Client(transport=SyncMockTransport())
url = "https://example.org/multiple_redirects?count=21"
response = client.get(url, allow_redirects=False)
- with pytest.raises(TooManyRedirects):
+ with pytest.raises(httpx.TooManyRedirects):
while response.is_redirect:
response = response.next()
-@pytest.mark.usefixtures("async_environment")
-async def test_redirect_loop():
- client = AsyncClient(transport=AsyncMockTransport())
- with pytest.raises(TooManyRedirects):
- await client.get("https://example.org/redirect_loop")
+def test_redirect_loop():
+ client = httpx.Client(transport=SyncMockTransport())
+ with pytest.raises(httpx.TooManyRedirects):
+ client.get("https://example.org/redirect_loop")
-@pytest.mark.usefixtures("async_environment")
-async def test_cross_domain_redirect():
- client = AsyncClient(transport=AsyncMockTransport())
+def test_cross_domain_redirect():
+ client = httpx.Client(transport=SyncMockTransport())
url = "https://example.com/cross_domain"
headers = {"Authorization": "abc"}
- response = await client.get(url, headers=headers)
- assert response.url == URL("https://example.org/cross_domain_target")
+ response = client.get(url, headers=headers)
+ assert response.url == httpx.URL("https://example.org/cross_domain_target")
assert "authorization" not in response.json()["headers"]
-@pytest.mark.usefixtures("async_environment")
-async def test_same_domain_redirect():
- client = AsyncClient(transport=AsyncMockTransport())
+def test_same_domain_redirect():
+ client = httpx.Client(transport=SyncMockTransport())
url = "https://example.org/cross_domain"
headers = {"Authorization": "abc"}
- response = await client.get(url, headers=headers)
- assert response.url == URL("https://example.org/cross_domain_target")
+ response = client.get(url, headers=headers)
+ assert response.url == httpx.URL("https://example.org/cross_domain_target")
assert response.json()["headers"]["authorization"] == "abc"
-@pytest.mark.usefixtures("async_environment")
-async def test_body_redirect():
+def test_body_redirect():
"""
A 308 redirect should preserve the request body.
"""
- client = AsyncClient(transport=AsyncMockTransport())
+ client = httpx.Client(transport=SyncMockTransport())
url = "https://example.org/redirect_body"
data = b"Example request body"
- response = await client.post(url, data=data)
- assert response.url == URL("https://example.org/redirect_body_target")
+ response = client.post(url, data=data)
+ assert response.url == httpx.URL("https://example.org/redirect_body_target")
assert response.json()["body"] == "Example request body"
assert "content-length" in response.json()["headers"]
-@pytest.mark.usefixtures("async_environment")
-async def test_no_body_redirect():
+def test_no_body_redirect():
"""
A 303 redirect should remove the request body.
"""
- client = AsyncClient(transport=AsyncMockTransport())
+ client = httpx.Client(transport=SyncMockTransport())
url = "https://example.org/redirect_no_body"
data = b"Example request body"
- response = await client.post(url, data=data)
- assert response.url == URL("https://example.org/redirect_body_target")
+ response = client.post(url, data=data)
+ assert response.url == httpx.URL("https://example.org/redirect_body_target")
assert response.json()["body"] == ""
assert "content-length" not in response.json()["headers"]
-@pytest.mark.usefixtures("async_environment")
-async def test_can_stream_if_no_redirect():
- client = AsyncClient(transport=AsyncMockTransport())
+def test_can_stream_if_no_redirect():
+ client = httpx.Client(transport=SyncMockTransport())
url = "https://example.org/redirect_301"
- async with client.stream("GET", url, allow_redirects=False) as response:
+ with client.stream("GET", url, allow_redirects=False) as response:
assert not response.is_closed
- assert response.status_code == codes.MOVED_PERMANENTLY
+ assert response.status_code == httpx.codes.MOVED_PERMANENTLY
assert response.headers["location"] == "https://example.org/"
-@pytest.mark.usefixtures("async_environment")
-async def test_cannot_redirect_streaming_body():
- client = AsyncClient(transport=AsyncMockTransport())
+def test_cannot_redirect_streaming_body():
+ client = httpx.Client(transport=SyncMockTransport())
url = "https://example.org/redirect_body"
- async def streaming_body():
+ def streaming_body():
yield b"Example request body" # pragma: nocover
- with pytest.raises(RequestBodyUnavailable):
- await client.post(url, data=streaming_body())
+ with pytest.raises(httpx.RequestBodyUnavailable):
+ client.post(url, data=streaming_body())
-@pytest.mark.usefixtures("async_environment")
-async def test_cross_subdomain_redirect():
- client = AsyncClient(transport=AsyncMockTransport())
+def test_cross_subdomain_redirect():
+ client = httpx.Client(transport=SyncMockTransport())
url = "https://example.com/cross_subdomain"
- response = await client.get(url)
- assert response.url == URL("https://www.example.org/cross_subdomain")
+ response = client.get(url)
+ assert response.url == httpx.URL("https://www.example.org/cross_subdomain")
-class MockCookieTransport(httpcore.AsyncHTTPTransport):
- async def request(
+class MockCookieTransport(httpcore.SyncHTTPTransport):
+ def request(
self,
method: bytes,
url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes],
headers: typing.List[typing.Tuple[bytes, bytes]] = None,
- stream: httpcore.AsyncByteStream = None,
+ stream: httpcore.SyncByteStream = None,
timeout: typing.Mapping[str, typing.Optional[float]] = None,
) -> typing.Tuple[
bytes, int, bytes, typing.List[typing.Tuple[bytes, bytes]], ContentStream
return b"HTTP/1.1", 200, b"OK", [], ByteStream(content)
elif path == b"/login":
- status_code = codes.SEE_OTHER
+ status_code = httpx.codes.SEE_OTHER
headers = [
(b"location", b"/"),
(
else:
assert path == b"/logout"
- status_code = codes.SEE_OTHER
+ status_code = httpx.codes.SEE_OTHER
headers = [
(b"location", b"/"),
(
return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(b"")
-@pytest.mark.usefixtures("async_environment")
-async def test_redirect_cookie_behavior():
- client = AsyncClient(transport=MockCookieTransport())
+def test_redirect_cookie_behavior():
+ client = httpx.Client(transport=MockCookieTransport())
# The client is not logged in.
- response = await client.get("https://example.com/")
+ response = client.get("https://example.com/")
assert response.url == "https://example.com/"
assert response.text == "Not logged in"
# Login redirects to the homepage, setting a session cookie.
- response = await client.post("https://example.com/login")
+ response = client.post("https://example.com/login")
assert response.url == "https://example.com/"
assert response.text == "Logged in"
# The client is logged in.
- response = await client.get("https://example.com/")
+ response = client.get("https://example.com/")
assert response.url == "https://example.com/"
assert response.text == "Logged in"
# Logout redirects to the homepage, expiring the session cookie.
- response = await client.post("https://example.com/logout")
+ response = client.post("https://example.com/logout")
assert response.url == "https://example.com/"
assert response.text == "Not logged in"
# The client is not logged in.
- response = await client.get("https://example.com/")
+ response = client.get("https://example.com/")
assert response.url == "https://example.com/"
assert response.text == "Not logged in"
-@pytest.mark.usefixtures("async_environment")
-async def test_redirect_custom_scheme():
- client = AsyncClient(transport=AsyncMockTransport())
- with pytest.raises(UnsupportedProtocol) as e:
- await client.post("https://example.org/redirect_custom_scheme")
+def test_redirect_custom_scheme():
+ client = httpx.Client(transport=SyncMockTransport())
+ with pytest.raises(httpx.UnsupportedProtocol) as e:
+ client.post("https://example.org/redirect_custom_scheme")
assert str(e.value) == "Scheme b'market' not supported."
import pytest
-from httpx import QueryParams
+import httpx
@pytest.mark.parametrize(
],
)
def test_queryparams(source):
- q = QueryParams(source)
+ q = httpx.QueryParams(source)
assert "a" in q
assert "A" not in q
assert "c" not in q
assert dict(q) == {"a": "456", "b": "789"}
assert str(q) == "a=123&a=456&b=789"
assert repr(q) == "QueryParams('a=123&a=456&b=789')"
- assert QueryParams({"a": "123", "b": "456"}) == QueryParams(
+ assert httpx.QueryParams({"a": "123", "b": "456"}) == httpx.QueryParams(
[("a", "123"), ("b", "456")]
)
- assert QueryParams({"a": "123", "b": "456"}) == QueryParams("a=123&b=456")
- assert QueryParams({"a": "123", "b": "456"}) == QueryParams(
+ assert httpx.QueryParams({"a": "123", "b": "456"}) == httpx.QueryParams(
+ "a=123&b=456"
+ )
+ assert httpx.QueryParams({"a": "123", "b": "456"}) == httpx.QueryParams(
{"b": "456", "a": "123"}
)
- assert QueryParams() == QueryParams({})
- assert QueryParams([("a", "123"), ("a", "456")]) == QueryParams("a=123&a=456")
- assert QueryParams({"a": "123", "b": "456"}) != "invalid"
+ assert httpx.QueryParams() == httpx.QueryParams({})
+ assert httpx.QueryParams([("a", "123"), ("a", "456")]) == httpx.QueryParams(
+ "a=123&a=456"
+ )
+ assert httpx.QueryParams({"a": "123", "b": "456"}) != "invalid"
- q = QueryParams([("a", "123"), ("a", "456")])
- assert QueryParams(q) == q
+ q = httpx.QueryParams([("a", "123"), ("a", "456")])
+ assert httpx.QueryParams(q) == q
def test_queryparam_types():
- q = QueryParams(None)
+ q = httpx.QueryParams(None)
assert str(q) == ""
- q = QueryParams({"a": True})
+ q = httpx.QueryParams({"a": True})
assert str(q) == "a=true"
- q = QueryParams({"a": False})
+ q = httpx.QueryParams({"a": False})
assert str(q) == "a=false"
- q = QueryParams({"a": ""})
+ q = httpx.QueryParams({"a": ""})
assert str(q) == "a="
- q = QueryParams({"a": None})
+ q = httpx.QueryParams({"a": None})
assert str(q) == "a="
- q = QueryParams({"a": 1.23})
+ q = httpx.QueryParams({"a": 1.23})
assert str(q) == "a=1.23"
- q = QueryParams({"a": 123})
+ q = httpx.QueryParams({"a": 123})
assert str(q) == "a=123"
- q = QueryParams({"a": [1, 2]})
+ q = httpx.QueryParams({"a": [1, 2]})
assert str(q) == "a=1&a=2"
def test_queryparam_setters():
- q = QueryParams({"a": 1})
+ q = httpx.QueryParams({"a": 1})
q.update([])
assert str(q) == "a=1"
- q = QueryParams([("a", 1), ("a", 2)])
+ q = httpx.QueryParams([("a", 1), ("a", 2)])
q["a"] = "3"
assert str(q) == "a=3"
- q = QueryParams([("a", 1), ("b", 1)])
- u = QueryParams([("b", 2), ("b", 3)])
+ q = httpx.QueryParams([("a", 1), ("b", 1)])
+ u = httpx.QueryParams([("b", 2), ("b", 3)])
q.update(u)
assert str(q) == "a=1&b=2&b=3"
yield b"world!"
-@pytest.mark.asyncio
-async def test_response():
+def test_response():
response = httpx.Response(200, content=b"Hello, world!", request=REQUEST)
assert response.status_code == 200
import pytest
-from httpx import URL, InvalidURL
+import httpx
@pytest.mark.parametrize(
],
)
def test_idna_url(given, idna, host, scheme, port):
- url = URL(given)
- assert url == URL(idna)
+ url = httpx.URL(given)
+ assert url == httpx.URL(idna)
assert url.host == host
assert url.scheme == scheme
assert url.port == port
def test_url():
- url = URL("https://example.org:123/path/to/somewhere?abc=123#anchor")
+ url = httpx.URL("https://example.org:123/path/to/somewhere?abc=123#anchor")
assert url.scheme == "https"
assert url.host == "example.org"
assert url.port == 123
)
new = url.copy_with(scheme="http", port=None)
- assert new == URL("http://example.org/path/to/somewhere?abc=123#anchor")
+ assert new == httpx.URL("http://example.org/path/to/somewhere?abc=123#anchor")
assert new.scheme == "http"
def test_url_eq_str():
- url = URL("https://example.org:123/path/to/somewhere?abc=123#anchor")
+ url = httpx.URL("https://example.org:123/path/to/somewhere?abc=123#anchor")
assert url == "https://example.org:123/path/to/somewhere?abc=123#anchor"
assert str(url) == url
def test_url_params():
- url = URL("https://example.org:123/path/to/somewhere", params={"a": "123"})
+ url = httpx.URL("https://example.org:123/path/to/somewhere", 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", params={"a": "123"})
+ url = httpx.URL(
+ "https://example.org:123/path/to/somewhere?b=456", params={"a": "123"}
+ )
assert str(url) == "https://example.org:123/path/to/somewhere?b=456&a=123"
"""
Some basic URL joining tests.
"""
- url = URL("https://example.org:123/path/to/somewhere")
+ url = httpx.URL("https://example.org:123/path/to/somewhere")
assert url.join("/somewhere-else") == "https://example.org:123/somewhere-else"
assert (
url.join("somewhere-else") == "https://example.org:123/path/to/somewhere-else"
https://tools.ietf.org/html/rfc3986#section-5.4
"""
- url = URL("http://example.com/b/c/d;p?q")
+ url = httpx.URL("http://example.com/b/c/d;p?q")
assert url.join("g") == "http://example.com/b/c/g"
assert url.join("./g") == "http://example.com/b/c/g"
def test_url_set():
urls = (
- URL("http://example.org:123/path/to/somewhere"),
- URL("http://example.org:123/path/to/somewhere/else"),
+ httpx.URL("http://example.org:123/path/to/somewhere"),
+ httpx.URL("http://example.org:123/path/to/somewhere/else"),
)
url_set = set(urls)
"port": 444,
"host": "example.net",
}
- url = URL("https://example.org")
+ url = httpx.URL("https://example.org")
new = url.copy_with(**copy_with_kwargs)
for k, v in copy_with_kwargs.items():
assert getattr(new, k) == v
"username": "tom@example.org",
"password": "abc123@ %",
}
- url = URL("https://example.org")
+ url = httpx.URL("https://example.org")
new = url.copy_with(**copy_with_kwargs)
assert str(new) == "https://tom%40example.org:abc123%40%20%25@example.org"
assert new.username == "tom@example.org"
def test_url_invalid():
- with pytest.raises(InvalidURL):
- URL("https://😇/")
+ with pytest.raises(httpx.InvalidURL):
+ httpx.URL("https://😇/")