syshttp
HTTP plumbing that behaves the same in every client you build on it:
which proxy to use, with which credential, for which hosts; how a prefix
gateway is spoken to; which cookies and tokens go with which origin; and TLS
through the operating system's own certificate verifier. By default it
routes the way the system does: the system's proxy configuration, PAC scripts
and WPAD included, unless a proxy variable says otherwise. An HTTP client on the
standard library puts all of them together; requests is needed by none of
it. Documentation: https://jose-pr.github.io/syshttp/.
Features
- Routing is proxylib's —
proxy.proxy_map()turns the settings below into one proxylib proxy map, and proxylib's client integrations send through it. - The system's proxy, by default — with no proxy variable set, the
system's configuration decides per URL: WinHTTP on Windows, CFNetwork on
macOS, libproxy or the desktop's settings elsewhere, PAC and WPAD included.
A list (
PROXY a; PROXY b; DIRECT) is tried in order, the next entry when one does not connect; with no proxy connecting and no DIRECT the request fails rather than going direct. - Proxies with credentials — a proxy URL from
SYSHTTP_PROXY, else the usualHTTPS_PROXY/HTTP_PROXY/ALL_PROXYfor the request's scheme. The credential is a header value sent verbatim to that proxy only, so any scheme works (Basic,Bearer,Negotiate).NO_PROXYis honoured (CIDR included), and every redirect hop is decided again. - Prefix gateways —
SYSHTTP_PROXY_TYPE=prefix:/fetch/sendsGET https://api.example.com/xto<proxy>/fetch/https://api.example.com/x(the client, requests, httpx and urllib; the client sends anhttps:origin through anhttpsgateway only). Responses, redirects and cookies still use the caller's URL. - Prefixes of a tool's own —
SYSHTTP_PREFIX=MYTOOL_makes the package readMYTOOL_HTTPS_PROXY,MYTOOL_SYSHTTP_HOMEand so on instead of the defaults;MYTOOL_:falls back to them, variable by variable. AnHTTPEnv("MYTOOL_")object keeps one configuration apart from another in the same process. - Cookie and token jars — Netscape cookie files with curl's matching rules, plus per-host token files. Both are chosen by the origin's host, never by the proxy's or the gateway's.
- URL hooks —
SYSHTTP_HOOKS_<KEY>=<regex>plus_PY=module:callableruns your code before matching requests: a login, a signature, a canned response. - The system's TLS client, or your own TLS context — by default
sslcontext's system context: the
operating system verifies certificates (CryptoAPI, the Security framework),
with no
certifibundle involved, and a server that asks for a client certificate gets one from the OS store (smart cards included), chosen as a browser chooses. OrHTTPClient(ssl_context=...)for a given identity, a cipher list or a pinned protocol version. - An HTTP client on the standard library —
HTTPClientandfetch(): retry with backoff, redirects that keep a credential with its origin, and all of the above, onhttp.clientandsslalone. Its transport is replaceable: any object withsend()(arequestsorhttpxone, a fake in a test), chosen per client or bySYSHTTP_DEFAULT_TRANSPORT. - Other programs' clients, patched on import —
SYSHTTP_IMPORTPATCH=1(orrequests:urllib:httpx:aiohttp:pip) makes those libraries route and verify the same way in any program of the environment, through importpatch; what a caller sets itself still wins.
Installation
pip install syshttp
| Extra | Adds | Needed for |
|---|---|---|
pac |
a JavaScript engine for proxylib | PAC scripts proxylib evaluates itself (Linux without libproxy) |
syshttp depends on proxylib (the system proxy), sslcontext (the system's
TLS client: the OS verifier through truststore on Python 3.10+, OpenSSL over
the default store on 3.9) and importpatch (its .pth hooks imports at
interpreter start; nothing is patched unless SYSHTTP_IMPORTPATCH says so).
Quick start
Ask where a request would go, the way every client here does:
import proxylib
from syshttp import proxy
for entry in proxylib.lookup(proxy.proxy_map(), "https://api.example.com/"):
print("DIRECT" if entry is None else entry.url) # tried in this order
One request, routed and verified the way the system does (no extra to install):
from syshttp import fetch
response = fetch("https://api.example.com/thing")
print(response.status, response.json())
A client with file-backed cookies and tokens, kept across requests:
from syshttp.client import HTTPClient
with HTTPClient(cookies=True, tokens=True) as client:
response = client.request("GET", "https://api.example.com/thing")
A separate configuration, isolated from the process environment:
from syshttp import HTTPEnv, fetch
env = HTTPEnv("MYTOOL_", environ={"MYTOOL_SYSHTTP_PROXY": "http://proxy.internal:3128"})
response = fetch("https://api.example.com/thing", env=env)
API overview
| Module | Purpose |
|---|---|
syshttp.env |
HTTPEnv: the prefixes and mapping every setting is read from |
syshttp.proxy |
proxy_map(): the settings as one proxylib proxy map |
syshttp.client |
HTTPClient and fetch(): the HTTP client, its transport protocol and response |
syshttp.jar |
file and memory cookie/token jars |
syshttp.cookies |
Netscape cookie files and curl's cookie rules |
syshttp.hooks |
URL hooks declared in the environment |
syshttp.tls |
the OS verifier as an SSLContext |
syshttp.autopatch |
requests, urllib, httpx, aiohttp and pip patched on import |
syshttp.retry |
the transient statuses, Retry-After |
Settings
Every setting is read as <PREFIX><NAME> for each prefix of
SYSHTTP_PREFIX (:-separated; default none, the names as written). The
full list is on the docs site:
https://jose-pr.github.io/syshttp/settings/.
| Variable | Sets |
|---|---|
SYSHTTP_PREFIX |
the prefixes every other setting is read under |
SYSHTTP_PROXY |
the proxy URL; else HTTPS_PROXY, HTTP_PROXY, ALL_PROXY, else the system's |
SYSHTTP_SYSTEM_PROXY |
0 to stop consulting the system's proxy configuration |
SYSHTTP_PROXY_AUTH |
the proxy credential, sent verbatim; else HTTP_PROXY_AUTH |
SYSHTTP_PROXY_AUTH_HEADER |
the header it is sent in (default Proxy-Authorization) |
SYSHTTP_PROXY_TYPE |
connect (default) or prefix[:/endpoint] |
SYSHTTP_HOME |
the jar directory (default: the per-user state directory) |
SYSHTTP_IMPORTPATCH |
1, or :-separated names: the client libraries patched on import |
SYSHTTP_HOOKS_<KEY> |
a URL hook's pattern, with _PY / _CURL targets |
SYSHTTP_DEFAULT_TRANSPORT |
module:attr or <file>.py:attr: the transport of a client given none (it names code to import) |
CA_BUNDLE |
the CA bundle a client verifies with (default: the OS verifier) |
Development
dotagents pyvenv # or any Python 3.9+ virtual environment
.pyvenv/<tag>/Scripts/python -m pip install -e ".[dev]"
.pyvenv/<tag>/Scripts/python -m pytest -q
Releasing
This project follows Semantic Versioning and keeps a
CHANGELOG.md.
Pushing a tag matching v* triggers the release workflow: test gate → build
(checking the tag names the version built) → a strict docs build as a gate →
GitHub release → publish. The release workflow never deploys the docs site
itself: for a final release its last job dispatches the docs workflow at the
tag, which owns every Pages deploy.
License
MIT — see LICENSE.
Metadata
Release files for syshttp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| syshttp-0.1.0.tar.gz | 175.4 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| syshttp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 279.9 kB
Release files / syshttp-0.1.0.tar.gz
| Download URL | syshttp-0.1.0.tar.gz |
|---|---|
| Size | 175.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
90603d717bf677ccfcd16c666458669bb93db512806ad5aaf7d9a96c80dd49ed
|
|
BLAKE2b-256 checksum How to use checksums |
9d86c58506f957a9c22bcffdcaeff1fc9cbbb9c7243df8d45f8b4ac84b4906e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logRelease files / syshttp-0.1.0-py3-none-any.whl
| Download URL | syshttp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 104.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1fdc1456a8fcb012a85067d0e9f5d96d4e1335722eaeb6288eeaf36b53e01fb0
|
|
BLAKE2b-256 checksum How to use checksums |
cf730cfd5e6259557eb6cc7f19d610b865aed123ae8ad9a34e1050a3c85dcc9a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logSecurity for syshttp 0.1.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for syshttp-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.
Transparency logA 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.