Skip to main content

flyfile

Agent-native data transfer. Push/pull anything (text, files, directories) through a central server, or stream it directly client-to-client. Built for AI agents: JSON output everywhere, stable exit codes, content-addressed dedup, burn-after-read.

pip install flyfile

# server (single worker; data lives in LMDB via flaxkv2)
flyfile serve --port 8632 --token SECRET

# client
export FLYFILE_SERVER=http://host:8632 FLYFILE_TOKEN=SECRET
echo "build log" | flyfile push - --name buildlog --tag ci --ttl 2h
flyfile push ./model.bin --reads 1            # burn after one read
flyfile push ./dataset/                       # dirs stream as tar, no temp files
flyfile push ./release.tar --keep             # objects expire in 7d unless --keep
flyfile ls --tag ci --json                    # → {"total": N, "items": [...]}
flyfile rm --until 30d --dry-run              # bulk delete by filters, preview first
flyfile preview k3x9m2pq                      # peek without consuming reads
flyfile pull k3x9m2pq -o ./model.bin

# client → client (server relays the stream, nothing is stored)
flyfile send ./results/          # prints: code: amber-falcon
flyfile recv amber-falcon        # on the other machine

Agent contract

  • JSON everywhere: --json, or automatic when stdout is not a TTY. Progress goes to stderr, data to stdout. Never prompts.
  • Exit codes (stable): 0 ok · 2 usage · 3 not found · 4 auth · 5 conflict · 6 expired/burned · 7 network (retryable) · 1 other.
  • Errors are JSON on stderr: {"error", "message", "retryable", "suggestion"}.
  • Idempotent push: content-addressed (sha256). Re-pushing the same bytes is instant ("deduped": true).
  • Default retention is 7 days, enforced server-side (so the HTTP API and the Python client behave the same). --ttl adjusts it; --keep stores forever.
  • flyfile preview <id> reads the head of an object (or a dir's file manifest) without downloading and without consuming burn-after-read counts. Because it does not consume a read, the response is capped at 64 KiB and sets truncated when it clips.
  • flyfile schema [cmd] dumps the command tree as JSON for introspection.
  • flyfile send --json emits NDJSON events; the code event arrives before the transfer starts, so an agent can hand it to the receiver immediately.

Breaking changes in 0.3.0

  • The on-disk format changed and is not backward compatible. Chunks are now namespaced by upload rather than by content hash, which is what makes concurrent uploads of the same content safe and makes abandoned chunks reclaimable. A server started against a 0.2.x data directory fails at startup with instructions rather than corrupting or silently leaking data. To upgrade: pull anything you still need with 0.2.x, then delete the data directory (default ~/.local/share/flyfile).
  • GET /objects/{id}/chunks/{idx} for idx > 0 now requires the x-ff-lease header issued with chunk 0. Previously any caller could fetch later chunks without claiming a read, which made --reads 1 meaningless for multi-chunk objects. The bundled client handles this transparently; custom clients that fetch chunks directly must pass the lease through.

Breaking changes in 0.2.0

  • GET /objects (and FlyfileClient.ls()) now returns {"total": N, "items": [...]} instead of a bare list, so a paged query can report how many objects matched. flyfile ls --json changes shape accordingly. Upgrade server and clients together.
  • Uploads without an explicit TTL now expire after 7 days instead of being kept forever. Pass --keep (CLI) or ttl=0 (client/x-ff-ttl: 0) for the old behavior.

Design notes

  • Storage is flaxkv2 (LMDB): metadata and 8 MiB content chunks in one env. The LMDB file does not shrink after deletes (free pages are reused; file size ≈ historical peak).
  • Compression (zstd-3) happens on the client; the server stores/relays compressed bytes. Each 8 MiB chunk of a large upload is an independent zstd frame, so parallel upload, resume, and parallel download all work per-chunk.
  • Burn-after-read: the read is claimed atomically when chunk 0 (or /content) is fetched. That claim issues a short-lived lease (x-ff-lease, default 5 min) which an in-flight parallel download presents to fetch the remaining chunks, so a burnt object stays unreadable to everyone else while the legitimate download finishes. A sweeper grace period (default 15 min) keeps the chunks around for the life of the lease.
  • Every chunk belongs to exactly one owner at all times — an upload ledger entry or a blob record — and ownership moves in a single transaction. That invariant is what makes crashes, aborted uploads, and concurrent uploads of the same content unable to strand or clobber data. See docs/architecture.md.
  • Run exactly one uvicorn worker: relay pairing and the burn-claim lock are in-process.

Development

uv venv && uv pip install -e ".[dev]"
.venv/bin/pytest
scripts/bench.sh   # 1 GiB loopback throughput smoke test

Download files

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

Source Distribution

flyfile-0.3.0.tar.gz (56.1 kB view details)

Uploaded Source

Built Distribution

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

flyfile-0.3.0-py3-none-any.whl (42.9 kB view details)

Uploaded Python 3

File details

Details for the file flyfile-0.3.0.tar.gz.

File metadata

  • Download URL: flyfile-0.3.0.tar.gz
  • Upload date:
  • Size: 56.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for flyfile-0.3.0.tar.gz
Algorithm Hash digest
SHA256 b9e14f70b499dbe6758bb8b9731bc89bba9ae96725477445316a120254eabe7e
MD5 68b70b10574b1142a34c86230c5d5ddd
BLAKE2b-256 ef2e3a0fbe08689aa78dfd950a55b11f0b18124cfab898c24ab1fa964e97385e

See more details on using hashes here.

Provenance

The following attestation bundles were made for flyfile-0.3.0.tar.gz:

Publisher: python-publish.yml on KenyonY/flyfile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flyfile-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: flyfile-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 42.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for flyfile-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 266272e74756380634ff10e7dc17acdae3a72fa628e69d4d895c516504cf13fd
MD5 15d07f8f7bd6bc1b771e167eef8a43af
BLAKE2b-256 86c3f625ab0fa07108e4b6ffd90a7bf005c9fac61f2e2eb6b26a5b7ca3f7fc81

See more details on using hashes here.

Provenance

The following attestation bundles were made for flyfile-0.3.0-py3-none-any.whl:

Publisher: python-publish.yml on KenyonY/flyfile

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.4.0

2 files

This release

0.3.0 This release

2 files

0.1.0

2 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