Skip to main content

stapel-attributes

CI coverage pypi downloads python license llms.txt

Typed attributes engine: an L1 library (no models, migrations, views, urls, comm surface or service identity of its own) providing a polymorphic type-plugin system (config/dto/dao/type per feature type) behind an open registry, nine built-in types, DTO/DAO validation and normalization, polymorphic DRF serializers with OpenAPI schemas, and a schema-driven (Lit 3) admin config editor. Imported directly by stapel-categories (feature schema) and stapel-listings (value validation).

Part of the Stapel framework — composable Django apps that deploy as a monolith or as microservices without changing module code.

Install

pip install stapel-attributes

At a glance

Fact Value
Version 0.4.6
Python >=3.11 (3.11, 3.12, 3.13, 3.14)
Django djangorestframework>=3.14
Config axes 1
Usage surface 36
Extension points 4
Fleet dependencies stapel-core

Documentation

capabilities.json · llms.txt (for agents)

What this is

This is an L1 library, not a module: it ships no models, migrations, views, urls or comm surface. Both stapel-categories (attribute schema) and stapel-listings (attribute values) import it — the code both need synchronously lives one layer down, like stapel-core itself.

Provenance: port of the categories/feature_types engine and the ads validation pipeline from a legacy catalog app (see CHANGELOG for what was fixed in transit).

Quick start

No INSTALLED_APPS entry, no urls — just import it:

from stapel_attributes import (
    FeatureDef,
    validate_dto,
    normalize_to_dao,
    validate_dto_structured,
)

configs = [
    FeatureDef(slug="mileage", config={"type": "int", "min": 0, "postfix": "km"}),
    FeatureDef(slug="condition", config={"type": "bool"}, mandatory=True),
]
payload = {"mileage": {"type": "int", "value": 120000},
           "condition": {"type": "bool", "value": True}}

validate_dto(configs, payload)              # raises ValidationError on failure
dao = normalize_to_dao(configs, payload)    # {"mileage": {"type": "int", "value": 120000, "postfix": "km", "order": 0}, ...}
result = validate_dto_structured(configs, payload)  # machine-readable batch result

Built-in types

int, float, string, bool, hex_color, select, date, header, hierarchical_select, convertible_unit. Each type is a plugin: a Config dataclass (schema), a DTO (client input), a DAO (stored value + display metadata) and a handler (BaseFeatureType[TConfig, TDto, TDao]). convertible_unit stores values in a canonical base unit per family (length/weight/area/volume/temperature) and converts to/from the user-facing unit — see MODULE.md for the storage/conversion/range-filter contract.

Other marketplace-specific types (size grids, ...) are not shipped — hosts register their own via the open registry (see MODULE.md for the worked example).

Settings

All configuration lives in the STAPEL_ATTRIBUTES namespace (dict setting, flat setting, or env var — resolved lazily):

Key Default Meaning
EXTRA_TYPES [] Dotted paths of extra feature types, merged over the built-ins (each entry: a BaseFeatureType subclass or a module that registers types on import).

Structured validation

Every validation failure carries a machine code end-to-end (ValidationErrorCode) via FeatureValidationError — no message parsing. Batch validators return ValidationBatchResult rows with error, ref_value, localizable_error (an error.400.feature_* key) and params.

Extension points

See MODULE.md — the agent-facing map of every fork-free seam (settings, the type registry, serializer factories, translation-key hooks).

Admin UI

A schema-driven config editor (Lit 3 web components) ships with the package. Each type declares its admin form in Python (config_form() → field-kinds); the committed bundle renders it, so a new type needs zero JS for standard kinds. Use ConfigEditorWidget on a config JSONField:

from stapel_attributes import ConfigEditorWidget

class FeatureForm(forms.ModelForm):
    class Meta:
        widgets = {"config": ConfigEditorWidget()}

Two themes (--stapel-*, light + dark), en/ru locales (merge without fork via ADMIN_LOCALES), and JS widget registries for exotic types. See MODULE.md "Admin UI" and docs/done/attributes-admin-ui.md. Frontend source is in static_src/ (npm test / npm run build); the built bundle is committed — consumers need no Node.

Development

pip install -e . && pip install pytest pytest-django ruff
./setup-hooks.sh
pytest tests/

License

MIT — see LICENSE.


This page is assembled by stapel-readme from docs/readme.md plus the contract artifacts in docs/. Edit the prose in docs/readme.md; the badges, facts and links above and below it are generated — do not hand-edit README.md.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stapel_attributes-0.4.6.tar.gz (110.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stapel_attributes-0.4.6-py3-none-any.whl (150.4 kB view details)

Uploaded Python 3

File details

Details for the file stapel_attributes-0.4.6.tar.gz.

File metadata

  • Download URL: stapel_attributes-0.4.6.tar.gz
  • Upload date:
  • Size: 110.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for stapel_attributes-0.4.6.tar.gz
Algorithm Hash digest
SHA256 27143cc57c1270de947a7e7b71fc56578ce9254d97d73643387cf4b11f8469fb
MD5 ee51aa130abe1785ea15fba8eb6ea787
BLAKE2b-256 2ddba4a11bfcd86874ae7348523dd31efd89e87f4aa6475ecb09be0cc7f2a5d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for stapel_attributes-0.4.6.tar.gz:

Publisher: publish.yml on usestapel/stapel-attributes

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file stapel_attributes-0.4.6-py3-none-any.whl.

File metadata

File hashes

Hashes for stapel_attributes-0.4.6-py3-none-any.whl
Algorithm Hash digest
SHA256 5ad75ff6188a9cd0e01a670d095d763c762187138dd68b2583015616972825d7
MD5 994351c35f3d67706232a6166371ca52
BLAKE2b-256 0f40a686c67ccc13b14a286f0a36274cd5a753b106ef63e68217142188432a83

See more details on using hashes here.

Provenance

The following attestation bundles were made for stapel_attributes-0.4.6-py3-none-any.whl:

Publisher: publish.yml on usestapel/stapel-attributes

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.4.7

2 files

This release

0.4.6 This release

2 files

0.4.5

2 files

0.4.4

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page