Skip to content
FDL
Esc
↑↓navigate↵open⌘Jpreview
On this page

Python API

The fdl package - stores, refs, and the repository operations without a terminal.

from fdl import repo, refs
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)
Module Holds
fdl.repo the operations: init, checkout, commit, push, log, expire, prune
fdl.refs reading and moving refs under their conditions
fdl.version Version, the record in version.json, and new IDs
fdl.catalog DuckLake catalogs in DuckDB and SQLite, and the copy between them
fdl.layout where each file of a repository sits
fdl.store, fdl.stores what a store has to do, and the folder and S3 stores

Stores

open_store(url) returns a folder store, an S3 store, or an HTTP store for a host that takes pushes over HTTP. Any object with these methods works in their place:

Method Does
put(key, data, *, content_type, if_match, if_none_match) Write and return the ETag. A failed condition raises an error whose status is 412
put_file(key, path, …) The same, from a file
get(key) Read. A missing object raises an error whose status is 404
head(key) The object’s headers (with ETag), or None
list(prefix) Keys under a prefix
delete(keys) Remove. A key already gone is not an error
put_files(files, *, content_type) Optional. Write (key, path) pairs that are written once. The HTTP store asks the host for upload URLs (batch) and sends the files straight to storage

fdl.repo

repo.init(store, *, data_dir="data/") -> Config

Start a repository. An existing one is left as it is and its settings returned.

repo.checkout(store, working, *, ref="HEAD") -> Version | None

Make a working catalog at working from the version ref holds. Returns that version, or None before the first one.

repo.commit(working, out_dir, *, parent, data_path, author, message, inputs=(), annotations=None, dataset=None) -> Version

Freeze the working catalog into out_dir/<ID>/, with dataset (the parsed dataset.json) checked against the catalog and completed from it. data_path is repo.data_url(store). Nothing is uploaded.

repo.record(frozen, out_dir, *, parent, author, message, inputs=(), annotations=None, dataset=None) -> Version

Make a version around a catalog that is already frozen, for a writer that freezes it itself.

repo.push(store, local, version, *, ref="refs/heads/main", move_ref=True) -> None

Upload a committed version, then move ref to it on condition. Raises NotFastForward when the ref moved, and RepoError when data files are missing. With move_ref=False it uploads and stops, for a host that moves refs itself.

repo.log(store, name="HEAD") -> Iterator[Version]
repo.head(store, name="HEAD") -> Version | None
repo.is_ancestor(store, ancestor_id, descendant) -> bool

Walk the first-parent line, read the version a ref holds, and check whether a version is behind another.

repo.readable(store, name="HEAD") -> Version

The version a ref holds, checked the way a reader must before opening its catalog. Raises RepoError before the first version, for a version.json of a format this does not read, and for a version past retention or withdrawn. fdl url uses it.

repo.expire(store, version_id, *, reason="retention") -> None
repo.prune(store, newest, *, keep=1, since=None, reason="retention") -> list[str]

Take one version out of retention, or every version behind newest that falls out of it. Versions a ref points at are kept.

repo.tag(store, name, version_id) -> None
repo.delete_tag(store, name) -> None
repo.tags(store) -> dict[str, str]

Create refs/tags/<name> at a version, delete it, or list the tags with the versions they hold. A tag is never moved: tag raises RepoError when the name is already there at another version.

repo.update_refs_index(store) -> None

Rewrite refs.json from the refs. push, tag and delete_tag call it after moving a ref. A 403 from a host that keeps refs.json itself is taken as done.

repo.plan_withdrawal(store, version_ids) -> Withdrawal
repo.withdraw(store, version_ids, *, plan=None) -> Withdrawal

Withdraw versions that hold data that must not be published. plan_withdrawal changes nothing and returns the tags, the data files to delete, and the files kept because a kept version reads them. withdraw deletes the tags, the data files and the catalogs, in that order. Both raise RepoError while a branch or a request points at one of the versions.

fdl.refs

refs.read(store, name) -> Ref | None
refs.write(store, name, version_id, *, expected) -> str

read returns the ref with the ETag a move has to name. write creates the ref when expected is None and moves it otherwise, and raises RefConflict when the condition fails.

refs.listed(store) -> dict[str, str]
refs.write_index(store) -> dict

listed reads every branch and tag afresh. write_index writes refs.json from them and HEAD.

Was this page helpful?