fetchtron
A safe HTTP GET with the guardrails most clients leave to you.
One call fetches a URL and contains it: a deny-by-default domain allowlist, SSRF
protection, robots.txt (RFC 9309), and hard caps on size, time and redirects — with the
allowlist and SSRF checks re-run on every redirect hop, so a 302 cannot walk the
request to an internal address or an off-list host.
from fetchtron import fetch, FetchError
try:
got = fetch("https://example.org/doc", allowlist=["example.org"])
except FetchError as e:
print(e.code) # blocked_by_allowlist | blocked_private_address | robots_disallowed | ...
else:
print(got.final_url, got.status, got.content_type, len(got.content))
print(got.text) # decoded best-effort; got.content is the raw bytes
Or from the shell (deny-by-default: at least one --allow is required):
$ fetchtron get https://example.org/doc --allow example.org --json
What it guards
| Guard | Behaviour |
|---|---|
| Allowlist | deny-by-default; a domain also covers its subdomains; re-checked every redirect hop |
| SSRF | refuses loopback, private, link-local (incl. 169.254.169.254 cloud metadata), reserved, multicast and unspecified addresses |
| robots.txt | RFC 9309: 4xx = no rules (allowed); 5xx or unreachable = disallowed |
| Caps | max_bytes (streamed, never the whole page in memory), timeout_s (total), max_redirects |
| Scheme | http/https with a host only |
| Provenance | cleaned url/final_url (no credentials, no fragment), status, content_type, content_hash |
The allowlist is data you pass in — where the policy comes from (a config file, a
per-tenant rule, an area map) is your business; fetchtron only enforces it. It is
content-agnostic: pass content_types=["text/html"] to restrict, or omit it for any.
Why it exists
The classic SSRF bug is a plain requests.get(url) that follows a redirect to
http://169.254.169.254/… or http://10.0.0.5/…. Raw clients give you none of this
containment; you are expected to bolt it on, and most code doesn't. fetchtron is that
containment in one call, on a maintained client.
How it compares
See POSITIONING.md for the evidence-based comparison with raw requests/httpx,
advocate, and the web tools in langchain/smolagents — including the one place a
competitor does better (DNS-rebinding) and how fetchtron's roadmap closes it.
Install
pip install fetchtron
MIT licensed. Part of the network-agents-setup ecosystem; extracted from its governed runner so any project can fetch the web safely.
Metadata
Release files for fetchtron 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 | |
|---|---|---|---|
| fetchtron-0.1.0.tar.gz | 11.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fetchtron-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.8 kB
Release files / fetchtron-0.1.0.tar.gz
| Download URL | fetchtron-0.1.0.tar.gz |
|---|---|
| Size | 11.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a4eb4c767a809dbdffe49abe2f3cf96ea77db5d2958f2bcc99ffa531c8d7ca9e
|
|
BLAKE2b-256 checksum How to use checksums |
91d9529cf22083a3b45774f212a37cc77b50daef4631ac13960d1c84b1ad34c5
|
| 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 11, 2026.
Transparency logRelease files / fetchtron-0.1.0-py3-none-any.whl
| Download URL | fetchtron-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3bcc303e60066bd49d67155e23edfbb161fbfac1b30fda9ebc46ef900347901c
|
|
BLAKE2b-256 checksum How to use checksums |
19ea06957053a94afbbcecb9e157a45cfa547939a6b33d4be50a02a7277b470f
|
| 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 11, 2026.
Transparency log