dagster-static
A trait-based static validation system for Dagster assets that enables load-time verification of asset dependencies and capabilities.
Overview
dagster-static provides a mechanism for defining and validating traits (capabilities) that assets provide and require. This allows you to catch dependency mismatches at definition time rather than runtime, making your Dagster pipelines more robust and easier to maintain.
Features
- Trait-based Asset Definition: Declare what capabilities each asset provides
- Static Validation: Verify that requested traits are provided by upstream assets
- Namespace Support: Organize assets into separate namespaces for isolation
- Upstream Trait Inheritance: Inherit traits from upstream assets with the
+syntax - Rich Error Messages: Clear error messages when trait mismatches are detected
Installation
pip install dagster-static
Or using uv:
uv add dagster-static
Requirements
- Python >= 3.13
- Dagster >= 1.12.0
Quick Start
Basic Usage
from dagster import AssetKey
from dagster_static import asset, with_traits
# Define an asset that provides a trait
@asset(
key=AssetKey(['data', 'raw']),
provides='raw_data'
)
def raw_data_asset():
return {'data': 'raw'}
# Define an asset that requires a trait from another asset
@asset(
key=AssetKey(['data', 'processed']),
provides='processed_data',
traits={AssetKey(['data', 'raw']): 'raw_data'}
)
def processed_data_asset(raw_data_asset):
return {'data': 'processed'}
# Validate all trait dependencies
@with_traits()
def main():
# Your Dagster pipeline code here
pass
Using Namespaces
You can organize assets into separate namespaces to avoid conflicts:
from dagster_static import asset, with_traits, DEFAULT_NS
# Assets in the default namespace
@asset(
key=AssetKey(['data', 'raw']),
provides='raw_data',
ns=DEFAULT_NS
)
def raw_data_asset():
return {'data': 'raw'}
# Assets in a custom namespace
@asset(
key=AssetKey(['data', 'raw']),
provides='raw_data',
ns='custom'
)
def custom_raw_data_asset():
return {'data': 'custom_raw'}
# Validate a specific namespace
@with_traits(ns='custom')
def validate_custom_namespace():
pass
Inheriting Traits from Upstream Assets
You can inherit traits from upstream assets using the + syntax:
@asset(
key=AssetKey(['data', 'raw']),
provides='raw_data'
)
def raw_data_asset():
return {'data': 'raw'}
@asset(
key=AssetKey(['data', 'enriched']),
provides='+data/raw:enriched_data,raw_data'
)
def enriched_data_asset(raw_data_asset):
# This asset provides both 'enriched_data' and 'raw_data'
# (inherited from the upstream asset)
return {'data': 'enriched'}
Multiple Traits
Assets can provide and request multiple traits:
@asset(
key=AssetKey(['data', 'multi']),
provides='trait1,trait2,trait3'
)
def multi_trait_asset():
return {'multi': True}
@asset(
key=AssetKey(['data', 'consumer']),
provides='result',
traits={
AssetKey(['data', 'multi']): 'trait1,trait2'
}
)
def consumer_asset(multi_trait_asset):
return {'result': True}
API Reference
asset Decorator
The main decorator for defining assets with traits.
Parameters:
key(AssetKey): The asset key (required)provides(str): Comma-separated list of traits this asset provides (required)traits(dict[AssetKey, str]): Dictionary mapping upstream asset keys to their required traits (optional)ns(str): Namespace for this asset (default:'default')**kwargs: Additional arguments passed to Dagster's@assetdecorator
Returns:
- Decorated function that creates a Dagster asset with trait validation
with_traits Decorator
Validates all trait dependencies in a namespace before execution.
Parameters:
ns(str): Namespace to validate (default:'default')
Returns:
- Decorator that validates traits before executing the wrapped function
Raises:
ValueError: If trait dependencies cannot be resolved
provide Function
Manually register that an asset provides certain traits.
from dagster_static import provide
from dagster import AssetKey
provide(AssetKey(['data', 'raw']), 'raw_data')
request Function
Manually register that an asset requests certain traits from another asset.
from dagster_static import request
from dagster import AssetKey
request(
AssetKey(['data', 'raw']),
'raw_data',
by=AssetKey(['data', 'processed'])
)
resolve Function
Manually validate trait dependencies in a namespace.
from dagster_static import resolve
resolve('default') # Validates the default namespace
Raises:
ValueError: If trait dependencies cannot be resolved
Error Messages
When trait validation fails, dagster-static provides detailed error messages:
dagster-static: Errors in namespace default: [
'Asset "default:data/processed" provides nothing but requested "{\'raw_data\'} by data/consumer"',
'Asset default:data/raw provides only "raw" but expected "raw_data" requested by data/processed'
]
These messages help you quickly identify which assets have mismatched trait dependencies.
Development
Setup
- Clone the repository:
git clone https://github.com/scartill/dagster-static
cd dagster-static
- Install dependencies using
uv:
uv sync
Code Style
This project follows PEP 8 with a maximum line length of 160 characters. It uses:
flake8for lintingrufffor formatting (line length: 120, single quotes)
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Author
Boris Resnick (boris.resnick@gmail.com)
Metadata
Release files for dagster-static 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dagster_static-0.2.0.tar.gz | 47.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dagster_static-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.2 kB
Release files / dagster_static-0.2.0.tar.gz
| Download URL | dagster_static-0.2.0.tar.gz |
|---|---|
| Size | 47.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b6ce26a7a2bc46c49b1a66c3f9d1b22d098eee8ad30ab6a0edda44763d0c6e94
|
|
BLAKE2b-256 checksum How to use checksums |
48e0a2df6819c459dc72a565ed32bdcf76d81e09c4ae2c18d134b8bb2298981f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 15, 2026.
Transparency logRelease files / dagster_static-0.2.0-py3-none-any.whl
| Download URL | dagster_static-0.2.0-py3-none-any.whl |
|---|---|
| Size | 8.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e4ce4aa832d317cea824c13df6d44f65db547fa7c651860c9709b3169eaae322
|
|
BLAKE2b-256 checksum How to use checksums |
5967213539c2837969f4d10437a928428d9d9cdc38698d837d492f92f36ed9b1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Apr 15, 2026.
Transparency log