Skip to main content

fromcache

ci PyPI license built with Zig static musl

A tiny, operator-curated artifact cache for a small lab, for the big vendor downloads you re-pull constantly (CUDA, ROCm, DOCA, firmware, drivers), fronted by transparent curl/wget shims so existing scripts use it with no changes.

Think of it as "ccache for HTTP artifacts, without a proxy."

curl -fsSL https://the/origin/cuda.tar.gz -o cuda.tar.gz     # your script, unchanged
   └─ curlfromcache shim ─ FROMCACHE_SERVER set?
        ├─ cached  → served from the cache-host (fast, local)
        └─ miss/unset/unreachable → runs the real curl, exactly as written

Artifacts are cached by their origin URL as a key; the shim opts in by re-pointing the URL at the cache. No transparent proxy, no TLS interception, no client CA. The URL is a lookup key, not a connection target.

Misses are not fetched automatically. An operator reviews the miss list in a small web UI and presses Download (or pre-seeds via Add from URI); only then does the cache-host pull from origin. So the cache-host is the only box that needs internet egress (and any vendor credentials), and clients never write to it.

Why not just curl + a caching proxy?

For https:// (i.e. every vendor download) a forward proxy can't cache without SSL-bump / MITM: curl tunnels TLS end-to-end via CONNECT, so the proxy only sees ciphertext. The shim sidesteps that entirely by re-pointing the URL to the cache instead of intercepting the connection. And no proxy offers the operator-curated model (a miss queue a human approves).

Components

Path What it is
src/fromcache/server.py The cache-host: blob store + miss table + background download manager + operator UI (Pico.css + HTMX)
src/fromcache/_shim.py Shared shim core (find URL → probe → rewrite → exec)
src/fromcache/curlfromcache.py / wgetfromcache.py The Python curl / wget shims
shim/shim.zig The native shim: one static binary, both tools via argv[0]
deploy/Containerfile, deploy/compose.yml Single Podman/Docker host deploy

The cache-host and the Python shims are stdlib-only (no third-party runtime deps); the native shim is a dependency-free static binary.

Install

The cache-host and Python shims (works on any box with Python):

pipx install fromcache    # or: uv tool install fromcache  /  pip install fromcache
# provides: curlfromcache  wgetfromcache  fromcache-server

The native shim (no Python needed, for minimal/distroless boxes; ~200 KB static musl binary). Grab it from the Releases page; one binary serves both tools by the name it's invoked as:

curl -L .../releases/.../fromcache-shim-x86_64-linux-musl -o /usr/local/bin/curlfromcache
chmod +x /usr/local/bin/curlfromcache

The Python shim is also the tested oracle and install-time fallback for platforms without a prebuilt binary; a differential test asserts the binary and the Python plan() rewrite argv identically.

Deploy the cache-host

export FROMCACHE_ADMIN_PASSWORD=change-me    # protects the operator UI
podman compose -f deploy/compose.yml up -d   # or: docker compose -f ...
# operator UI:  http://fromcache-server:3000/

Or without containers:

FROMCACHE_ADMIN_PASSWORD=change-me fromcache-server --data-dir ./data --port 3000

Data (blobs + cache.db + session-secret) lives in the /data volume (or --data-dir). Artifacts are immutable per version, so there's no cache invalidation. --workers N sets the number of concurrent download workers.

Use the shims (transparent curl / wget)

Every approach is the same two ingredients: (1) point at the cache with FROMCACHE_SERVER, and (2) make curl/wget resolve to the shim. They differ only in how widely the system curl/wget is shadowed. Pick the least invasive one that fits.

Safety: with FROMCACHE_SERVER unset the shim is a pure pass-through (it just execs the real tool, zero network/parsing), so even the system-wide setup is harmless wherever the cache isn't configured. Worst case is always "no caching, curl still works."

These all use command -v curlfromcache, so they work whether you installed the native binary or the Python launcher (both land under that name).

1. No shadowing: call the shims by name (least invasive)

Nothing is renamed; you opt in per command. Good for trying it out or a script you can edit.

export FROMCACHE_SERVER=http://fromcache-server:3000
curlfromcache -fsSL https://the/origin/cuda.tar.gz -o cuda.tar.gz
wgetfromcache https://the/origin/rocm.tar.gz

2. This shell only: shadow curl/wget for the session

Put curl/wget symlinks in a dir and prepend it to PATH in the current shell. Reversible by just closing the shell.

mkdir -p ~/.fromcache/bin
ln -sf "$(command -v curlfromcache)" ~/.fromcache/bin/curl
ln -sf "$(command -v wgetfromcache)" ~/.fromcache/bin/wget

export FROMCACHE_SERVER=http://fromcache-server:3000
export PATH="$HOME/.fromcache/bin:$PATH"
hash -r                       # forget any cached curl/wget location

command -v curl               # -> ~/.fromcache/bin/curl  (verify it's the shim)
curl -fsSL https://the/origin/cuda.tar.gz -o cuda.tar.gz   # existing scripts, unchanged
wget https://the/origin/rocm.tar.gz                        # still saved as rocm.tar.gz

3. Your user: make it the default for your shells (persistent)

Create the symlinks once, then add the two exports to your shell rc. Affects all your future interactive shells; undo by deleting the block.

mkdir -p ~/.fromcache/bin
ln -sf "$(command -v curlfromcache)" ~/.fromcache/bin/curl
ln -sf "$(command -v wgetfromcache)" ~/.fromcache/bin/wget

cat >> ~/.bashrc <<'EOF'

# fromcache: transparent curl/wget caching
export FROMCACHE_SERVER=http://fromcache-server:3000
export PATH="$HOME/.fromcache/bin:$PATH"
EOF

4. One project only: scope it with direnv

Drop an .envrc in a project tree (requires direnv); caching applies only inside that directory.

# .envrc
export FROMCACHE_SERVER=http://fromcache-server:3000
PATH_add ~/.fromcache/bin        # assumes the symlinks from approach 2/3 exist

Then direnv allow.

5. The whole machine: every user, every shell (most invasive)

Install the shim as curl/wget in /usr/local/bin (ahead of /usr/bin on the default PATH) and set the server globally. This also catches build tools and package managers that shell out to curl/wget.

sudo ln -sf "$(command -v curlfromcache)" /usr/local/bin/curl
sudo ln -sf "$(command -v wgetfromcache)" /usr/local/bin/wget

# A login-shell env file (covers interactive logins; daemons started outside a
# login shell won't see it; set FROMCACHE_SERVER in their unit if you need it).
echo 'export FROMCACHE_SERVER=http://fromcache-server:3000' \
  | sudo tee /etc/profile.d/fromcache.sh >/dev/null

On minimal/distroless hosts use the native shim binary here: same symlink, no Python required.

Verify / turn it off

command -v curl                       # which curl is in effect (the shim, or the real one)
export REAL_CURL=/usr/bin/curl        # optional: pin the wrapped tool (also $REAL_WGET)

unset FROMCACHE_SERVER                 # instantly back to plain curl (pass-through)
rm ~/.fromcache/bin/curl ~/.fromcache/bin/wget   # remove shadowing entirely

How it works: the shim scans for the URL, asks the cache, and execs the real tool:

  1. Find the real curl/wget on $PATH (skipping itself; $REAL_CURL/$REAL_WGET override).
  2. With FROMCACHE_SERVER set, find the URL (the scheme:// arg, or --url).
  3. Probe the cache with that same tool (curl -I / wget --spider).
    • Hit → re-point only the URL at http://server/b/<base64(origin)>/<basename> and exec the real tool (so -o, -O, -L, --retry, … all still apply, and the file is named after the artifact).
    • Miss / unreachable → exec the real tool with your arguments untouched (origin); the miss is recorded for the operator.
  4. With no FROMCACHE_SERVER, it does zero network/parsing, just execs the real tool.

Notes & limits (all degrade gracefully; worst case is "no caching, curl still works"):

  • Needs the wrapped tool present (it shims it). Adds ~Python-startup latency per call.
  • URLs hidden in a -K/-i config file or piped via stdin aren't seen → those calls pass through uncached.
  • Per-tool env override: CURLFROMCACHE_SERVER / WGETFROMCACHE_SERVER beat FROMCACHE_SERVER.

Operator UI

http://fromcache-server:3000/ (Pico.css + HTMX, bundled offline) shows:

  • Misses: each with Download (queues a background pull) and Dismiss.
  • Downloads: live progress bars, queued/running/completed/cancelled/failed, Cancel, and Clear finished. Downloads run in a background worker pool, not in the request, so large pulls never block, modelled on bty's job managers.
  • Cached artifacts: URL, size, hits (times served) and misses (times requested before it was cached), SHA-256, fetched-at.
  • Add from URI: pre-seed an artifact before anyone misses it.

Auth

Single-tenant session-cookie auth (modelled on bty's approach, env password instead of PAM). The read path (/blob, /b/…, /healthz) is open so shims never log in; the operator surface (/, /admin/*) is gated.

Env var Purpose
FROMCACHE_SERVER Cache-host URL the shims use
CURLFROMCACHE_SERVER / WGETFROMCACHE_SERVER Per-tool override of the above
FROMCACHE_ADMIN_PASSWORD Operator login password (unset ⇒ UI open, with a warning)
FROMCACHE_SESSION_SECRET Override the persisted cookie-signing key (optional)

Cache keys & signed URLs

The key is scheme://host/path with the query string dropped by default, so CDN/presigned URLs (whose tokens change every request) still match by path. Pass --keep-query to the server for query-sensitive keys. Package-manager repos (.deb/.rpm) are GPG-signed and verified by the client regardless of transport, so caching them this way is safe.

Tests

python -m unittest discover -s tests   # stdlib only, no test deps

Metadata

Release files for fromcache 0.1.0

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

Source distribution (sdist)

Source distribution for fromcache 0.1.0
File Size Uploaded
fromcache-0.1.0.tar.gz 58.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for fromcache 0.1.0
File
fromcache-0.1.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
fromcache-0.1.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details
fromcache-0.1.0-py3-none-manylinux_2_17_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
fromcache-0.1.0-py3-none-manylinux_2_17_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
fromcache-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.1 MB

Release files / fromcache-0.1.0.tar.gz

Download URL fromcache-0.1.0.tar.gz
Size 58.4 kB
Tags Source
SHA-256 checksum
How to use checksums
75eb25c672ae28e3e20ae7af4eb8853c6ef08d4f4789b0c2bac35510d45117ee
BLAKE2b-256 checksum
How to use checksums
e44375b793489293aeb49a8ad9260a6e98b3af1da3f00c19976a39dcaba46d67
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 3, 2026.

Transparency log

Release files / fromcache-0.1.0-py3-none-musllinux_1_2_x86_64.whl

Download URL fromcache-0.1.0-py3-none-musllinux_1_2_x86_64.whl
Size 244.6 kB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
c4cd83aaa7b21d483c646e8c83a396ab2a1e33b2acca53e6b593f579b3907ad1
BLAKE2b-256 checksum
How to use checksums
928da105b0380ab73ef65d0bbc680e6143c3324b54b54f51fbda8a9ec1f32d62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 3, 2026.

Transparency log

Release files / fromcache-0.1.0-py3-none-musllinux_1_2_aarch64.whl

Download URL fromcache-0.1.0-py3-none-musllinux_1_2_aarch64.whl
Size 262.3 kB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
a160a33557c08741ca649d3bf71d5f6280969721bb586be426865570c1142b21
BLAKE2b-256 checksum
How to use checksums
96caede75c6963951d755c34272672527794ea31f68ed7a8458900e809eef187
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 3, 2026.

Transparency log

Release files / fromcache-0.1.0-py3-none-manylinux_2_17_x86_64.whl

Download URL fromcache-0.1.0-py3-none-manylinux_2_17_x86_64.whl
Size 244.6 kB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
1e673c07cb1e218dc8618730367525b8f65ca5766204aeb7d5721ea7f52af25c
BLAKE2b-256 checksum
How to use checksums
56d071dcd03d77f0f06403f36d7b9f132f8e1b23bb3d4c5a1beb8ad377fa213e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 3, 2026.

Transparency log

Release files / fromcache-0.1.0-py3-none-manylinux_2_17_aarch64.whl

Download URL fromcache-0.1.0-py3-none-manylinux_2_17_aarch64.whl
Size 262.3 kB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
b3d844448598e72519e0beba7922ac33cdb3ddae9ee8093a98f9e3e8c51aaa37
BLAKE2b-256 checksum
How to use checksums
73d2bf9eeb51d28eb4f200df35359afa09d99a073cbfa82462fe4453769d2b5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 3, 2026.

Transparency log

Release files / fromcache-0.1.0-py3-none-any.whl

Download URL fromcache-0.1.0-py3-none-any.whl
Size 50.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c37d859a3b5af4528bbb3aad8ff1862e1d91707ccb89443c27debdae3ab9dd27
BLAKE2b-256 checksum
How to use checksums
7f4bd28687e7219d60a5c0788465830cb98ff0f849a5194ba8396866addde338
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jun 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

6 release files

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