Skip to main content

flat-adapter

flat-adapter converts nested mappings into deterministic flat rows suitable for database imports and ETL pipelines.

Quick start

from flat_adapter import FlatAdapter


class ItemAdapter(FlatAdapter):
    item_id: int
    quantity: int


class OrderAdapter(FlatAdapter):
    order_id: int
    items: list[ItemAdapter]


rows = OrderAdapter.adapt(
    {
        "order_id": "1001",
        "items": [
            {"item_id": "10", "quantity": "2"},
            {"item_id": "20", "quantity": "1"},
        ],
    }
)

assert rows == [
    {"order_id": 1001, "item_id": 10, "quantity": 2},
    {"order_id": 1001, "item_id": 20, "quantity": 1},
]

The first release supports Mapping[str, object] input, nested mappings, typed scalar conversion, optional fields, aliases, custom Field paths, and deterministic Cartesian expansion of nested lists. adapt() returns list[dict[str, object]]; iter_adapt() returns an iterator over the same rows.

Field configuration

Use typing.Annotated to attach extraction metadata without a runtime assignment or a cast:

from typing import Annotated

from flat_adapter import Field, FlatAdapter


class CustomerAdapter(FlatAdapter):
    customer_id: Annotated[int, Field(source="payload.customer_id")]
    display_name: Annotated[str, Field(source="payload.name", default="Unknown")]

The legacy name: int = Field(...) form remains supported at runtime, but Annotated is the preferred form for mypy --strict projects.

Performance and row limits

Depth of seven to ten nested adapters is normally safe; the main cost comes from Cartesian expansion. For list lengths L1, L2, ..., the result count can grow as product(max(1, len(Li))). adapt() materializes all rows in memory, while iter_adapt() yields them lazily.

Use max_rows to fail fast before an expansion becomes too large. The limit works with both eager and lazy APIs:

rows = OrderAdapter.adapt(payload, max_rows=10_000)

For large results, consume rows lazily:

for row in OrderAdapter.iter_adapt(payload, max_rows=10_000):
    process(row)

Run the local benchmark scenarios with:

uv run python benchmarks/flatten_benchmark.py

Development

The project uses uv for environments, dependencies, and lockfile management.

uv sync
uv run pre-commit install
uv run pre-commit run --all-files
uv run pytest --cov=flat_adapter --cov-report=term-missing
uv run ruff check src tests
uv run mypy --strict src tests
uv build
uv run twine check dist/*

Package layout

src/flat_adapter/  Library package
tests/unit/        Pure behavior tests
docs/              English/Russian guides and promotion notes
benchmarks/        Manual performance scenarios

See CONTEXT.md for architecture boundaries and TECHDEBT.md for known risks.

Русская версия руководства: docs/README.ru.md. English guide: docs/README.en.md.

Versioning

Releases follow Semantic Versioning. While the package is below 1.0.0, a minor release may include a documented contract change; patch releases remain backward-compatible fixes. CHANGELOG.md records user-visible changes.

Metadata

Release files for flat-adapter 0.2.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 flat-adapter 0.2.0
File Size Uploaded
flat_adapter-0.2.0.tar.gz 90.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for flat-adapter 0.2.0
File Interpreter ABI Platform
flat_adapter-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 102.4 kB

Release files / flat_adapter-0.2.0.tar.gz

Download URL flat_adapter-0.2.0.tar.gz
Size 90.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2d082ba6c15ee17f544efb253aaefe8f71e0687e7fa1a5fecd73738dc00cffb4
BLAKE2b-256 checksum
How to use checksums
1c8f84cf7dd4dfcf51d03de1270e58eea1a7e56ad651471f585181a633a8312c
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 Aug 8, 2026.

Transparency log

Release files / flat_adapter-0.2.0-py3-none-any.whl

Download URL flat_adapter-0.2.0-py3-none-any.whl
Size 11.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b7dadbe0b78bfd28520ce3ee04b4c1f09a3a4635d9201055cbad09f86018a32d
BLAKE2b-256 checksum
How to use checksums
9c5ebcb860ae88b059e87b69a59fd817e4dc218cc821e396c1d58ef650ad6f6f
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 Aug 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 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