Pattern: Asset-to-Task
An asset produces cached data. A task consumes that data to perform a side-effect. Use barca get for the asset, barca run for the task.
The right way
Section titled “The right way”from barca import asset, task
@assetdef trained_model(): return train(load_data("training_set.csv"))
@task(inputs={"model": trained_model})def deploy(model): upload_to_s3(model, bucket="models", key="latest.pkl") notify_slack("Model deployed")# Materialize the asset (cached)barca get trained_model pipeline.py
# Execute the task (always runs)barca run deploy pipeline.pyWhy this works
Section titled “Why this works”- Assets are cached data.
trained_modelonly re-runs when its code or upstream inputs change. Expensive computation is done once and reused. - Tasks are side-effects.
deployalways re-runs because side-effects (uploading, notifying) are not idempotent by default. Barca treats tasks as “always stale.” - Clean separation. The DAG edge from asset to task means the task is guaranteed to see a fully materialized, up-to-date model before it executes.
Common mistakes
Section titled “Common mistakes”Making a task an input to an asset
Section titled “Making a task an input to an asset”# Wrong -- DAG validation will reject this@taskdef migrate_db(): run_migrations()
@asset(inputs={"_done": migrate_db})def user_counts(): return query("SELECT count(*) FROM users")Tasks always re-run, so any asset downstream of a task would have its cache perpetually invalidated. Barca’s DAG validation rejects task-to-asset edges to prevent this. If you need ordering without data, see Ordering-Only Dependencies and use a task-to-task edge or an asset-to-asset edge instead.
Using barca get on a task
Section titled “Using barca get on a task”# Wrong -- tasks are not cacheable artifactsbarca get deploy pipeline.py# Error: 'deploy' is a task -- use `barca run` insteadbarca get targets assets; naming a task explicitly is rejected with a clear error pointing you to barca run. Note that running barca get pipeline.py on a whole file (no target) still executes every node in the file, tasks included – it does not silently skip them. Scope to barca get <asset> pipeline.py if you want to materialize just the asset without side effects firing.