curl-cffi-proxyhat
Route curl_cffi requests through ProxyHat residential proxies — real browser TLS/JA3 impersonation plus a sticky residential IP, geo-targeting and rotation.
Why
curl_cffi already wins half the anti-bot fight: it impersonates a real browser's TLS/JA3 and HTTP2 fingerprint, so servers see Chrome or Safari instead of Python. The other half is the exit IP — a datacenter address gives you away no matter how good the fingerprint is. This package plugs ProxyHat's residential IPs (50M+ across 148+ countries) into curl_cffi so the fingerprint and the IP both look like a real user. One pinned residential IP per session by default, so cookies and TLS stay coherent. No fork, no boilerplate.
Install
pip install curl-cffi-proxyhat
curl_cffi and the official proxyhat SDK come as dependencies.
Quick start
from curl_cffi_proxyhat import ProxyHatSession
# An API key auto-selects an active residential sub-user.
# Sticky by default: one pinned US IP for the whole session.
with ProxyHatSession(country="us", impersonate="chrome") as s:
r = s.get("https://tls.browserleaks.com/json")
print(r.json()) # residential IP + a Chrome TLS fingerprint
ProxyHatSession is a drop-in curl_cffi.requests.Session subclass: same get/post/request methods and the same impersonation, but every request exits through a ProxyHat residential IP.
Get an API key at proxyhat.com.
Just want the proxy dict for a plain curl_cffi call?
import curl_cffi
from curl_cffi_proxyhat import proxyhat_proxies
proxies = proxyhat_proxies(country="de", sticky="1h")
r = curl_cffi.get("https://example.com", impersonate="chrome", proxies=proxies)
# proxyhat_proxies(...) -> {"http": "http://...@gate.proxyhat.com:8080", "https": "..."}
Credentials
Pass them explicitly or via environment variables — options win over env:
| Option | Env var | Notes |
|---|---|---|
api_key |
PROXYHAT_API_KEY |
Auto-selects an active sub-user with remaining traffic |
sub_user |
PROXYHAT_SUBUSER |
Pick a specific sub-user by uuid or name (with an API key) |
username |
PROXYHAT_USERNAME |
Explicit gateway proxy_username (skips the API) |
password |
PROXYHAT_PASSWORD |
Explicit gateway proxy_password |
Targeting
ProxyHatSession(
protocol="http", # or "socks5"
country="us", # ISO code or "any" (default)
region="california",
city="new_york",
filter="high", # AI IP-quality tier
sticky="30m", # session lifetime (default); sticky=False rotates every request
impersonate="chrome", # any curl_cffi browser target; default "chrome", None disables
timeout=30, # any extra kwarg is forwarded to curl_cffi's Session
)
The same knobs work on proxyhat_proxies(...) (everything except impersonate, which is a curl_cffi request option, not a proxy one).
Sticky IP per session (default)
A scraping session usually makes many requests against the same site — a search, then result pages, then details. If the exit IP changed mid-session the site would see a user teleporting between cities and block it. So this package is sticky by default: one residential IP is pinned for the whole session (sticky="30m", renewed as you work), keeping cookies and TLS fingerprint coherent.
Want a fresh IP on every request instead (e.g. many independent one-shot fetches)? Turn stickiness off:
with ProxyHatSession(country="us", sticky=False) as s: # rotating residential IP per request
for url in urls:
s.get(url)
Set a custom lifetime with sticky="2h".
How it works
ProxyHatSession resolves your gateway credentials (via the official proxyhat SDK — an API key auto-picks an active sub-user, or pass username/password), then builds a ProxyHat connection URL with the SDK's targeting grammar (http://<user>-country-us-sid-<id>-ttl-30m:<pass>@gate.proxyhat.com:8080) and hands proxies={"http": url, "https": url} plus your impersonate choice to curl_cffi.requests.Session. From there it is a curl_cffi session: it speaks the impersonated browser handshake over ProxyHat's residential exit. A sticky username pins one IP; a rotating one makes the gateway hand out a fresh IP per connection. proxyhat_proxies(...) builds the same dict for a bare curl_cffi.get(...) when you don't need a session.
License
MIT © ProxyHat
Metadata
Release files for curl-cffi-proxyhat 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| curl_cffi_proxyhat-0.1.1.tar.gz | 10.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| curl_cffi_proxyhat-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.1 kB
Release files / curl_cffi_proxyhat-0.1.1.tar.gz
| Download URL | curl_cffi_proxyhat-0.1.1.tar.gz |
|---|---|
| Size | 10.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bf14c7a1a2c8a5eaefe8d8c883b3608b68dec7c9a5dec4ef52be31e7e9346712
|
|
BLAKE2b-256 checksum How to use checksums |
8282ea44e064f1a2298f4556e6962059b17a36cf9d6be83814769bbf20d6afd2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jul 14, 2026.
Transparency logRelease files / curl_cffi_proxyhat-0.1.1-py3-none-any.whl
| Download URL | curl_cffi_proxyhat-0.1.1-py3-none-any.whl |
|---|---|
| Size | 8.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
978ee6aae3f8ddaee1da82595c5d7505d01a20ed020dfa3001b3871f86ea1904
|
|
BLAKE2b-256 checksum How to use checksums |
2703bb84cf8a5e508ec521ead26907d5eca6709412b07eb2051a4aab9444992c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jul 14, 2026.
Transparency log