httpx2-audit
Find what breaks when your Python stack moves from httpx to httpx2 (the pydantic fork; openai 3.x, anthropic 1.x, Starlette, the MCP SDK and huggingface_hub already switched). Pure stdlib, Python 3.9+ (it analyses code, it does not import httpx), no network except the optional TLS probe.
Unofficial community tool, not affiliated with httpx, httpx2 or pydantic. State as of 2026-10-18.
Why
The move breaks things silently: import httpx fails once an SDK stops pulling it in; respx and
pytest-httpx mocks stop intercepting, so tests hit the live API; except httpx.ConnectError no longer
catches errors raised by httpx2 code; httpx clients passed as http_client= are the wrong type; TLS switches
from the certifi bundle to the OS trust store.
pip install httpx2-audit # or: pip install git+https://github.com/rafal-one/httpx2-audit
check: static audit
$ httpx2-audit check src/
src/app.py:1:1: HX001 imports httpx; httpx2 is a separate package with its own module name [info]
src/app.py:4:36: HX004 httpx object or http_client passed on; an httpx2-based SDK needs httpx2 objects (http_client) [warning]
src/app.py:7:8: HX003 except clause names an httpx exception; errors raised by httpx2-based code are not caught (httpx.ConnectError) [warning]
| Rule | Severity | Meaning |
|---|---|---|
| HX001 | info | import httpx / from httpx import ... |
| HX002 | error | httpx imported but not declared in pyproject/requirements (transitive install is gone) |
| HX003 | warning | except httpx.X (also aliases and tuples) |
| HX004 | warning | http_client= or any httpx object (httpx.Timeout, httpx.Limits, ...) passed to a non-httpx call |
| HX005 | warning | isinstance/issubclass against httpx classes |
| HX006 | warning | import httpcore (httpx2 uses httpcore2) |
| HX007 | warning | respx / pytest_httpx imports: they do not mock httpx2 |
| HX008 | info | certifi.where() passed explicitly while httpx is in use |
| HX010 | warning | file imports both httpx and httpx2 |
Options: --format text|json|sarif (SARIF for GitHub code scanning), --min-severity, --fail-on info|warning|error|never (default warning), -q (no footer). Exit codes: 0 nothing at or above
--fail-on, 1 findings, 2 bad usage or missing path. Directories like .venv, node_modules, build
are skipped; files that do not parse are reported on stderr and skipped. Imports already wrapped in
try: import httpx2 ... except ImportError: import httpx are treated as handled.
CI: httpx2-audit check . --format sarif > audit.sarif, or just httpx2-audit check . --fail-on error.
fix: import and dependency codemod
Dry run by default (prints a unified diff); --write applies it.
httpx2-audit fix . # diff
httpx2-audit fix . --write # apply
httpx2-audit fix . --dual --write # libraries: try httpx2, fall back to httpx
import httpx->import httpx2 as httpx(so the rest of the file keeps working),from httpx import X->from httpx2 import X; same forhttpcore->httpcore2andpytest_httpx->pytest_httpx2.requirements*.txtandpyproject.tomlrequirement strings:httpx->httpx2>=2.0,httpcore,pytest-httpx(extras and markers are kept).--dualwraps each import in atry/except ImportErrorand leaves dependencies alone.- Private modules (
httpx._models) and dotted imports are reported asmanual:and left untouched. - It does not touch
exceptclauses,respxmocks or TLS settings; runcheckafterwards. httpx2 needs Python 3.10+.
env: mixed stacks and TLS
$ httpx2-audit env --probe api.openai.com --probe intranet.corp:8443
installed:
httpx 0.28.1
httpx2 2.14.0
depend on httpx: respx
depend on httpx2: pytest-httpx2
tls intranet.corp:8443: openssl-default=ok, certifi=FAIL: CERTIFICATE_VERIFY_FAILED, truststore=ok
WARNING: TLS trust differs for intranet.corp:8443: ...
Lists the relevant installed distributions, which installed packages require httpx or httpx2 (a mixed
environment cannot pass clients between them), and compares what the system store, certifi and truststore
(if installed) accept for the hosts you probe. Exit code 1 when warnings are printed.
Development
pytest (37 tests). Tested on Python 3.9 and 3.14; clean installs of wheel and sdist checked.
Donate
If this saved your migration a day: https://paypal.me/RafalBaranowski
MIT licensed.
Metadata
Release files for httpx2-audit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| httpx2_audit-0.1.0.tar.gz | 13.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| httpx2_audit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.8 kB
Release files / httpx2_audit-0.1.0.tar.gz
| Download URL | httpx2_audit-0.1.0.tar.gz |
|---|---|
| Size | 13.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1567db0aeb83c7d7afbe04bacc3f8e1c6dc9b52c31fd72696de266304f2abc2c
|
|
BLAKE2b-256 checksum How to use checksums |
5e8ee08ef446e13626c8203390efbbd7735c167e73db348f64677b63ae12b0b1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.8
|
Release files / httpx2_audit-0.1.0-py3-none-any.whl
| Download URL | httpx2_audit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1816f295ae77db856cca10af116f68b988f14ecadf1b89e31e0d9424dab168b7
|
|
BLAKE2b-256 checksum How to use checksums |
74f6a50394e2b27840481248afee7e517ef4ad2518ef8529150af89584e41f1f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.8
|
Security for httpx2-audit 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.