Releases: encode/httpx
Version 0.20.0
0.20.0 (13th October, 2021)
The 0.20.0 release adds an integrated command-line client, and also includes some design changes. The most notable of these is that redirect responses are no longer automatically followed, unless specifically requested.
This design decision prioritises a more explicit approach to redirects, in order to avoid code that unintentionally issues multiple requests as a result of misconfigured URLs.
For example, previously a client configured to send requests to http://api.github.com/ would end up sending every API request twice, as each request would be redirected to https://api.github.com/.
If you do want auto-redirect behaviour, you can enable this either by configuring the client instance with Client(follow_redirects=True), or on a per-request basis, with .get(..., follow_redirects=True).
This change is a classic trade-off between convenience and precision, with no "right" answer. See discussion #1785 for more context.
The other major design change is an update to the Transport API, which is the low-level interface against which requests are sent. Previously this interface used only primitive datastructures, like so...
(status_code, headers, stream, extensions) = transport.handle_request(method, url, headers, stream, extensions)
try
...
finally:
stream.close()Now the interface is much simpler...
response = transport.handle_request(request)
try
...
finally:
response.close()Changed
- The
allow_redirectsflag is nowfollow_redirectsand defaults toFalse. - The
raise_for_status()method will now raise an exception for any responses except those with 2xx status codes. Previously only 4xx and 5xx status codes would result in an exception. - The low-level transport API changes to the much simpler
response = transport.handle_request(request). - The
client.send()method no longer accepts atimeout=...argument, but theclient.build_request()does. This required by the signature change of the Transport API. The request timeout configuration is now stored on the request instance, asrequest.extensions['timeout'].
Added
- Added the
httpxcommand-line client. - Response instances now include
.is_informational,.is_success,.is_redirect,.is_client_error, and.is_server_errorproperties for checking 1xx, 2xx, 3xx, 4xx, and 5xx response types. Note that the behaviour of.is_redirectis slightly different in that it now returns True for all 3xx responses, in order to allow for a consistent set of properties onto the different HTTP status code types. Theresponse.has_redirect_locationlocation may be used to determine responses with properly formed URL redirects.
Fixed
response.iter_bytes()no longer raises a ValueError when called on a response with no content. (Pull #1827)- The
'wsgi.error'configuration now defaults tosys.stderr, and is corrected to be aTextIOinterface, not aBytesIOinterface. Additionally, the WSGITransport now accepts awsgi_errorconfguration. (Pull #1828) - Follow the WSGI spec by properly closing the iterable returned by the application. (Pull #1830)
Version 1.0.0.beta0
1.0.0.beta0 (14th September 2021)
The 1.0 pre-release adds an integrated command-line client, and also includes some design changes. The most notable of these is that redirect responses are no longer automatically followed, unless specifically requested.
This design decision prioritises a more explicit approach to redirects, in order to avoid code that unintentionally issues multiple requests as a result of misconfigured URLs.
For example, previously a client configured to send requests to http://api.github.com/ would end up sending every API request twice, as each request would be redirected to https://api.github.com/.
If you do want auto-redirect behaviour, you can enable this either by configuring the client instance with Client(follow_redirects=True), or on a per-request basis, with .get(..., follow_redirects=True).
This change is a classic trade-off between convenience and precision, with no "right" answer. See discussion #1785 for more context.
The other major design change is an update to the Transport API, which is the low-level interface against which requests are sent. Previously this interface used only primitive datastructures, like so...
(status_code, headers, stream, extensions) = transport.handle_request(method, url, headers, stream, extensions)
try
...
finally:
stream.close()Now the interface is much simpler...
response = transport.handle_request(request)
try
...
finally:
response.close()Changed
- The
allow_redirectsflag is nowfollow_redirectsand defaults toFalse. - The
raise_for_status()method will now raise an exception for any responses
except those with 2xx status codes. Previously only 4xx and 5xx status codes
would result in an exception. - The low-level transport API changes to the much simpler
response = transport.handle_request(request). - The
client.send()method no longer accepts atimeout=...argument, but the
client.build_request()does. This required by the signature change of the
Transport API. The request timeout configuration is now stored on the request
instance, asrequest.extensions['timeout'].
Added
- Added the
httpxcommand-line client. - Response instances now include
.is_informational,.is_success,.is_redirect,.is_client_error, and.is_server_error
properties for checking 1xx, 2xx, 3xx, 4xx, and 5xx response types. Note that the behaviour of.is_redirectis slightly different in that it now returns True for all 3xx responses, in order to allow for a consistent set of properties onto the different HTTP status code types. Theresponse.has_redirect_locationlocation may be used to determine responses with properly formed URL redirects.
Fixed
response.iter_bytes()no longer raises a ValueError when called on a response with no content. (Pull #1827)- The
'wsgi.error'configuration now defaults tosys.stderr, and is corrected to be aTextIOinterface, not aBytesIOinterface. Additionally, the WSGITransport now accepts awsgi_errorconfiguration. (Pull #1828) - Follow the WSGI spec by properly closing the iterable returned by the application. (Pull #1830)
Version 0.19.0
0.19.0 (19th August, 2021)
Added
- Add support for
Client(allow_redirects=<bool>). (Pull #1790) - Add automatic character set detection, when no
charsetis included in the responseContent-Typeheader. (Pull #1791)
Changed
- Event hooks are now also called for any additional redirect or auth requests/responses. (Pull #1806)
- Strictly enforce that upload files must be opened in binary mode. (Pull #1736)
- Strictly enforce that client instances can only be opened and closed once, and cannot be re-opened. (Pull #1800)
- Drop
modeargument fromhttpx.Proxy(..., mode=...). (Pull #1795)
Version 0.18.2
0.18.2 (17th June, 2021)
Added
- Support for Python 3.10. (Pull #1687)
- Expose
httpx.USE_CLIENT_DEFAULT, used as the default toauthandtimeoutparameters in request methods. (Pull #1634) - Support HTTP/2 "prior knowledge", using
httpx.Client(http1=False, http2=True). (Pull #1624)
Fixed
Version 0.18.1
Version 0.18.0
0.18.0 (27th April, 2021)
The 0.18.x release series formalises our low-level Transport API, introducing the base classes httpx.BaseTransport and httpx.AsyncBaseTransport.
See the "Writing custom transports" documentation and the httpx.BaseTransport.handle_request() docstring for more complete details on implementing custom transports.
Pull request #1522 includes a checklist of differences from the previous httpcore transport API, for developers implementing custom transports.
The following API changes have been issuing deprecation warnings since 0.17.0 onwards, and are now fully deprecated...
- You should now use httpx.codes consistently instead of httpx.StatusCodes.
- Use limits=... instead of pool_limits=....
- Use proxies={"http://": ...} instead of proxies={"http": ...} for scheme-specific mounting.
Changed
- Transport instances now inherit from
httpx.BaseTransportorhttpx.AsyncBaseTransport,
and should implement either thehandle_requestmethod orhandle_async_requestmethod. (Pull #1522, #1550) - The
response.extproperty andResponse(ext=...)argument are now namedextensions. (Pull #1522) - The recommendation to not use
data=<bytes|str|bytes (a)iterator>in favour ofcontent=<bytes|str|bytes (a)iterator>has now been escalated to a deprecation warning. (Pull #1573) - Drop
Response(on_close=...)from API, since it was a bit of leaking implementation detail. (Pull #1572) - When using a client instance, cookies should always be set on the client, rather than on a per-request basis. We prefer enforcing a stricter API here because it provides clearer expectations around cookie persistence, particularly when redirects occur. (Pull #1574)
- The runtime exception
httpx.ResponseClosedis now namedhttpx.StreamClosed. (#1584) - The
httpx.QueryParamsmodel now presents an immutable interface. The is a discussion on the design and motivation here. Useclient.params = client.params.merge(...)instead ofclient.params.update(...). The basic query manipulation methods arequery.set(...),query.add(...), andquery.remove(). (#1600)
Added
- The
RequestandResponseclasses can now be serialized using pickle. (#1579) - Handle
data={"key": [None|int|float|bool]}cases. (Pull #1539) - Support
httpx.URL(**kwargs), for examplehttpx.URL(scheme="https", host="www.example.com", path="/'), orhttpx.URL("https://www.example.com/", username="tom@gmail.com", password="123 456"). (Pull #1601) - Support
url.copy_with(params=...). (Pull #1601) - Add
url.paramsparameter, returning an immutableQueryParamsinstance. (Pull #1601) - Support query manipulation methods on the URL class. These are
url.copy_set_param(),url.copy_add_param(),url.copy_remove_param(),url.copy_merge_params(). (Pull #1601) - The
httpx.URLclass now performs port normalization, so:80ports are stripped fromhttpURLs and:443ports are stripped fromhttpsURLs. (Pull #1603) - The
URL.hostproperty returns unicode strings for internationalized domain names. TheURL.raw_hostproperty returns byte strings with IDNA escaping applied. (Pull #1590)
Fixed
- Fix Content-Length for cases of
files=...where unicode string is used as the file content. (Pull #1537) - Fix some cases of merging relative URLs against
Client(base_url=...). (Pull #1532) - The
request.contentattribute is now always available except for streaming content, which requires an explicit.read(). (Pull #1583)
Version 0.17.1
Version 0.17.0
0.17.0
Added
- Add
httpx.MockTransport(), allowing to mock out a transport using pre-determined responses. (Pull #1401, Pull #1449) - Add
httpx.HTTPTransport()andhttpx.AsyncHTTPTransport()default transports. (Pull #1399) - Add mount API support, using
httpx.Client(mounts=...). (Pull #1362) - Add
chunk_sizeparameter toiter_raw(),iter_bytes(),iter_text(). (Pull #1277) - Add
keepalive_expiryparameter tohttpx.Limits()configuration. (Pull #1398) - Add repr to
httpx.Cookiesto display available cookies. (Pull #1411) - Add support for
params=<tuple>(previously onlyparams=<list>was supported). (Pull #1426)
Fixed
- Add missing
raw_pathto ASGI scope. (Pull #1357) - Tweak
create_ssl_contextdefaults to usetrust_env=True. (Pull #1447) - Properly URL-escape WSGI
PATH_INFO. (Pull #1391) - Properly set default ports in WSGI transport. (Pull #1469)
- Properly encode slashes when using
base_url. (Pull #1407) - Properly map exceptions in
request.aclose(). (Pull #1465)
Version 0.16.1
Version 0.16.0
0.16.0 (October 6th, 2020)
Changed
- Preserve HTTP header casing. (Pull #1338, encode/httpcore#216, python-hyper/h11#104)
- Drop
response.next()andresponse.anext()methods in favour ofresponse.next_requestattribute. (Pull #1339) - Closed clients now raise a runtime error if attempting to send a request. (Pull #1346)
Added
- Add Python 3.9 to officially supported versions.
- Type annotate
__enter__/__exit__/__aenter__/__aexit__in a way that supports subclasses ofClientandAsyncClient. (Pull #1336)