fdl
Versions of a DuckLake catalog on object storage, kept the way Git keeps commits.
FDL is a storage layout and a tool for it. Each version is a frozen catalog with a record of its parent, author and message; refs such as refs/heads/main say which version readers get. Data files are shared between versions and never rewritten. All it needs is a store that can read, write and write on condition: a folder, S3, R2 or anything S3-compatible. There is no server.
<root>/
fdl.json
HEAD ref: refs/heads/main
refs/heads/main 019a3c4e-…
versions/019a3c4e-…/
version.json parents, author, message, sha256
ducklake.duckdb the frozen catalog
data/main/towns/ducklake-….parquet
The documentation and the specification are at fdl.flo8s.com.
Quick start
pip install 'fdl-cli[s3]'
fdl init s3://my-bucket/towns/
fdl checkout s3://my-bucket/towns/ work/lake.sqlite
The package is fdl-cli on PyPI. It installs the fdl command and the fdl Python package (import fdl).
Write to the working catalog with DuckDB, attached the way checkout prints:
ATTACH 'ducklake:work/lake.sqlite' AS lake (
DATA_PATH 's3://my-bucket/towns/data/', OVERRIDE_DATA_PATH true,
META_TYPE 'sqlite', DATA_INLINING_ROW_LIMIT 0, META_JOURNAL_MODE 'WAL', BUSY_TIMEOUT 5000
);
CREATE TABLE lake.main.towns AS SELECT * FROM 'towns.csv';
Rows have to go to Parquet, not into the catalog (DATA_INLINING_ROW_LIMIT 0): a version is read over HTTP, and inlined rows would not be in it.
Then make a version and move main to it:
fdl commit work/lake.sqlite -m "First towns" --author alice
fdl log s3://my-bucket/towns/
Anyone who can read the bucket can attach it:
fdl url s3://my-bucket/towns/
ATTACH 'ducklake:s3://my-bucket/towns/versions/019a3c4e-…/ducklake.duckdb' AS towns (
DATA_PATH 's3://my-bucket/towns/data/', OVERRIDE_DATA_PATH true, READ_ONLY
);
Credentials and the endpoint come from boto3's usual places (AWS_* environment variables, AWS_ENDPOINT_URL for R2 and other S3-compatible stores). A folder works as a repository too: pass its path instead of an s3:// URL.
Commands
| Command | What it does |
|---|---|
fdl init <remote> |
Start a repository (fdl.json and HEAD) |
fdl checkout <remote> <working> |
Make a working catalog from the version main holds |
fdl commit <working> -m … --author … |
Freeze the working catalog into a version and push it |
fdl log <remote> |
List versions from main back to the first |
fdl url <remote> |
Print the catalog URL of the version main holds |
fdl expire <remote> --keep N |
Mark older versions as past retention and delete their catalogs |
A push that is not built on what main holds now is refused: check out again and redo the work.
Python
from fdl import repo
from fdl.stores import open_store
store = open_store("s3://my-bucket/towns/")
for version in repo.log(store):
print(version.seq, version.id, version.message)
fdl.repo has the operations without a terminal (init, checkout, commit, push, log, expire, prune), for tools and services that build on FDL.
Earlier releases
Releases up to 0.11 were a different tool for managing a single frozen catalog, published as frozen-ducklake. Their code is at the legacy branch.
License
MIT
Metadata
Release files for fdl-cli 0.14.1
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 | Actions |
|---|---|---|---|---|
| fdl_cli-0.14.1.tar.gz | 264.4 kB | With provenance | Details for fdl_cli-0.14.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| fdl_cli-0.14.1-py3-none-any.whl | Python 3 | none | any | Details for fdl_cli-0.14.1-py3-none-any.whl |
Total release size: 295.8 kB
Release files / fdl_cli-0.14.1.tar.gz
| Download URL | fdl_cli-0.14.1.tar.gz |
|---|---|
| Size | 264.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bb085dc7ee671b5eb633525f400523958950773f03832cb191cf08663c5ceec3
|
|
BLAKE2b-256 checksum How to use checksums |
c5e07019992ce0f3acecebc0cffcf61ce63b1e951f50f230c0fb6013ee99310a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 1, 2026.
Transparency logRelease files / fdl_cli-0.14.1-py3-none-any.whl
| Download URL | fdl_cli-0.14.1-py3-none-any.whl |
|---|---|
| Size | 31.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e15519bec327f1b3fcc4d73249f5f0e6d0c1d5937f7abd5ecfc80da64abca5fc
|
|
BLAKE2b-256 checksum How to use checksums |
d06a8c4f36e1fb4f2fb4e3eaf6e2c07158b1253cddaab61a5bbaf08146b610ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Nov 1, 2026.
Transparency logSecurity for fdl-cli 0.14.1
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 fdl_cli-0.14.1.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 Nov 1, 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.