Skip to main content

fdu (Python)

Python bindings for fdu, a fast, incremental file roll-up engine.

Install

uvx fdu@latest .      # run the latest release once, without installing it
uv tool install fdu   # put the fdu command on your PATH; uv tool upgrade fdu updates it
uv add fdu            # use the library in a uv project
pip install fdu       # or install the library with pip

uvx fdu@<version> --help runs one exact release. For coding agents, fdu --install-skill writes the agent skill under the project root and fdu --skill prints it; the repository README has the details. Prebuilt abi3 wheels cover GIL-enabled CPython 3.12 and newer on Linux glibc (x86-64 and arm64), macOS (x86-64 and arm64), and Windows x86-64, so installing needs no Rust toolchain. Free-threaded CPython, such as 3.14t, cannot install them and is not supported; an installer there falls back to building the source distribution. If uv selects a free-threaded interpreter, pass --python 3.14 (or --python 3.12), as in uv tool install --python 3.14 fdu.

Use

The public package is fdu; fdu._native is private build machinery. The supported API includes typed query and scan options, immutable report sections, roll-ups, per-path provenance, cache management, refresh results, and change feeds. .gitignore is read by default: tree, summary, extension, and file rows carry their ignored share, Selection(ignored=...) selects one side, and Status.ignore_rules names any file the limits refused. ScanOptions carries the switch (read_controls) and both limits (control_budget, control_line_limit). Cache status is typed as CacheState, with StaleReason and LeftoverKind, and clear_all_caches returns a ClearSummary. Filesystem failures that prevent an operation from starting remain exceptions. Errors that make a scan partial remain structured data on Status, so callers can use the covered result without losing the reason it is incomplete. The roll-up adapter example shows one scan serving several application-owned summaries without parsing terminal output or adopting fdu’s machine schema as the application’s internal model.

from pathlib import Path

import fdu

index = fdu.open(
    Path("/path/to/tree"),
    cache=fdu.CachePolicy.AUTO,
    scan=fdu.ScanOptions(one_filesystem=True),
    analysis=fdu.AnalysisOptions(analyze=fdu.Analysis.ALL),
)
print(index.status.complete)
print(index.total().by_extension)

report = index.report(
    fdu.Query(
        views=(fdu.View.TYPES, fdu.View.FAMILIES, fdu.View.DOCUMENTS),
        selection=fdu.Selection(limit=20, size=fdu.SizeMetric.APPARENT),
    )
)
print(report.provenance.freshness)
print(report.sections)
print(report.as_dict())

mark = index.clock
result = index.refresh()
print(result.status, index.since(mark).changes)

Every method is bulk: it returns a whole structured result in one call rather than a cursor Python iterates. Open, scan, and the native reconciliation phase of refresh run with the GIL released, so unrelated Python threads and independent indexes can progress. Content analysis streams every eligible file through EOF. Binary data, invalid UTF-8, and unsupported SLOC languages remain visible as coverage without making the operation partial; I/O failures and files changed during a read remain operational errors. One Index object still has PyO3 runtime borrow exclusion: an overlapping call on that same object is rejected rather than becoming an unsynchronized shared-index access. The wheel enables the optional watch dependency and exposes Index.watch() as a closable, event-driven change feed. Content analysis itself remains one-shot: refresh reanalyzes after metadata reconciliation, while a watch feed reports metadata changes.

Analysis names the same analyzers as the command line’s --analyze: lines, code, and words, with none and all as totals. AnalysisOptions takes one of them or a comma-separated set such as "code,words", plus a worker count. Typed report sections expose stable type/family groups, exact share fractions, line and word slots, page denominators, coverage outcomes, analyzer provenance, detection source and confidence, and generated/vendor/documentation flags. The original extension grouping remains available as the extensions view. The package supports Python 3.12 and newer and builds one abi3-py312 extension rather than separate native payloads for every Python minor release.

Directory Inventories and Formats

A default Query() keeps the existing directory tree. Select a flat presentation when requesting a report, so an ordinary tree need not materialize a complete inventory:

from pathlib import Path

import fdu

index = fdu.open(Path("/path/to/tree"))
for name in (".venv", "venv", "node_modules", "target"):
    report = index.report(
        fdu.Query(
            format=fdu.Format.LONG,
            selection=fdu.Selection(
                kinds=(fdu.EntryKind.DIR,),
                include=(name,),
                modified_before="30d",
                sort=fdu.SortKey.MTIME,
                reverse=True,
            ),
        )
    )
    print(report.render())
    print(report.render(fdu.Format.JSON))

All four reads use one retained index without rescanning. View.LIST is the metadata default. Format.TREE explicitly requests the current tree; PATHS lists matching paths, LONG adds size and signed modification age, and JSON/JSONL/YAML carry exact metrics. TEXT selects automatic human presentation. Legacy View.FILES keeps flat name ordering, and View.TREE preserves structured directory output. Largest/recent remain regular-file presets, with optional Paths/Long output.

Directory FileRow values carry subtree bytes, allocated, files, dirs, complete, mtime_ns, and age_ns; non-directory counts are None. A directory whose subtree was not listed in full has complete=False, lower-bound sizes, and age_ns=None. The fixed Report.age_reference_ns explains age, including negative future ages and pre-epoch mtime. An unrepresentable reference yields None age. Exclusions win throughout the subtree; nested roots may overlap, while grouped totals count their union once. Age describes modification, not access or last use. Native entry/lookup projections retain inode attributes; these report rows deliberately carry subtree metrics instead.

A Report owns its requested projection. Re-render it to another serialization or between Paths and Long without querying again; request another report to change between a bounded tree and complete flat inventory. An incompatible conversion raises InvalidArgumentError rather than silently listing only visible tree rows. Tree limits remain per-directory, flat limits apply to the whole list, and machine List output is complete unless explicitly limited. Details and exact fields are in the usage guide and machine-output reference.

Long-lived roots

fdu.opened is the direct typed interface to the long-lived engine. It starts progressive discovery, returns several projections from one coherent version, exposes exact resumable changes, verifies explicit path sets, accepts discovery priorities, and joins all native work on close:

from pathlib import Path

from fdu import opened

with opened.OpenedIndex.open(Path("."), opened.OpenedOptions(observe=True)) as index:
    answer = index.read(
        opened.Tree(page=opened.Page(limit=200, max_work=100_000)),
        opened.Diagnostics(),
    )
    cursor = answer.change_cursor
    changed = index.changes(cursor, timeout=1.0)

The methods are synchronous and release the GIL during native work. An async application adapts them with its own executor policy, keeping task and shutdown ownership visible. The package does not run a private event loop or shell out to the command line.

The wheel also exposes the native Rust CLI as the fdu console script. Argument parsing, help, streams, color, errors, broken-pipe handling, and exit status all use the same Rust process boundary as the Cargo-installed binary; there is no Python CLI reimplementation.

Status: 0.x. A new minor release may change the Python API; the release process states the compatibility rules. Building and testing the package from a checkout is covered in the repository README.

License: MIT.

Release files for fdu 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 fdu 0.1.0
File Size Uploaded
fdu-0.1.0.tar.gz 990.2 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for fdu 0.1.0
File
fdu-0.1.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
fdu-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 abi3 Linux glibc 2.17+ x86-64 Details
fdu-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.12 abi3 Linux glibc 2.17+ ARM64 Details
fdu-0.1.0-cp312-abi3-macosx_11_0_x86_64.whl CPython 3.12 abi3 macOS 11.0+ x86-64 Details
fdu-0.1.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details

Total release size: 10.6 MB

Release files / fdu-0.1.0.tar.gz

Download URL fdu-0.1.0.tar.gz
Size 990.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b31c14b34776adc266de8797d97c1f9c358b22190029e4d618f041c68979453e
BLAKE2b-256 checksum
How to use checksums
df49ebc1fd0fbc4163e1d12d7756135e9c49badacb4de72cfe326b2c4f24751e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fdu-0.1.0-cp312-abi3-win_amd64.whl

Download URL fdu-0.1.0-cp312-abi3-win_amd64.whl
Size 2.1 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
43311ffcafcd52680b2ce4b946fe728e1d4976f035ddfb37ab122c59a8ff4b9c
BLAKE2b-256 checksum
How to use checksums
7684065e5482810c97339f9c59e74ac9f0cd2e789dc0fc80b9e3944b18b65f33
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fdu-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL fdu-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.0 MB
Tags CPython 3.12 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
6dd83f9868d6e1cc877205a2b7abf5bebd874c3f776388693d839de002f0d5b4
BLAKE2b-256 checksum
How to use checksums
1e18e0eab9775383d4713721862373fd9043c291e2bd0e007464ceba91e289a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fdu-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL fdu-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 1.9 MB
Tags CPython 3.12 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
b5e56f40682be6c9642057423cd55e7265d701dbd161354079319f4478300f4b
BLAKE2b-256 checksum
How to use checksums
d37ed3226f5e5173ab5d9c204218d7d26774b3e3431fedb4bd64eaaac4e9d6dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fdu-0.1.0-cp312-abi3-macosx_11_0_x86_64.whl

Download URL fdu-0.1.0-cp312-abi3-macosx_11_0_x86_64.whl
Size 1.9 MB
Tags CPython 3.12 abi3 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
6b3021e8270310d533a9fd790c15aafc9327e5405ad4d448188527f9b16a9fdd
BLAKE2b-256 checksum
How to use checksums
728a9e98ebcd47a1c0a8785fc29b7e6eee1890589249270fdf4eb9840c7f40d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fdu-0.1.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL fdu-0.1.0-cp312-abi3-macosx_11_0_arm64.whl
Size 1.8 MB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
2f3052e7f29908dda1268e42e1127983b80d40346b325b13b371b0390629af78
BLAKE2b-256 checksum
How to use checksums
3e6181856f41d6bda347c7a89f7925e60e42136dc8361eb1a49d5023ad43ea16
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

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