ProxyHat residential proxies for curl_cffi — TLS/JA3 browser impersonation with sticky sessions, geo-targeting and rotation.
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file curl_cffi_proxyhat-0.1.0.tar.gz.
File metadata
- Download URL: curl_cffi_proxyhat-0.1.0.tar.gz
- Upload date:
- Size: 10.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b64e0faf9273a2310763876ecd7b7e8b236c4fde4d7d677a11ecaec5f6c38196
|
|
| MD5 |
c4bded83ea3e52c6f74dcae29167363d
|
|
| BLAKE2b-256 |
b2cdb36c16cde1556638500851542b965c5bf51004f2d2e2a6deccae15550c2b
|
Provenance
The following attestation bundles were made for curl_cffi_proxyhat-0.1.0.tar.gz:
Publisher:
ci.yml on ProxyHatCom/curl-cffi-proxyhat
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
curl_cffi_proxyhat-0.1.0.tar.gz -
Subject digest:
b64e0faf9273a2310763876ecd7b7e8b236c4fde4d7d677a11ecaec5f6c38196 - Sigstore transparency entry: 2164396048
- Sigstore integration time:
-
Permalink:
ProxyHatCom/curl-cffi-proxyhat@d72a6276bacd8fab9382866354ef80fcb0033ae5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ProxyHatCom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@d72a6276bacd8fab9382866354ef80fcb0033ae5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file curl_cffi_proxyhat-0.1.0-py3-none-any.whl.
File metadata
- Download URL: curl_cffi_proxyhat-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d3ae5506742829b604f7cbf2785521b1714c55a93488e1cd07de6cd3323ffef2
|
|
| MD5 |
257463b423b2160cb50e66ab77e2cae8
|
|
| BLAKE2b-256 |
b24c0a94b1cdd56d3649fa0dc760b42c610bc601a20f859a0042415369f7cd6e
|
Provenance
The following attestation bundles were made for curl_cffi_proxyhat-0.1.0-py3-none-any.whl:
Publisher:
ci.yml on ProxyHatCom/curl-cffi-proxyhat
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
curl_cffi_proxyhat-0.1.0-py3-none-any.whl -
Subject digest:
d3ae5506742829b604f7cbf2785521b1714c55a93488e1cd07de6cd3323ffef2 - Sigstore transparency entry: 2164396062
- Sigstore integration time:
-
Permalink:
ProxyHatCom/curl-cffi-proxyhat@d72a6276bacd8fab9382866354ef80fcb0033ae5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ProxyHatCom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@d72a6276bacd8fab9382866354ef80fcb0033ae5 -
Trigger Event:
push
-
Statement type: