tlsreq
English | 简体中文
A single Session / AsyncSession API over four TLS-capable HTTP stacks:
curl_cffi · wreq · niquests + xutls · httpx + xutls
Change backend and impersonate. Request code stays the same.
Install
pip install tlsreq # httpx + h2 + brotli + zstd + xutls
pip install "tlsreq[niquests]" # or wreq / curl_cffi / all
pip install tlsreq pulls the default httpx stack: HTTP/2 (h2), br/zstd body decoding, and Chrome 152 TLS via xutls.
| Extra | Pulls in | Notes |
|---|---|---|
| (default) | httpx, h2, brotli, zstandard, xutls | Chrome 152 TLS + HTTP/2; decodes br/zstd |
httpx |
(already in the default install) | Kept so tlsreq[httpx] still works |
niquests |
niquests | Chrome 152 TLS + HTTP/2 patches |
wreq |
wreq | Python ≥ 3.11 only; skipped on 3.9/3.10 |
curl_cffi |
curl_cffi | |
all |
niquests, curl_cffi; wreq if Python ≥ 3.11 |
xutls import name is still utls. Do not also install the upstream utls package — both provide the utls module. To upgrade later: pip install -U xutls.
Quick start
import asyncio
from tlsreq import AsyncSession, Session, niquests, wreq
async def main():
async with AsyncSession(
backend=niquests,
impersonate=niquests.chrome152,
proxy="http://user:pass@host:port",
timeout=30,
extra={"pool_maxsize": 1},
) as s:
r = await s.get("https://tls.peet.ws/api/all")
print(r.status_code, r.http_version, r.cookies)
print(r.json()["tls"]["ja4"])
r = await s.post(
"https://example.com/login",
data=b"user=a&pass=b",
headers={"content-type": "application/x-www-form-urlencoded"},
header_order=["user-agent", "accept", "content-type"],
)
print(r.status_code, r.text)
asyncio.run(main())
with Session(wreq, wreq.chrome154, proxy="http://127.0.0.1:7890") as s:
r = s.get("https://example.com")
print(r.status_code, r.headers)
The native client is on session.raw when you need a backend-specific knob.
Backends
backend |
Default impersonate | Latest Chrome alias | Sync | Async |
|---|---|---|---|---|
niquests |
chrome:152 |
chrome152 |
yes | yes |
httpx |
chrome:152 |
chrome152 |
yes | yes |
curl_cffi |
chrome150 |
chrome150 |
yes | yes |
wreq |
Chrome154 |
chrome154 |
yes | yes |
Unknown backend or impersonate values raise. There is no silent fallback to another profile.
chrome / chromestable map to that backend’s current default. Fingerprints are attributes on the library object, so the editor lists only that library: Session(wreq, wreq.chrome154), Session(httpx, httpx.chrome152), Session(curl_cffi, curl_cffi.chrome150). wreq includes chrome154, firefox152, safari26_4, edge148, opera131, and okhttp5. httpx and niquests, along with nirequest, nirequests, and nio, have the eight xutls presets (chrome131, chrome142, chrome146, chrome148, chrome150, chrome152, chrome, chromestable). curl, cffi, and curl_cffi share the curl_cffi list. Session(wreq, "chrome154") and Session("wreq", "chrome154") still run. A quoted fingerprint string does not offer that list. Session(impersonate=...) defaults to httpx.
httpx / niquests offer both HTTP/2 and HTTP/1.1. The protocol is chosen from the negotiated TLS ALPN (h2 vs http/1.1); an HTTP/1.1-only origin falls back instead of failing.
Chrome 152 (niquests / httpx)
These two backends apply Chrome 152 HTTP/2 framing on top of xutls ClientHello impersonation:
| Signal | Value |
|---|---|
| SETTINGS | 1:65536;2:0;4:6291456;6:262144 |
| WINDOW_UPDATE | 15663105 |
| HEADERS priority | exclusive, weight 256 |
| Pseudo-header order | m,a,s,p |
| JA4 | t13d1517h2_8daaf6152771_cb7bf5808d99 |
| Akamai fingerprint | 1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p |
Checked against tls.peet.ws.
curl_cffi and wreq use their own stacks; they do not take this HTTP/2 patch.
API
Session / AsyncSession
Session(
backend: Backend[Imp] | str = httpx,
impersonate: Imp | None = None,
*,
proxy: str | None = None,
timeout: float = 30,
verify: bool = True,
headers: Mapping[str, str] | None = None,
cookies: Mapping[str, str] | None = None,
allow_redirects: bool = True,
extra: dict[str, Any] | None = None,
)
httpx, niquests, wreq, and curl_cffi are Backend objects exported by tlsreq. Import the one you pass in, then pass one of its fingerprint attributes: Session(wreq, wreq.chrome154). AsyncSession has the same signature.
Context-manager safe. AsyncSession methods are coroutines.
Requests
get / post / put / patch / delete / head / options all call request.
| Argument | Meaning |
|---|---|
headers |
Per-request headers |
params |
Query string |
data |
Form dict or raw body (str / bytes) |
json |
JSON body |
cookies |
Per-request cookies |
timeout |
Override session timeout |
allow_redirects |
Override session redirect flag |
header_order |
Wire order of header names, when the backend supports it |
extra |
Backend-specific kwargs for this call |
extra on the session is merged into the underlying constructor; extra on a request is merged into that call. Later keys win.
Response
Body is fully read when the response is wrapped. .text and .json() are synchronous on both Session types.
| Attribute | Type |
|---|---|
status_code |
int |
content |
bytes |
text |
str |
headers |
dict[str, str] |
cookies |
dict[str, str] |
url |
str |
http_version |
str | None |
raw |
native response |
session.cookies is the cookie jar as a dict. session.set_cookies(dict, url=None) writes into it.
License
Metadata
Release files for tlsreq 0.1.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tlsreq-0.1.8.tar.gz | 33.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tlsreq-0.1.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 64.5 kB
Release files / tlsreq-0.1.8.tar.gz
| Download URL | tlsreq-0.1.8.tar.gz |
|---|---|
| Size | 33.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b875dd7fa9f80e519be5d576078864d37ca4cba4a34c8c09038af0abad96112a
|
|
BLAKE2b-256 checksum How to use checksums |
aa9546325b2c5117b89632503e9054a77711c0094f7e96cb5849d2b696bef5de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / tlsreq-0.1.8-py3-none-any.whl
| Download URL | tlsreq-0.1.8-py3-none-any.whl |
|---|---|
| Size | 30.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
74885b1cb3a1fd60331c46dd3e32994b9c42b41d785f7c1144b09351340889a7
|
|
BLAKE2b-256 checksum How to use checksums |
7d2aac17efdfa90ceaca6c1b1fb67394fb96f4c39f3497e6814505d756613a73
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|