Skip to main content

genro-bag

0.28.0 — breaking API: read the ingestion and scheduling migration note before upgrading dependent projects.

PyPI version Tests codecov Documentation Python 3.10+ License

An Intermediate Representation for Structured Data

A Bag is an intermediate representation (IR) for hierarchical data in Python.

What is an Intermediate Representation?

In compiler design, an IR is a data structure that sits between source code and machine code. It captures the essential structure while abstracting away format-specific details, making it easier to analyze, transform, and generate output.

The same principle applies to data: configuration files, API responses, documents, and UI structures all share a common shape—named things containing values, organized hierarchically, with metadata attached—but we typically scatter this across dictionaries, classes, JSON, XML, and database rows.

A Bag provides a canonical representation for this common pattern:

flowchart LR
    subgraph Sources
        JSON[JSON file]
        XML[XML file]
        API[API response]
        DB[Database]
        Input[User input]
    end

    subgraph BAG[" "]
        Tree["Unified tree<br/>of named nodes"]
    end

    subgraph Outputs
        HTML[HTML]
        XMLout[XML]
        DBout[Database]
        JSONout[JSON]
        UI[UI]
    end

    JSON --> Tree
    XML --> Tree
    API --> Tree
    DB --> Tree
    Input --> Tree

    Tree --> HTML
    Tree --> XMLout
    Tree --> DBout
    Tree --> JSONout
    Tree --> UI

Why an IR?

Decoupling: Your application logic works with one structure, regardless of input/output formats. Change your data source from XML to JSON? Your code doesn't change.

Uniformity: One access pattern (bag['path.to.value']), one way to attach metadata, one subscription model—instead of learning different APIs for each library.

Transformation: Operate on the structure itself: walk the tree, filter nodes, transform values, validate structure—without knowing if it came from a file, an API, or a database.

Round-tripping: Serialize to XML, JSON, or MessagePack and back, preserving types, attributes, and structure—including lazy-loaded values (resolvers).

The Core Model

Every node in a Bag has:

Component Purpose
Label The node's name (key in the hierarchy)
Value The data it holds (any Python value, or another Bag)
Attributes Metadata attached to the node
Tag Optional semantic type (like XML elements)

Access is path-based: bag['config.database.host'] navigates the hierarchy using dot notation.

Progressive Capability

Bag provides four layers—use only what you need:

Layer Purpose Use When
Core Bag Paths, values, attributes, serialization Always
Resolvers Lazy-loaded, computed values API calls, DB queries, expensive computations
Subscriptions React to changes Validation, logging, sync, computed properties

Interactive Notebooks

Try genro-bag directly in your browser with Google Colab:

Notebook Topics
Open In Colab Core Bag — Paths, values, attributes, serialization
Open In Colab Resolvers — Lazy loading, caching, custom resolvers
Open In Colab Subscriptions — Events, validation, computed properties

Install

pip install genro-bag

Documentation

Resource Description
Full Documentation Complete guide with examples
Why Bag? Detailed comparison with alternatives
Getting Started Learn the core concepts

In This Repository

Directory Description
src/genro_bag/ Core implementation
src/genro_bag/resolvers/ Built-in resolvers (URL, Directory, OpenAPI, Env, UUID, etc.)
examples/ Usage examples
tests/ Test suite (1800+ tests)
docs/ Sphinx documentation source

Development

pip install -e ".[dev]"
pytest

License

Apache License 2.0 — see LICENSE for details.

Copyright 2025 Softwell S.r.l. — Genropy Team

Migration to 0.22.0

DataChangeCollector and genro_bag.datachange have been removed. Consumers that need to accumulate or replicate changes should own that policy and use Bag subscriptions as needed. Importing the removed class or module is no longer supported.

Bag subscriptions, transactions and TYTX registration remain available, including serialization of Bags nested in ordinary dict/list values and registered branch types.

Synchronous Bag access

Bag and its resolvers return completed values, including in a running event loop. Resolvers implement synchronous load() methods. Async loaders and callbacks are rejected; application code owns asynchronous I/O and scheduling. See the synchronous resolver migration guide.

Release 0.23.0

See release notes for the synchronous resolver contract, constructor additions and compatibility boundaries.

Metadata

Release files for genro-bag 0.28.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 genro-bag 0.28.0
File Size Uploaded
genro_bag-0.28.0.tar.gz 260.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for genro-bag 0.28.0
File Interpreter ABI Platform
genro_bag-0.28.0-py3-none-any.whl Python 3 none any Details

Total release size: 372.5 kB

Release files / genro_bag-0.28.0.tar.gz

Download URL genro_bag-0.28.0.tar.gz
Size 260.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4be78bc5eaa84b18328d3474c9bc129bfb9198c84c411af51082d4cba06b04d1
BLAKE2b-256 checksum
How to use checksums
756576a5ddc45369ee25265a1d89612b73054760626fa0d784053340c353e90a
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 14, 2026.

Transparency log

Release files / genro_bag-0.28.0-py3-none-any.whl

Download URL genro_bag-0.28.0-py3-none-any.whl
Size 111.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a4be93c9867028d308f3c9d24f4f89b4f2acf41e64b57ef4adf413dfac384a3d
BLAKE2b-256 checksum
How to use checksums
4b33e15c6f6e1f8ed53971ab8435d4e5f5615b3d11f84775e99201cbe6590a61
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 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.28.0 This release

2 release files

0.27.0

2 release files

0.26.0

2 release files

0.25.1

2 release files

0.25.0

2 release files

0.24.0

2 release files

0.23.1

2 release files

0.23.0

2 release files

0.20.2

2 release files

0.20.1

2 release files

0.20.0

2 release files

0.19.1

2 release files

0.19.0

2 release files

0.18.5

2 release files

0.18.4

2 release files

0.18.3

2 release files

0.18.2

2 release files

0.18.1

2 release files

0.18.0

2 release files

0.17.1

2 release files

0.17.0

2 release files

0.11.2

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

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