Skip to main content

ffl-python

ffl-python is the Python binding for the FastFileLink CLI (FFL), which turns a file, folder, or stream into a browser-ready HTTPS link so the recipient can download it without installing anything. It prefers a direct QUIC/WebRTC P2P connection and falls back to a relayed/tunneled HTTPS link, with optional end-to-end encryption. See the FFL repository for the full protocol and CLI details.

The package bundles the portable ffl.com APE and runs it behind a Python API, powered by APEBind, so callers do not need to locate or install a separate FFL

Installation

pip install ffl-python

This installs the ffl package with the bundled ffl.com APE included -- no separate FFL install or PATH setup required.

Development

python -m venv .venv
.venv/Scripts/python -m pip install -e ".[dev]"   # Windows
# or: .venv/bin/python -m pip install -e ".[dev]"

.\scripts\test.ps1                 # Windows
# or: ./scripts/test.sh              # Linux/macOS

.\scripts\build.ps1                # Windows
# or: ./scripts/build.sh             # Linux/macOS

Share

import ffl

with ffl.share("release.zip", max_downloads=1, timeout_seconds=1800) as session:
    print(session.link)

share() always requests a foreground FFL process and disables clipboard side effects, which gives library callers a deterministic ShareSession they can stop or keep alive. FFL's runtime-owned --json output is used internally to wait until session.link is ready.

Multiple files are accepted directly:

session = ffl.share(["one.txt", "two.txt"], name="files.zip")

Text and bytes helpers own their temporary file until the share session is closed:

with ffl.share_text("hello", name="hello.txt") as session:
    print(session.link)

Stream a source without a temporary file

share_stream() passes a binary file-like object directly to FFL stdin. It is useful for database dumps, generated artifacts, and other data that should not first be materialized as a separate temporary file:

with open("backup.tar", "rb") as source:
    with ffl.share_stream(source, name="backup.tar") as session:
        print(session.link)

Events

session.on(name, listener) follows FFL's integrated events:

Semantic name FFL event
ready /share/available
started /transfer/create
progress /transfer/progress
completed /transfer/complete
failed /transfer/fail

HTTP, WebRTC, and direct P2P also emit their own events, such as /download/complete. Those stay on session.on_raw(). completed follows /transfer/complete, so one transfer notifies that listener once. Each accepted hook POST is answered with HTTP 200 and {}.

The bundled ffl.com emits these names.

Download

result = ffl.download("https://example.fastfilelink/...", output_path="download.bin")
print(result.output_path)
print(result.transfer_mode)

download() waits for the foreground FFL process to finish and returns a DownloadResult. For cancellation, progress, or caller-controlled timeouts, use start_download() and manage its DownloadSession explicitly.

Stream a download

download_stream() exposes FFL stdout as binary chunks without buffering the whole file in memory:

with ffl.download_stream("https://example.fastfilelink/...") as transfer:
    with open("output.bin", "wb") as target:
        for chunk in transfer.iter_bytes():
            target.write(chunk)

    result = transfer.wait()

Consume iter_bytes() through EOF before calling wait(). Calling wait() with unconsumed streamed stdout raises RuntimeError; this avoids silently discarding binary data or deadlocking when the child process fills its stdout pipe.

Authentication secrets

For shares protected with HTTP Basic Auth, FFL supports FFL_AUTH_PASSWORD. Set it in the application environment and pass only auth_user to keep the password out of the FFL command line:

export FFL_AUTH_PASSWORD='use-your-secret-manager'
$env:FFL_AUTH_PASSWORD = 'use-your-secret-manager'
with ffl.share("release.zip", auth_user="deploy") as session:
    print(session.link)

Do not also pass auth_password= when using this pattern: FFL gives the explicit CLI option precedence over FFL_AUTH_PASSWORD. The environment variable applies to the sharing side; pass download credentials explicitly when downloading a protected link.

Key generation

result = ffl.keygen("alice")
print(result.public_key_path)
print(result.private_key_path)

Version and raw access

print(ffl.version())
result = ffl.raw(["download", "--help"])

raw() is the escape hatch for new FFL options or commands that the semantic API has not adopted yet.

Compared to magic-wormhole

magic-wormhole is the other Python tool commonly reached for to move a file between two machines. Both are ad hoc, non-account-based transfers you can drive from Python, but they differ in shape:

  • Binding vs. native library. ffl-python is a subprocess wrapper around the separate ffl.com CLI binary -- WebRTC/QUIC, NAT traversal, and relay/tunnel fallback all happen in that external process. wormhole is a native, in-process Python package (Twisted-based); no external binary is involved. In practice, though, wormhole's own file-transfer path is also driven through its CLI machinery rather than a stable public library call -- wormhole.create() covers generic message exchange, not file transfer directly.
  • Recipient experience. An FFL share is an HTTPS link: the recipient opens it in a browser and downloads, no install required. A wormhole transfer is a short code (e.g. 7-crossbow-clockwork) exchanged out-of-band; the recipient needs the wormhole CLI installed to redeem it.
  • Transport. FFL tries a direct WebRTC/QUIC P2P connection first, falls back to a plain P2P TCP connection, and falls back again to a relayed/tunneled HTTPS link if no P2P path is reachable at all. wormhole's own transit protocol does direct TCP with a relay fallback, with the connection authenticated by a SPAKE2 PAKE key derived from the code.
  • Security default. wormhole is end-to-end encrypted on every transfer by construction of the code exchange. FFL's end-to-end encryption is opt-in (--e2ee); without it, data in transit is only as protected as the HTTPS connection to FFL's relay/tunnel infrastructure.
  • Feature surface. FFL adds application-layer conveniences wormhole doesn't have: a secondary pickup-code/public-key recipient check layered on top of the link, receipt-confirmation emails, a pluggable choice of tunnel backend when P2P isn't reachable (built-in default, plus Cloudflare, ngrok, Localtunnel, Loophole, Dev Tunnel, Bore, or a self-hosted sish tunnel via --preferred-tunnel, with custom tunnels configurable in ~/.fastfilelink/tunnels.json), and general SOCKS5/HTTP proxy configuration (wormhole only knows how to route through Tor, via --tor).

Metadata

Release files for ffl-python 0.1.5

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

Source distribution (sdist)

Source distribution for ffl-python 0.1.5
File Size Uploaded Provenance
ffl_python-0.1.5.tar.gz 24.5 MB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ffl-python 0.1.5
File Interpreter ABI Platform
ffl_python-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 49.1 MB

Release files / ffl_python-0.1.5.tar.gz

Download URL ffl_python-0.1.5.tar.gz
Size 24.5 MB
Tags Source
SHA-256 checksum
How to use checksums
bade3ad3a9407dc3632c74296331ffe90f5f433e391e43006896372c90633783
BLAKE2b-256 checksum
How to use checksums
94568e301f27f3eb598ac3fce631f8d1d73e1ab29dddea3431bf8e62a7eecca5
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 6, 2026.

Transparency log

Release files / ffl_python-0.1.5-py3-none-any.whl

Download URL ffl_python-0.1.5-py3-none-any.whl
Size 24.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
63a4d82eebb72101dd8af6dd40ac50b14d3477c2f2f1074feb797b36ce1a469c
BLAKE2b-256 checksum
How to use checksums
26ccbb15dac7ec3075be8454ba95ac7fd6be65be61396dcef58dd9f53ec74a42
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 6, 2026.

Transparency log

Security for ffl-python 0.1.5

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.

Select from 2 files

Attestation for ffl_python-0.1.5.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 6, 2026.

Transparency log

A 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.

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