modern-httplib2
A 100% compatible, zero-code-change drop-in replacement for Python's httplib2 library, powered under the hood by httpx and httpcore.
Why modern-httplib2?
Legacy httplib2 is deeply embedded across the Python ecosystem (notably via google-api-python-client, google-auth-httplib2, and multi-threaded tools like GAM), but its original transport layer is built directly on Python's low-level http.client with single-socket state per Http() instance.
modern-httplib2 keeps the exact httplib2 public API, module layout, exception hierarchy, RFC 2616 caching, authentication schemes (Basic, Digest, WSSE, GoogleLogin, HmacDigest), and ProxyInfo semantics while replacing the underlying transport engine with httpx (httpcore + h2):
- Python Package & PyPI Name: Published as
modern-httplib2, importing asmodern_httplib2. - Transparent Interceptor / Auto-Patching: Providing
import modern_httplib2.autoormodern_httplib2.patch()which mountsmodern_httplib2intosys.modules["httplib2"]. Existing dependencies likegoogle-api-python-clientandgoogle-auth-httplib2automatically and transparently usemodern_httplib2without any code changes to Google's libraries. - Direct Import Support: Use directly via
import modern_httplib2orimport modern_httplib2 as httplib2. - Modern
httpx/httpcoreTransport: Useshttpx'shttpcoreconnection pool andh11/h2protocol state machines. - True Multi-Threaded HTTP/2 Multiplexing: Multiple threads sharing a single
Http()instance multiplex concurrent requests over a single TCP+TLS HTTP/2 connection (up to 100 concurrent streams per connection), even on cold start. - Thread-Safe Connection Pooling: Unlike upstream
httplib2.Http()(which is notorious for thread-safety crashes when shared across threads),modern-httplib2uses thread-local active request dispatch backed by a thread-safe per-originhttpcore.ConnectionPool(pool_maxsize=16by default). - Transparent HTTP/2 over TLS (ALPN
h2): Automatically negotiates HTTP/2 on HTTPS connections when the server advertisesh2via TLS ALPN, with seamless fallback to HTTP/1.1. - Python 3.11+ Native: Built exclusively for supported Python versions (3.11+), free of legacy Python 2 / early Python 3 compatibility shims.
- 100% Upstream Test Suite Compatibility: Passes all 526+ upstream
httplib2unit and integration tests.
Installation
Install from PyPI:
pip install modern-httplib2
Usage
1. Transparent Interception in Existing Projects (e.g. GAM)
To automatically redirect all import httplib2 calls across your application and its dependencies (like google-api-python-client and google-auth-httplib2) to modern_httplib2, import modern_httplib2.auto at your application entrypoint:
try:
import modern_httplib2.auto
except ImportError:
pass
# All downstream imports now transparently use modern_httplib2!
import google_auth_httplib2
import googleapiclient.discovery
import httplib2
http = httplib2.Http()
2. Direct Import Usage
import modern_httplib2 as httplib2
http = httplib2.Http(".cache")
resp, content = http.request("https://httpbin.org/get", "GET")
print(resp.status, resp.version) # e.g. 200, 20 (HTTP/2) or 11 (HTTP/1.1)
2. Thread-Safe Concurrent Requests
You can safely share a single httplib2.Http instance across multiple threads:
from concurrent.futures import ThreadPoolExecutor
import httplib2
http = httplib2.Http(pool_maxsize=16)
def fetch(url):
resp, body = http.request(url)
return resp.status, len(body)
with ThreadPoolExecutor(max_workers=8) as pool:
results = list(pool.map(fetch, ["https://example.com"] * 32))
3. Controlling HTTP/2 Negotiation & Corporate Firewall Downgrade
HTTP/2 over TLS is enabled by default (enable_http2=True). For environments where corporate firewalls, deep packet inspection (DPI) middleboxes, or legacy proxies reject, reset, or misbehave with HTTP/2 traffic, modern-httplib2 provides multiple ways to force HTTP/1.1:
Automatic Firewall Fallback (Enabled by Default)
By default (auto_downgrade_http2=True), if an HTTP/2 connection fails due to a network or protocol reset (e.g. proxy RST on HTTP/2 preface, stream errors, or closed connections), modern-httplib2 will:
- Automatically downgrade the connection to HTTP/1.1.
- Remember that host for subsequent requests in the session.
- Transparently retry the request without raising an exception to the caller.
Global / Application-Wide Toggle
Disable HTTP/2 globally in your application (for example, when a user sets force_http11 = true in their configuration file):
import httplib2
# Any of these can be called at startup:
httplib2.force_http11()
# or:
httplib2.ENABLE_HTTP2 = False
# or:
httplib2.set_enable_http2(False)
Environment Variable (Zero Code Change)
Set the environment variable in your shell or configuration:
export MODERN_HTTPLIB2_ENABLE_HTTP2=0
# or
export HTTPLIB2_ENABLE_HTTP2=0
Per-Instance Control
import httplib2
http_v1 = httplib2.Http(enable_http2=False)
# or dynamically on an existing instance:
http_v1.force_http11()
resp, content = http_v1.request("https://example.com")
assert resp.version == 11
4. Using with google-auth-httplib2
import google.auth
import google_auth_httplib2
import httplib2
credentials, project = google.auth.default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
authed_http = google_auth_httplib2.AuthorizedHttp(credentials, http=httplib2.Http())
resp, content = authed_http.request("https://www.googleapis.com/oauth2/v1/ tokeninfo")
Running Tests
.venv/bin/pytest
Metadata
Release files for modern-httplib2 1.32.0.post1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| modern_httplib2-1.32.0.post1.tar.gz | 141.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| modern_httplib2-1.32.0.post1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 248.7 kB
Release files / modern_httplib2-1.32.0.post1.tar.gz
| Download URL | modern_httplib2-1.32.0.post1.tar.gz |
|---|---|
| Size | 141.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0b8a65de75ddbce997988db97a5b0507ae4154ba426f9d3b47d9fe5cd0ed2f43
|
|
BLAKE2b-256 checksum How to use checksums |
0803a198761dbfd23f2d921a2e0fe356ab8c53e53cc3f8f16a81a2fe0bb115ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency logRelease files / modern_httplib2-1.32.0.post1-py3-none-any.whl
| Download URL | modern_httplib2-1.32.0.post1-py3-none-any.whl |
|---|---|
| Size | 107.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e0aed9cf4b4217441110fb84c272813aacf16b450d0e036f81e563a325b46a6e
|
|
BLAKE2b-256 checksum How to use checksums |
9f8ced810954d3a2d74109b58e3f61923bcd1dcc4dbec9224cf4a70d3673280b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency log