Rule-based attribute enrichment for any sequence of items
Project description
Attribute Enricher
Rule-based attribute enrichment for any sequence of items.
Overview
vcti-attribute-enricher adds attributes to items in a sequence by
matching vcti-lookup rules. Each EnrichRule pairs a condition
(when) with attributes to write (set); the enricher walks an
iterable, evaluates each rule against each item, and stamps matching
items with the rule's attributes.
The package is iterable-generic, not tree-specific: the items can be
tree-node payloads (e.g., from vcti-fileloader), dicts, dataclasses,
or any object with an attribute-bearing surface. Reading and writing
are pluggable via getter / setter callables, with sensible defaults
for vcti-fileloader's DataNode-shaped payloads.
The package is the write-side counterpart to vcti-lookup: where
Lookup filters a sequence by rules, the enricher mutates the sequence
by rules.
Installation
pip install vcti-attribute-enricher
In requirements.txt
vcti-attribute-enricher>=1.0.0
In pyproject.toml dependencies
dependencies = [
"vcti-attribute-enricher>=1.0.0",
]
Quick Start
from vcti.attribute_enricher import EnrichRule, apply_rules
from vcti.lookup import MISSING, Rule
items = [
{"name": "stress.h5", "dtype": "float64", "attributes": {}, "enricher_attributes": {}},
{"name": "ids.h5", "dtype": "int64", "attributes": {}, "enricher_attributes": {}},
{"name": "config.json", "dtype": "object", "attributes": {}, "enricher_attributes": {}},
]
def getter(item, key):
# Read from the item's "attributes" dict, then the top-level item.
# Return MISSING (not None) when absent so the rule cleanly no-matches.
if key in item["attributes"]:
return item["attributes"][key]
return item.get(key, MISSING)
apply_rules(
items,
rules=[
EnrichRule(set={"loaded_at": "2026-06-06"}), # every item
EnrichRule(set={"category": "mechanical"},
when=(Rule("name", "^=", "stress"),)), # name starts with "stress"
EnrichRule(set={"is_numeric": True},
when=(Rule("dtype", "^=", "float"),
Rule("dtype", "!=", "object"))), # AND across rules
],
getter=getter,
setter=lambda item, key, value: item["enricher_attributes"].__setitem__(key, value),
)
For payloads with a single mutable attribute dict (the common case):
items = [{"name": "x", "tags": {}}, {"name": "y", "tags": {}}]
apply_rules(
items,
rules=[EnrichRule(set={"seen": True})],
getter=lambda item, key: item.get(key, MISSING),
setter=lambda item, key, value: item["tags"].__setitem__(key, value),
)
Getters must return
vcti.lookup.MISSINGfor absent attributes, notNone.Noneis a legal value that gets passed to the operator;MISSINGshort-circuits the rule to "no match".
Enriching tree-node payloads
The package's default getter/setter are tuned for vcti-fileloader's
DataNode/LazyDataNode payloads, which carry both a read-only
file_attributes mapping (file-native) and a mutable
enricher_attributes dict. The merged read view is exposed via
.attributes (a ChainMap).
from vcti.attribute_enricher import EnrichRule, apply_rules
from vcti.tree import descendants
from vcti.lookup import Rule
apply_rules(
descendants(tree, subtree_root, include_self=True),
rules=[
EnrichRule(set={"file_path": str(path)}),
EnrichRule(set={"category": "mechanical"},
when=(Rule("name", "^=", "stress"),)),
],
)
No getter / setter arguments needed — the defaults read
item.attributes (ChainMap) and write to item.enricher_attributes.
How it works
- Iterate the supplied items.
- For each item, evaluate every
EnrichRule:- If
whenis empty, the rule matches. - If
whenhas one or moreRules, every rule must match (AND). - A rule matches by reading the relevant attribute through
getterand evaluating it viavcti.predicate.evaluate(forwarded throughvcti-lookup).
- If
- On a match, write each key/value in
setto the item viasetter.
Layering — last write wins. Multiple EnrichRules that match the
same item all apply, in the order given. Later rules overwrite earlier
ones on collision. This makes it easy to express "set a default for
everything, then refine for specific subsets."
Return value. apply_rules returns an EnrichResult with summary
counts — handy for logging and for spotting dead rules:
result = apply_rules(items, rules)
print(result.items_visited, result.items_matched, result.writes_applied)
print(result.per_rule_matches) # match count per rule, in order; 0 = dead rule
The items are mutated in place; the result carries metrics only.
API
| Symbol | Description |
|---|---|
EnrichRule(set, when=()) |
Frozen dataclass. set is a dict of attributes to write; when is a tuple[Rule, ...] combined with AND logic. Empty when matches every item. Not hashable (the set dict). |
apply_rules(items, rules, *, getter=None, setter=None) |
Walk items, evaluate rules, stamp matches. Returns an EnrichResult. Defaults to vcti.lookup.attributes_getter and a setter that writes to item.enricher_attributes. Mutates in place (not thread-safe); raises ValueError with rule context if evaluation fails (fail-fast, non-transactional). |
EnrichResult(items_visited, items_matched, writes_applied, per_rule_matches) |
Frozen dataclass of summary counts returned by apply_rules. per_rule_matches is per-rule, in order (a 0 flags a dead rule). |
Getter / Setter |
Type aliases for the (item, key) -> value and (item, key, value) -> None callables. |
Values in set are written by reference — a mutable value shared across
matched items is the same object on each. See docs/patterns.md
for pitfalls.
Dependencies
- vcti-lookup (>=1.0.0) —
Rule,MISSING, defaultattributes_getter - vcti-predicate (>=1.0.0) —
evaluate()is called directly for rule matching
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vcti_attribute_enricher-1.0.0.tar.gz.
File metadata
- Download URL: vcti_attribute_enricher-1.0.0.tar.gz
- Upload date:
- Size: 15.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc8e5a31d89fd8ce7d397724e62006dee754abf7a8b85af1cc48b7a2500430af
|
|
| MD5 |
0c3967beec75fdd1c7bf298ae7d1a2c6
|
|
| BLAKE2b-256 |
8cb276a31ef6d07fc85609f8bbfec9f641095019e9f0c040dcbd1c6e54f5b5be
|
Provenance
The following attestation bundles were made for vcti_attribute_enricher-1.0.0.tar.gz:
Publisher:
release.yml on vcollab/vcti-python-attribute-enricher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vcti_attribute_enricher-1.0.0.tar.gz -
Subject digest:
dc8e5a31d89fd8ce7d397724e62006dee754abf7a8b85af1cc48b7a2500430af - Sigstore transparency entry: 1740203028
- Sigstore integration time:
-
Permalink:
vcollab/vcti-python-attribute-enricher@e8c0b58c1403188dc4e346604521ef3a1d91c749 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/vcollab
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e8c0b58c1403188dc4e346604521ef3a1d91c749 -
Trigger Event:
push
-
Statement type:
File details
Details for the file vcti_attribute_enricher-1.0.0-py3-none-any.whl.
File metadata
- Download URL: vcti_attribute_enricher-1.0.0-py3-none-any.whl
- Upload date:
- Size: 10.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f53287c01013bcb8004789bb3d60d9ab26017cab1d08137baec524d7f45b56ee
|
|
| MD5 |
31d7316b3274b4df6d26f340ca3671a3
|
|
| BLAKE2b-256 |
23abc39d4163e18ce45a28ddaf61ca77f213519f34d4f116a73060b35fe643f6
|
Provenance
The following attestation bundles were made for vcti_attribute_enricher-1.0.0-py3-none-any.whl:
Publisher:
release.yml on vcollab/vcti-python-attribute-enricher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vcti_attribute_enricher-1.0.0-py3-none-any.whl -
Subject digest:
f53287c01013bcb8004789bb3d60d9ab26017cab1d08137baec524d7f45b56ee - Sigstore transparency entry: 1740203057
- Sigstore integration time:
-
Permalink:
vcollab/vcti-python-attribute-enricher@e8c0b58c1403188dc4e346604521ef3a1d91c749 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/vcollab
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e8c0b58c1403188dc4e346604521ef3a1d91c749 -
Trigger Event:
push
-
Statement type: