httpx-curl-cffi
httpx transport for curl_cffi - python binding for curl-impersonate fork
Unlike other pure python http clients
like httpx (with native transport) or requests,
curl_cffi can impersonate browser's TLS/JA3 and HTTP/2 fingerprints.
Browser simulation implemented by low-level customizations
and usage of native browser TLS libraries
(BoringSSL for Chrome, nss for Firefox) -
which is impossible to achieve with Python's OpenSSL binding.
If you are blocked by some website for no obvious reason,
you can give curl_cffi a try.
Install
pip install httpx-curl-cffi
Usage
from httpx import Client, AsyncClient
from httpx_curl_cffi import CurlTransport, AsyncCurlTransport, CurlOpt
client = Client(transport=CurlTransport(impersonate="chrome", default_headers=True))
client.get("https://tools.scrapfly.io/api/fp/ja3")
async_client = AsyncClient(transport=AsyncCurlTransport(
impersonate="chrome",
default_headers=True,
# required for parallel requests, see curl_cffi issues below
curl_options={CurlOpt.FRESH_CONNECT: True}
))
Proxy from environment variables
Note that httpx.Client and httpx.AsyncClient
disables proxy configuration from environment variables
on providing transport argument even with trust_env=True (default),
to have this configured in the same way as native transport use snippet below:
import httpx
from httpx._utils import get_environment_proxies
from httpx_curl_cffi import CurlTransport # or AsyncCurlTransport
def transport_factory(proxy: httpx.Proxy | None = None) -> httpx.BaseTransport:
return CurlTransport( # or AsyncCurlTransport
proxy=proxy,
verify=False, # and other custom options
)
client = httpx.Client( # or httpx.AsyncClient
transport=transport_factory(),
mounts={
k: transport_factory(httpx.Proxy(url=v)) if v else None
for k, v in get_environment_proxies().items()
}
)
TODO
httpx.Requestcontent completely read in memory before sending, not sure if it's fixable withcurl_cffiat allCurlTransport.certargument should support in-memory data instead of filenames,pathlib.Path(instead of strings inhttpx._types.CertTypes) is forced
curl_cffi issues
httpx.Timeout.poolis ignored, should be implemented incurl_cffi- Simultaneous asynchronous requests requires to set
CurlTransport.curl_options={CurlOpt.FRESH_CONNECT: True}https://github.com/lexiforest/curl_cffi/issues/302 https://github.com/lexiforest/curl_cffi/issues/319
Known limitations
-
httpx.Timeout.writeis ignored (libcurllimitation) -
CurlTransport.verifyasssl.SSLContextisn't supported (becauseOpenSSLis not used) -
CurlTransport.trust_envargument is ignored,libcurlis always using environment variables for configuration, which is disabled for proxies usingCurlOpt.NOPROXYsetting to makeproxyargument have complete control on proxy usage, but may have effect in TLS configuration (but may not be used bycurl-impersonatefork, idk) https://github.com/lexiforest/curl_cffi/issues/345 -
httpx.Response.request.headersisn't updated with defaultcurl-impersonateheaders, which can be unexpected onCurlTransport.default_headers=Truehttps://github.com/lexiforest/curl_cffi/issues/368 -
CurlTransport.certargument isn't compatible with (deprecated)httpx._types.CertTypes- impossible to pass password as third tuple element,pathlib.Path(instead of strings inhttpx._types.CertTypes) is forced
Metadata
Release files for httpx-curl-cffi 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| httpx_curl_cffi-0.1.5.tar.gz | 7.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| httpx_curl_cffi-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.9 kB
Release files / httpx_curl_cffi-0.1.5.tar.gz
| Download URL | httpx_curl_cffi-0.1.5.tar.gz |
|---|---|
| Size | 7.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
177ee9968e9da142407017816cc3fb08ab281b134f773a9359b6a4650a6c81f3
|
|
BLAKE2b-256 checksum How to use checksums |
641f158975d2541effa30f0d7634542dce50e8280ab283e7efc8d221ebf8a949
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Dec 2, 2025.
Transparency logRelease files / httpx_curl_cffi-0.1.5-py3-none-any.whl
| Download URL | httpx_curl_cffi-0.1.5-py3-none-any.whl |
|---|---|
| Size | 8.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
be414a97ac1f627693f4c8a8631f2852bb1c09456e61ff8ad996ad050a11fb53
|
|
BLAKE2b-256 checksum How to use checksums |
6e1382039e3df58e0d52a6f82cc73d958400a2777d78c6cd6378c937a707afd0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Dec 2, 2025.
Transparency log