Skip to main content

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.

PyPI Python License: MIT

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

MIT

Metadata

Release files for tlsreq 0.1.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tlsreq 0.1.9
File Size Uploaded Provenance Actions
tlsreq-0.1.9.tar.gz 34.0 kB Without provenance Details for tlsreq-0.1.9.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tlsreq 0.1.9
File Interpreter ABI Platform Actions
tlsreq-0.1.9-py3-none-any.whl Python 3 none any Details for tlsreq-0.1.9-py3-none-any.whl

Total release size: 65.0 kB

Release files / tlsreq-0.1.9.tar.gz

Download URL tlsreq-0.1.9.tar.gz
Size 34.0 kB
Tags Source
SHA-256 checksum
How to use checksums
22e246d50a225ac2c18d106254c0d11d758f9d1b227cb975d3d9d4e5aaeb5398
BLAKE2b-256 checksum
How to use checksums
08ecffe8edc82cff6f05bfd90a0523d900f0c5fa47b9dd942e184d6cc2cc54f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release files / tlsreq-0.1.9-py3-none-any.whl

Download URL tlsreq-0.1.9-py3-none-any.whl
Size 31.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
04b26b5cd55f301a182e443cac6385003b6fc48eb3d65edb5183b70f52add49e
BLAKE2b-256 checksum
How to use checksums
c4a423838e76d9c4ea06b54f913d577851d613937d946b764ca4ac868c31d6c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Security for tlsreq 0.1.9

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page