Browser TLS fingerprint impersonation library powered by Rust (BoringSSL + hyper).
Project description
rqsession
A Python HTTP library that impersonates real browser TLS fingerprints, powered by a Rust native extension (BoringSSL + hyper + tokio).
What it does
Most anti-bot systems (Cloudflare, Akamai, DataDome, etc.) inspect the TLS ClientHello and HTTP/2 SETTINGS frame to distinguish scrapers from real browsers. Standard requests or httpx produce a recognizable Python fingerprint regardless of what User-Agent you set.
rqsession controls the full fingerprint stack at the Rust level:
| Layer | What is controlled |
|---|---|
| TLS ClientHello | Cipher suite order, supported groups (curves), ALPN, signature algorithms, version range |
| HTTP/2 | SETTINGS frame values (window size, max frame size), connection WINDOW_UPDATE |
| HTTP headers | Exact header order, browser-specific headers (sec-ch-ua, sec-fetch-*, etc.) |
No external proxy process required — it's a compiled .pyd / .so extension, imported directly.
Installation
pip install rqsession
Pre-built wheels are available for Windows x86_64, Linux x86_64/aarch64, and macOS x86_64/arm64.
Quick Start
Synchronous
from rqsession.rust_session import BrowserSession, Chrome120
with BrowserSession(Chrome120) as s:
resp = s.get("https://httpbin.org/get")
print(resp.status_code) # 200
print(resp.json())
Async
import asyncio
from rqsession.rust_session import AsyncBrowserSession, Chrome120
async def main():
async with AsyncBrowserSession(Chrome120) as s:
resp = await s.get("https://httpbin.org/get")
print(resp.status_code)
print(resp.json())
asyncio.run(main())
Concurrent async requests
import asyncio
from rqsession.rust_session import AsyncBrowserSession, Chrome120
async def main():
async with AsyncBrowserSession(Chrome120) as s:
results = await asyncio.gather(
s.get("https://httpbin.org/get"),
s.get("https://httpbin.org/ip"),
s.get("https://httpbin.org/user-agent"),
)
for r in results:
print(r.status_code)
asyncio.run(main())
Built-in Browser Profiles
| Import name | Browser | OS |
|---|---|---|
Chrome120 |
Chrome 120 | Windows |
Chrome119 |
Chrome 119 | Windows |
Edge142 |
Edge 142 | Windows |
Firefox133 |
Firefox 133 | Windows |
Safari17 |
Safari 17 | macOS |
from rqsession.rust_session import (
BrowserSession, AsyncBrowserSession,
Chrome120, Chrome119, Edge142, Firefox133, Safari17,
)
Each profile carries its own cipher suite order, curves, signature algorithms, HTTP/2 settings, and header order — matching the real browser's wire behavior.
Proxy Support
Both sync and async sessions accept a proxy URL at construction time:
# HTTP proxy
s = BrowserSession(Chrome120, proxy="http://127.0.0.1:7890")
# Authenticated proxy
s = BrowserSession(Chrome120, proxy="http://user:pass@host:port")
# Async
async with AsyncBrowserSession(Firefox133, proxy="http://127.0.0.1:7890") as s:
resp = await s.get("https://example.com")
The proxy tunnel is implemented as an HTTP CONNECT connection at the TCP level, so TLS fingerprinting applies end-to-end through the tunnel.
Session API
Constructor parameters
BrowserSession(
profile, # built-in constant or BrowserProfile object
*,
proxy=None, # "http://[user:pass@]host:port"
verify=True, # set False to skip SSL verification
ca_bundle=None, # path to CA bundle; auto-detects certifi when None
)
# AsyncBrowserSession takes the same parameters
Request methods
# GET
resp = s.get(url, headers={...}, params={...})
# POST — form data or JSON
resp = s.post(url, data=b"...", headers={...})
resp = s.post(url, json={"key": "value"})
# Generic
resp = s.request("PUT", url, headers={...}, json={...})
# Async versions — same signature, add `await`
resp = await s.get(url)
resp = await s.post(url, json={...})
Response object
Compatible with requests.Response style:
resp.status_code # int
resp.text # str (auto-decoded)
resp.content # bytes
resp.headers # dict[str, str]
resp.json() # parsed JSON → dict / list
resp.ok # True when status < 400
resp.raise_for_status() # raises on 4xx/5xx
resp.url # final URL after redirects
Response bodies are automatically decompressed (gzip, deflate, br, zstd).
Cookies
# Persist cookies manually
s.update_cookies({"token": "abc123"})
# Cookies from Set-Cookie response headers are automatically
# stored in the session and sent on subsequent requests.
Adding Custom Browser Profiles
Capture a fingerprint from a real browser using tls.peet.ws/api/all, then convert it:
# Save output from tls.peet.ws as chrome136.json, then:
python tools/tls_peet_to_profile.py chrome136.json -n chrome136_windows --install
The --install flag writes the profile directly to rqsession/rust_session/profiles/builtin/.
You can also load profiles at runtime without rebuilding:
from rqsession.rust_session import BrowserSession, load_custom, load_profile_json
from rqsession._rust_core import load_profile
# From profiles/custom/<name>.json
s = BrowserSession(load_custom("my_browser"))
# From a JSON string
s = BrowserSession(load_profile_json('{"name": "...", "tls": {...}, ...}'))
# From an arbitrary file path
s = BrowserSession(load_profile("/path/to/profile.json"))
# List available profiles
from rqsession.rust_session import list_builtin, list_custom
print(list_builtin()) # ['chrome120_windows', 'firefox133_windows', ...]
print(list_custom()) # ['my_browser', ...]
Windows asyncio note
Python 3.8+ on Windows uses ProactorEventLoop by default. If you see event-loop errors, switch to SelectorEventLoop before asyncio.run():
import asyncio, sys
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
asyncio.run(main())
Legacy layers
Earlier versions of this library included RequestSession and EnhancedRequestSession. These layers are still available for backward compatibility:
from rqsession import RequestSession # basic requests.Session wrapper
from rqsession import EnhancedRequestSession # routes through a local Rust proxy process
For new projects, use BrowserSession / AsyncBrowserSession instead — they are faster, require no external process, and provide more accurate fingerprinting.
License
Apache 2.0 — see LICENSE.
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 Distributions
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 rqsession-0.4.1.tar.gz.
File metadata
- Download URL: rqsession-0.4.1.tar.gz
- Upload date:
- Size: 273.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eefd0ab88579b615941960ee314d8fff6672a1610ec69142d58d4b73c0f819c2
|
|
| MD5 |
bf4d5c86fb315ee0a81b5a81b93e1257
|
|
| BLAKE2b-256 |
286d36c3cc6a957e538831764cb88adbf597ec139401aad7f567291bb9a2968d
|
File details
Details for the file rqsession-0.4.1-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7a2f3ac551196cccbb1102726fd85ceea8643cac0d0a43b18979c30fa7e46ee
|
|
| MD5 |
36cbf41339b57877898376cf726a11bc
|
|
| BLAKE2b-256 |
bca0d5ffbfdbe88cc4fe64fcb954d9df1ce9c7809b05a53100a92fd749c42387
|
File details
Details for the file rqsession-0.4.1-cp314-cp314-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp314-cp314-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.14, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
223eaa9823513391ddfdf68cc2cecdd4c30bd8799043625aa8936300d98bde24
|
|
| MD5 |
d80cf93cdd30b32efbf479b741642f37
|
|
| BLAKE2b-256 |
3447b1e55640aacfa035f7579e80703653b39d10f48e7f68ed2fd1033c55892e
|
File details
Details for the file rqsession-0.4.1-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8263f06c846be646c7f38963e0cb84fd293829b77bd36389ccea16019ebbaeb
|
|
| MD5 |
ed248bf05f9d2becc48aa5e8b1d709e1
|
|
| BLAKE2b-256 |
9ad8eb2d9ee48dbe41e49490853cdb79bc76e1a4bafc70df1d73f4f68bd82aec
|
File details
Details for the file rqsession-0.4.1-cp313-cp313-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp313-cp313-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.13, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b1fbd484e2be2d63d4022c4c534f0e9d708771ae89dcde64ad41c954cfcd29d
|
|
| MD5 |
00ab01b580cd53a0c5c3c9597567cdd0
|
|
| BLAKE2b-256 |
ffea18ede7fff5819e1521a85f0025df19d4faeca9778362b423f4918669f18f
|
File details
Details for the file rqsession-0.4.1-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
387c7832adebb6b50f1b6a92cde15c07b8a3cf956f69d1452433f7c37535ae43
|
|
| MD5 |
ac1d7b0c70f35886e4d6e836e25d47f6
|
|
| BLAKE2b-256 |
c052d49db9360d16396582dfb5a4c6b04340ebe67044308f85c744ae51035d14
|
File details
Details for the file rqsession-0.4.1-cp312-cp312-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp312-cp312-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4895373e3596c67318744801a370be77a0158ccd1e81c92780f8680a7b156ce7
|
|
| MD5 |
2fbd72753e060eed3d035d10c3ac00f0
|
|
| BLAKE2b-256 |
723b4d6d6fa687875dc111cbd3e38e6dddae44ef6d8dc67cc01a1edd50ef5963
|
File details
Details for the file rqsession-0.4.1-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
184a09e56609e4ca6a7934bb07eb490b77959e7805e696b045ecd27498322db5
|
|
| MD5 |
9b1763eaa849c130446bb54ddb4025ba
|
|
| BLAKE2b-256 |
4e79b6e5120ff08fc454cd438d42fb8a9382dbd17a3a66ca98eb6f2693caa31f
|
File details
Details for the file rqsession-0.4.1-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f82455074751ef6628511095ffa230d08acf73154f9407b8a6202deb7322ede9
|
|
| MD5 |
2ec559041038560c2b95135bbb3d0176
|
|
| BLAKE2b-256 |
a2e13c931ab1d2dfa40d9a2635de2134ccbb01a48de0c6d5ee1b0a8794d59331
|
File details
Details for the file rqsession-0.4.1-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2501637b906c09fc932da74765d6869c3a17304e6744c5212c28ff0b83a80485
|
|
| MD5 |
0073277069c7b0dd8a85cb90488e77c1
|
|
| BLAKE2b-256 |
ef8351d05782c461e1feabae65ecc0d32c16927188dc54faef5d4bfc6a81ff62
|
File details
Details for the file rqsession-0.4.1-cp310-cp310-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp310-cp310-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.10, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b95c4ebfff45143a546154fdd00fb903fc9b1bddb8fdd12a79c82dc2eb25155
|
|
| MD5 |
5e1919afa64717f222ea57c89f0c82d4
|
|
| BLAKE2b-256 |
78c7d727b19b22b3dbe411b3ffab8a2ceb30798c1853766902f0e044a06c43c6
|
File details
Details for the file rqsession-0.4.1-cp39-cp39-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp39-cp39-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.9, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74f6e66044a29066334f2e75bfb877341304def4c699a1d3a8ab94174479598a
|
|
| MD5 |
260c5124544a4e6c141bafcd759820e0
|
|
| BLAKE2b-256 |
7e098ef2f4f0cbd45ccf95bd8cef4368c6417282386073346fc2fda01d560241
|
File details
Details for the file rqsession-0.4.1-cp38-cp38-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rqsession-0.4.1-cp38-cp38-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.8, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84511d629aeb290eaee0dc56e14bc2854476927829d761ecebd1f55fba19ee2c
|
|
| MD5 |
6336a93c6305217dcdf709501479975a
|
|
| BLAKE2b-256 |
acc43c5f2b02b3078537b77fb3e851528cff8bbedac9057742981915974dc45a
|