Skip to main content

Trait-based static validation system for Dagster assets

Project description

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 @asset decorator

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

  1. Clone the repository:
git clone https://github.com/scartill/dagster-static
cd dagster-static
  1. Install dependencies using uv:
uv sync

Code Style

This project follows PEP 8 with a maximum line length of 160 characters. It uses:

  • flake8 for linting
  • ruff for 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)

Project details


Download files

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

Source Distribution

dagster_static-0.1.0.tar.gz (9.8 kB view details)

Uploaded Source

Built Distribution

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

dagster_static-0.1.0-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

File details

Details for the file dagster_static-0.1.0.tar.gz.

File metadata

  • Download URL: dagster_static-0.1.0.tar.gz
  • Upload date:
  • Size: 9.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for dagster_static-0.1.0.tar.gz
Algorithm Hash digest
SHA256 da37f94b5ccb7910cf51712709aeb708db4cd1ee136804c795e01da010992dd7
MD5 2b6c0f1546a70bed16df96955e288830
BLAKE2b-256 fbb2c9d36eeb649edf77c24e8bd571d73503251503c1412c71397d2f4659b5c7

See more details on using hashes here.

File details

Details for the file dagster_static-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: dagster_static-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for dagster_static-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 60881f5b97e7c8e6c3b571c9e0d3230060b502e22a89b5ba0300b91df5d3f858
MD5 9bd6b602b395619cf5647d8de1102db8
BLAKE2b-256 518083b7eda1568fa846c4c0c92b44fa1ecd78caea51dd8f563dcb5e6c904db4

See more details on using hashes here.

Supported by

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