From 26d48e0634e6ee9cdc0533996db289ce4b430177 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 6 Dec 2024 15:35:41 +0000 Subject: [PATCH 01/10] Version 0.28.1 (#3445) --- CHANGELOG.md | 2 +- httpx/__version__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f1233ef..f4cd341b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## Dev +## 0.28.1 (6th December, 2024) * Fix SSL case where `verify=False` together with client side certificates. diff --git a/httpx/__version__.py b/httpx/__version__.py index 0a684ac3..801bfacf 100644 --- a/httpx/__version__.py +++ b/httpx/__version__.py @@ -1,3 +1,3 @@ __title__ = "httpx" __description__ = "A next generation HTTP client, for Python 3." -__version__ = "0.28.0" +__version__ = "0.28.1" From c7c13f18a5af4c64c649881b2fe8dbd72a519c32 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 23 Dec 2024 23:50:57 +0200 Subject: [PATCH 02/10] Add support for Python 3.13 (#3460) --- .github/workflows/test-suite.yml | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index ce3df5db..ae70a6b3 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: "actions/checkout@v4" diff --git a/pyproject.toml b/pyproject.toml index 9e671911..675d2ad4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Internet :: WWW/HTTP", ] dependencies = [ From 10b7295922741b91a15751029e6ad3e8e5efb9f3 Mon Sep 17 00:00:00 2001 From: Bazyli Cyran Date: Fri, 17 Jan 2025 11:56:46 +0100 Subject: [PATCH 03/10] docs: Use `with` to open files in multipart examples (#3478) --- docs/advanced/clients.md | 14 +++++++++----- docs/quickstart.md | 15 +++++++++------ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/advanced/clients.md b/docs/advanced/clients.md index a55fc596..90969cef 100644 --- a/docs/advanced/clients.md +++ b/docs/advanced/clients.md @@ -270,8 +270,9 @@ multipart file encoding is available by passing a dictionary with the name of the payloads as keys and either tuple of elements or a file-like object or a string as values. ```pycon ->>> files = {'upload-file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel')} ->>> r = httpx.post("https://httpbin.org/post", files=files) +>>> with open('report.xls', 'rb') as report_file: +... files = {'upload-file': ('report.xls', report_file, 'application/vnd.ms-excel')} +... r = httpx.post("https://httpbin.org/post", files=files) >>> print(r.text) { ... @@ -318,7 +319,10 @@ To do that, pass a list of `(field, )` items instead of a dictionary, allo For instance this request sends 2 files, `foo.png` and `bar.png` in one request on the `images` form field: ```pycon ->>> files = [('images', ('foo.png', open('foo.png', 'rb'), 'image/png')), - ('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))] ->>> r = httpx.post("https://httpbin.org/post", files=files) +>>> with open('foo.png', 'rb') as foo_file, open('bar.png', 'rb') as bar_file: +... files = [ +... ('images', ('foo.png', foo_file, 'image/png')), +... ('images', ('bar.png', bar_file, 'image/png')), +... ] +... r = httpx.post("https://httpbin.org/post", files=files) ``` diff --git a/docs/quickstart.md b/docs/quickstart.md index aa203a83..38da2fec 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -174,8 +174,9 @@ Form encoded data can also include multiple values from a given key. You can also upload files, using HTTP multipart encoding: ```pycon ->>> files = {'upload-file': open('report.xls', 'rb')} ->>> r = httpx.post("https://httpbin.org/post", files=files) +>>> with open('report.xls', 'rb') as report_file: +... files = {'upload-file': report_file} +... r = httpx.post("https://httpbin.org/post", files=files) >>> print(r.text) { ... @@ -190,8 +191,9 @@ You can also explicitly set the filename and content type, by using a tuple of items for the file value: ```pycon ->>> files = {'upload-file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel')} ->>> r = httpx.post("https://httpbin.org/post", files=files) +>>> with open('report.xls', 'rb') report_file: +... files = {'upload-file': ('report.xls', report_file, 'application/vnd.ms-excel')} +... r = httpx.post("https://httpbin.org/post", files=files) >>> print(r.text) { ... @@ -206,8 +208,9 @@ If you need to include non-file data fields in the multipart form, use the `data ```pycon >>> data = {'message': 'Hello, world!'} ->>> files = {'file': open('report.xls', 'rb')} ->>> r = httpx.post("https://httpbin.org/post", data=data, files=files) +>>> with open('report.xls', 'rb') as report_file: +... files = {'file': report_file} +... r = httpx.post("https://httpbin.org/post", data=data, files=files) >>> print(r.text) { ... From b395e6626b45dc2122c04c6e080fc7fb908cc9af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:25:05 +0000 Subject: [PATCH 04/10] Bump cryptography from 44.0.0 to 44.0.1 (#3499) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0d8ba2ef..caa094f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ twine==6.0.1 # Tests & Linting coverage[toml]==7.6.1 -cryptography==44.0.0 +cryptography==44.0.1 mypy==1.13.0 pytest==8.3.4 ruff==0.8.1 From e70d0b08c929e5140e38aa92a419de0c6d494148 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 14 Feb 2025 14:52:54 +0000 Subject: [PATCH 05/10] Sharper CHANGELOG entry. (#3448) --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4cd341b..ee0f81f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## 0.28.0 (28th November, 2024) -The 0.28 release includes a limited set of deprecations. +Be aware that the default *JSON request bodies now use a more compact representation*. This is generally considered a prefered style, tho may require updates to test suites. + +The 0.28 release includes a limited set of deprecations... **Deprecations**: From 4189b7f051c6c51ce74c3bee1a5f269f9c50c6b2 Mon Sep 17 00:00:00 2001 From: Kar Petrosyan <92274156+karpetrosyan@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:38:39 +0400 Subject: [PATCH 06/10] fix typo (#3519) --- httpx/_client.py | 2 +- httpx/_models.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/httpx/_client.py b/httpx/_client.py index 2249231f..13cd9336 100644 --- a/httpx/_client.py +++ b/httpx/_client.py @@ -1723,7 +1723,7 @@ class AsyncClient(BaseClient): if not isinstance(request.stream, AsyncByteStream): raise RuntimeError( - "Attempted to send an sync request with an AsyncClient instance." + "Attempted to send a sync request with an AsyncClient instance." ) with request_context(request=request): diff --git a/httpx/_models.py b/httpx/_models.py index 67d74bf8..2cc86321 100644 --- a/httpx/_models.py +++ b/httpx/_models.py @@ -964,7 +964,7 @@ class Response: Automatically called if the response body is read to completion. """ if not isinstance(self.stream, SyncByteStream): - raise RuntimeError("Attempted to call an sync close on an async stream.") + raise RuntimeError("Attempted to call a sync close on an async stream.") if not self.is_closed: self.is_closed = True @@ -1045,7 +1045,7 @@ class Response: if self.is_closed: raise StreamClosed() if not isinstance(self.stream, AsyncByteStream): - raise RuntimeError("Attempted to call an async iterator on an sync stream.") + raise RuntimeError("Attempted to call an async iterator on a sync stream.") self.is_stream_consumed = True self._num_bytes_downloaded = 0 @@ -1068,7 +1068,7 @@ class Response: Automatically called if the response body is read to completion. """ if not isinstance(self.stream, AsyncByteStream): - raise RuntimeError("Attempted to call an async close on an sync stream.") + raise RuntimeError("Attempted to call an async close on a sync stream.") if not self.is_closed: self.is_closed = True From ce7a6e91fbcaae8b8e5d8df5865a95a9b75acb64 Mon Sep 17 00:00:00 2001 From: T-256 <132141463+T-256@users.noreply.github.com> Date: Thu, 27 Feb 2025 21:13:26 +0330 Subject: [PATCH 07/10] Add `httpdbg` to third party packages. (#3327) Co-authored-by: Kar Petrosyan <92274156+karpetrosyan@users.noreply.github.com> --- docs/third_party_packages.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/third_party_packages.md b/docs/third_party_packages.md index 78ecc5a7..22e0f1a9 100644 --- a/docs/third_party_packages.md +++ b/docs/third_party_packages.md @@ -16,6 +16,12 @@ WebSocket support for HTTPX. Proxy (HTTP, SOCKS) transports for httpx. +### httpdbg + +[GitHub](https://github.com/cle-b/httpdbg) - [Documentation](https://httpdbg.readthedocs.io/) + +A tool for Python developers to easily debug the HTTP(S) client requests in a Python program. + ### Hishel [GitHub](https://github.com/karpetrosyan/hishel) - [Documentation](https://hishel.com/) From 9e8ab40369bd3ec2cc8bff37ab79bf5769c8b00f Mon Sep 17 00:00:00 2001 From: mv-python Date: Wed, 5 Mar 2025 13:52:58 +0100 Subject: [PATCH 08/10] Docs: Add `httpx.Proxy` to api.md (#3512) --- docs/api.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/api.md b/docs/api.md index d01cc649..f1bd50c9 100644 --- a/docs/api.md +++ b/docs/api.md @@ -159,3 +159,18 @@ what gets sent over the wire.* * `def delete(name, [domain], [path])` * `def clear([domain], [path])` * *Standard mutable mapping interface* + +## `Proxy` + +*A configuration of the proxy server.* + +```pycon +>>> proxy = Proxy("http://proxy.example.com:8030") +>>> client = Client(proxy=proxy) +``` + +* `def __init__(url, [ssl_context], [auth], [headers])` +* `.url` - **URL** +* `.auth` - **tuple[str, str]** +* `.headers` - **Headers** +* `.ssl_context` - **SSLContext** From 6c7af967734bafd011164f2a1653abc87905a62b Mon Sep 17 00:00:00 2001 From: Will Ockmore Date: Fri, 2 May 2025 12:24:26 +0100 Subject: [PATCH 09/10] Add httpx-retries to third party packages docs (#3552) --- docs/third_party_packages.md | 122 ++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/docs/third_party_packages.md b/docs/third_party_packages.md index 22e0f1a9..546607f7 100644 --- a/docs/third_party_packages.md +++ b/docs/third_party_packages.md @@ -2,73 +2,21 @@ As HTTPX usage grows, there is an expanding community of developers building tools and libraries that integrate with HTTPX, or depend on HTTPX. Here are some of them. + + ## Plugins -### httpx-ws - -[GitHub](https://github.com/frankie567/httpx-ws) - [Documentation](https://frankie567.github.io/httpx-ws/) - -WebSocket support for HTTPX. - -### httpx-socks - -[GitHub](https://github.com/romis2012/httpx-socks) - -Proxy (HTTP, SOCKS) transports for httpx. - -### httpdbg - -[GitHub](https://github.com/cle-b/httpdbg) - [Documentation](https://httpdbg.readthedocs.io/) - -A tool for Python developers to easily debug the HTTP(S) client requests in a Python program. - ### Hishel [GitHub](https://github.com/karpetrosyan/hishel) - [Documentation](https://hishel.com/) An elegant HTTP Cache implementation for HTTPX and HTTP Core. -### Authlib - -[GitHub](https://github.com/lepture/authlib) - [Documentation](https://docs.authlib.org/en/latest/) - -The ultimate Python library in building OAuth and OpenID Connect clients and servers. Includes an [OAuth HTTPX client](https://docs.authlib.org/en/latest/client/httpx.html). - -### Gidgethub - -[GitHub](https://github.com/brettcannon/gidgethub) - [Documentation](https://gidgethub.readthedocs.io/en/latest/index.html) - -An asynchronous GitHub API library. Includes [HTTPX support](https://gidgethub.readthedocs.io/en/latest/httpx.html). - ### HTTPX-Auth [GitHub](https://github.com/Colin-b/httpx_auth) - [Documentation](https://colin-b.github.io/httpx_auth/) -Provides authentication classes to be used with HTTPX [authentication parameter](advanced/authentication.md#customizing-authentication). - -### pytest-HTTPX - -[GitHub](https://github.com/Colin-b/pytest_httpx) - [Documentation](https://colin-b.github.io/pytest_httpx/) - -Provides `httpx_mock` [pytest](https://docs.pytest.org/en/latest/) fixture to mock HTTPX within test cases. - -### RESPX - -[GitHub](https://github.com/lundberg/respx) - [Documentation](https://lundberg.github.io/respx/) - -A utility for mocking out the Python HTTPX library. - -### rpc.py - -[Github](https://github.com/abersheeran/rpc.py) - [Documentation](https://github.com/abersheeran/rpc.py#rpcpy) - -An fast and powerful RPC framework based on ASGI/WSGI. Use HTTPX as the client of the RPC service. - -### VCR.py - -[GitHub](https://github.com/kevin1024/vcrpy) - [Documentation](https://vcrpy.readthedocs.io/) - -A utility for record and repeat an http request. +Provides authentication classes to be used with HTTPX's [authentication parameter](advanced/authentication.md#customizing-authentication). ### httpx-caching @@ -76,22 +24,76 @@ A utility for record and repeat an http request. This package adds caching functionality to HTTPX +### httpx-socks + +[GitHub](https://github.com/romis2012/httpx-socks) + +Proxy (HTTP, SOCKS) transports for httpx. + ### httpx-sse [GitHub](https://github.com/florimondmanca/httpx-sse) Allows consuming Server-Sent Events (SSE) with HTTPX. -### robox +### httpx-retries -[Github](https://github.com/danclaudiupop/robox) +[GitHub](https://github.com/will-ockmore/httpx-retries) - [Documentation](https://will-ockmore.github.io/httpx-retries/) -A library for scraping the web built on top of HTTPX. +A retry layer for HTTPX. + +### httpx-ws + +[GitHub](https://github.com/frankie567/httpx-ws) - [Documentation](https://frankie567.github.io/httpx-ws/) + +WebSocket support for HTTPX. + +### pytest-HTTPX + +[GitHub](https://github.com/Colin-b/pytest_httpx) - [Documentation](https://colin-b.github.io/pytest_httpx/) + +Provides a [pytest](https://docs.pytest.org/en/latest/) fixture to mock HTTPX within test cases. + +### RESPX + +[GitHub](https://github.com/lundberg/respx) - [Documentation](https://lundberg.github.io/respx/) + +A utility for mocking out HTTPX. + +### rpc.py + +[Github](https://github.com/abersheeran/rpc.py) - [Documentation](https://github.com/abersheeran/rpc.py#rpcpy) + +A fast and powerful RPC framework based on ASGI/WSGI. Use HTTPX as the client of the RPC service. + +## Libraries with HTTPX support + +### Authlib + +[GitHub](https://github.com/lepture/authlib) - [Documentation](https://docs.authlib.org/en/latest/) + +A python library for building OAuth and OpenID Connect clients and servers. Includes an [OAuth HTTPX client](https://docs.authlib.org/en/latest/client/httpx.html). + +### Gidgethub + +[GitHub](https://github.com/brettcannon/gidgethub) - [Documentation](https://gidgethub.readthedocs.io/en/latest/index.html) + +An asynchronous GitHub API library. Includes [HTTPX support](https://gidgethub.readthedocs.io/en/latest/httpx.html). + +### httpdbg + +[GitHub](https://github.com/cle-b/httpdbg) - [Documentation](https://httpdbg.readthedocs.io/) + +A tool for python developers to easily debug the HTTP(S) client requests in a python program. + +### VCR.py + +[GitHub](https://github.com/kevin1024/vcrpy) - [Documentation](https://vcrpy.readthedocs.io/) + +Record and repeat requests. ## Gists - - ### urllib3-transport [GitHub](https://gist.github.com/florimondmanca/d56764d78d748eb9f73165da388e546e) From 336204f0121a9aefdebac5cacd81f912bafe8057 Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Mon, 2 Jun 2025 22:29:52 +0300 Subject: [PATCH 10/10] Display proxy protocol scheme on error (#3571) --- httpx/_transports/default.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpx/_transports/default.py b/httpx/_transports/default.py index d5aa05ff..fc8c7097 100644 --- a/httpx/_transports/default.py +++ b/httpx/_transports/default.py @@ -355,7 +355,7 @@ class AsyncHTTPTransport(AsyncBaseTransport): else: # pragma: no cover raise ValueError( "Proxy protocol must be either 'http', 'https', 'socks5', or 'socks5h'," - " but got {proxy.url.scheme!r}." + f" but got {proxy.url.scheme!r}." ) async def __aenter__(self: A) -> A: # Use generics for subclass support.