Skip to main content

Send local HTTP requests with a byte-exact macOS Safari 26.5 network fingerprint (TLS/HTTP2/HPACK/headers).

Project description

never_safari (Python)

Send local HTTP requests with a byte-exact macOS Safari 26.5 network fingerprint — TLS ClientHello (JA3/JA4), HTTP/2 (SETTINGS/WINDOW_UPDATE/ pseudo-header order), HPACK (Huffman + dynamic table), request-header order, download flow-control cadence, and TLS-record framing — like curl_cffi, but for Safari. Built on a patched BoringSSL + a from-scratch HTTP/2 layer.

Install

pip install never_safari          # prebuilt wheels: macOS / Linux / Windows
# or from source (needs cmake, go, ninja, a C/C++ compiler):
pip install maturin && maturin develop -m crates/safari-py/Cargo.toml

Use — a requests-style API

import never_safari

# Session keeps cookies + a connection pool (like a browser). `Client` is an alias.
s = never_safari.Session()
r = s.get("https://tls.peet.ws/api/all", params={"pretty": "1"})
print(r.status_code, r.ok)
print(r.json()["tls"]["ja4"])       # t13d2013h2_a09f3c656075_7f0f34a4126d

# POST: json= takes a Python object; data= takes a dict (form) / str / bytes.
r = s.post("https://api.example.com/v1/items",
           json={"name": "x"},
           headers={"authorization": "Bearer TOKEN"})
r.raise_for_status()                # raises never_safari.HTTPError on 4xx/5xx

# Module-level, exactly like requests:
never_safari.get("https://example.com", params={"q": "1"})
never_safari.post("https://api.example.com", data={"k": "v"}, timeout=10)

# Session options
s = never_safari.Session(
    ios=False,            # iOS Safari 26 profile (no post-quantum MLKEM768)
    verify=True,          # TLS cert verification (like requests)
    proxies={"https": "http://user:pass@host:8080"},
    multiplex=True,       # browser-style: concurrent requests share one connection
    timeout=30.0, connect_timeout=10.0, max_redirects=10,
)

Matches requests' surface:

  • Verbs: get/post/put/patch/delete/head/options/request — on the Session and at module level.
  • Request kwargs: params=, data= (dict → form / str / bytes), json= (any object), headers=, cookies=, referer=.
  • Response: .status_code (.status alias), .ok, .reason, .headers, .content, .text, .json(), .url, .resumed, .cookies, .raise_for_status().
  • Cookies (dict-like, like curl_cffi / httpx): s.cookies["k"], s.cookies.get("k", domain=…, path=…), .get_dict(domain=…, path=…), .set("k", "v", domain=…, path=…), .delete("k", domain=…, path=…), .clear(domain=…, path=…), .update(), .keys()/.values()/.items(), "k" in s.cookies, dict(s.cookies); r.cookies for what a response set.
  • never_safari.HTTPError, Session (alias of Client).

The network call releases the GIL, so many Python threads can crawl concurrently.

Async — AsyncSession (like curl_cffi)

import asyncio, never_safari

async def main():
    async with never_safari.AsyncSession() as s:      # max_workers= bounds concurrency
        r = await s.get("https://example.com", params={"q": "1"})
        r = await s.post(url, json={"a": 1})
        results = await asyncio.gather(*[s.get(u) for u in urls])   # runs concurrently

asyncio.run(main())

Same verbs, kwargs, Response and .cookies as the sync Session; every verb is a coroutine. It runs the (GIL-releasing) sync core in a bounded thread pool, so requests run genuinely in parallel. AsyncClient is an alias.

See the project README for the full fingerprint details and scope.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

never_safari-0.4.1-cp39-abi3-win_amd64.whl (1.4 MB view details)

Uploaded CPython 3.9+Windows x86-64

never_safari-0.4.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

never_safari-0.4.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

never_safari-0.4.1-cp39-abi3-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

never_safari-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file never_safari-0.4.1-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: never_safari-0.4.1-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for never_safari-0.4.1-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 4cc7cc1201ca88cc0e7ff84b13cf3117362f9751fd223eca37415a44e51e8327
MD5 1029630fa5cff48e33f07ac05256c867
BLAKE2b-256 1191e5219a423388ec016c99866f7085c32e977406cb4ffe3a8fc5f419b0eef1

See more details on using hashes here.

File details

Details for the file never_safari-0.4.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for never_safari-0.4.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 119793cc0afa7fdfbc28ede00c7968e6440877d2cf5e579617e557f37994a6c7
MD5 81fb875ffeea73b26b3d3631c471f723
BLAKE2b-256 12a6c65e96a6497933773aba9c5fa3217657005d75c386f7b4cec58ef3805030

See more details on using hashes here.

File details

Details for the file never_safari-0.4.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for never_safari-0.4.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0998eae1fce375b2b1262ccb4813f4e991bd98f72a438972686e0d4f2f1584d5
MD5 4b3e299bac5d1486c3834c6d2a6dbd25
BLAKE2b-256 6bf210dbfa8e5c6872ac5c49591355cd69bb33bf8bbbb25853d70084e00c71b7

See more details on using hashes here.

File details

Details for the file never_safari-0.4.1-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for never_safari-0.4.1-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f3e24704832fb5cbffebe81159cd0a6da29cd12da1057e0ecf4a434602832b6b
MD5 223fe03e92dcf3b3abe8f3a00dcebe20
BLAKE2b-256 d3e86647baa84e6dabf95d7761666746fb529aaec4c6fa5f0c82ac9fb04ea906

See more details on using hashes here.

File details

Details for the file never_safari-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for never_safari-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 dfb39b35582f3d9b706978ac25e537c8758e47bf0e8b68c66080483ece012e16
MD5 408998a76e644fb33277a688fe7b2cd9
BLAKE2b-256 2174760cd59f0a4474f57078440b365feacd516e39e78393daa122326bfba62a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page