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 theSessionand at module level. - Request kwargs:
params=,data=(dict → form / str / bytes),json=(any object),headers=,cookies=,referer=. Response:.status_code(.statusalias),.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.cookiesfor what a response set. never_safari.HTTPError,Session(alias ofClient).
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
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 Distributions
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4cc7cc1201ca88cc0e7ff84b13cf3117362f9751fd223eca37415a44e51e8327
|
|
| MD5 |
1029630fa5cff48e33f07ac05256c867
|
|
| BLAKE2b-256 |
1191e5219a423388ec016c99866f7085c32e977406cb4ffe3a8fc5f419b0eef1
|
File details
Details for the file never_safari-0.4.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: never_safari-0.4.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
119793cc0afa7fdfbc28ede00c7968e6440877d2cf5e579617e557f37994a6c7
|
|
| MD5 |
81fb875ffeea73b26b3d3631c471f723
|
|
| BLAKE2b-256 |
12a6c65e96a6497933773aba9c5fa3217657005d75c386f7b4cec58ef3805030
|
File details
Details for the file never_safari-0.4.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: never_safari-0.4.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0998eae1fce375b2b1262ccb4813f4e991bd98f72a438972686e0d4f2f1584d5
|
|
| MD5 |
4b3e299bac5d1486c3834c6d2a6dbd25
|
|
| BLAKE2b-256 |
6bf210dbfa8e5c6872ac5c49591355cd69bb33bf8bbbb25853d70084e00c71b7
|
File details
Details for the file never_safari-0.4.1-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: never_safari-0.4.1-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.3 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3e24704832fb5cbffebe81159cd0a6da29cd12da1057e0ecf4a434602832b6b
|
|
| MD5 |
223fe03e92dcf3b3abe8f3a00dcebe20
|
|
| BLAKE2b-256 |
d3e86647baa84e6dabf95d7761666746fb529aaec4c6fa5f0c82ac9fb04ea906
|
File details
Details for the file never_safari-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: never_safari-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dfb39b35582f3d9b706978ac25e537c8758e47bf0e8b68c66080483ece012e16
|
|
| MD5 |
408998a76e644fb33277a688fe7b2cd9
|
|
| BLAKE2b-256 |
2174760cd59f0a4474f57078440b365feacd516e39e78393daa122326bfba62a
|