diff --git a/httpx/_types.py b/httpx/_types.py index f3c1f6ef4e..6b610e1408 100644 --- a/httpx/_types.py +++ b/httpx/_types.py @@ -16,6 +16,7 @@ Iterator, List, Mapping, + NamedTuple, Optional, Sequence, Tuple, @@ -31,6 +32,16 @@ PrimitiveData = Optional[Union[str, int, float, bool]] +RawURL = NamedTuple( + "RawURL", + [ + ("raw_scheme", bytes), + ("raw_host", bytes), + ("port", Optional[int]), + ("raw_path", bytes), + ], +) + URLTypes = Union["URL", str] QueryParamTypes = Union[ diff --git a/httpx/_urls.py b/httpx/_urls.py index ab39c2ec01..f26b2eb2dc 100644 --- a/httpx/_urls.py +++ b/httpx/_urls.py @@ -6,7 +6,7 @@ import rfc3986.exceptions from ._exceptions import InvalidURL -from ._types import PrimitiveData, QueryParamTypes, URLTypes +from ._types import PrimitiveData, QueryParamTypes, RawURL, URLTypes from ._utils import primitive_value_to_str @@ -311,6 +311,21 @@ def fragment(self) -> str: """ return unquote(self._uri_reference.fragment or "") + @property + def raw(self) -> RawURL: + """ + Provides the (scheme, host, port, target) for the outgoing request. + + In older versions of `httpx` this was used in the low-level transport API. + We no longer use `RawURL`, and this property will be deprecated in a future release. + """ + return RawURL( + self.raw_scheme, + self.raw_host, + self.port, + self.raw_path, + ) + @property def is_absolute_url(self) -> bool: """ diff --git a/tests/models/test_url.py b/tests/models/test_url.py index 321cffb3c9..959681be9f 100644 --- a/tests/models/test_url.py +++ b/tests/models/test_url.py @@ -424,3 +424,13 @@ def test_ipv6_url_from_raw_url(host): assert url.host == "::ffff:192.168.0.1" assert url.netloc == b"[::ffff:192.168.0.1]" assert str(url) == "https://[::ffff:192.168.0.1]/" + + +def test_url_raw_compatibility(): + url = httpx.URL("https://www.example.com/path") + scheme, host, port, raw_path = url.raw + + assert scheme == b"https" + assert host == b"www.example.com" + assert port is None + assert raw_path == b"/path"