Skip to main content

convalesce-emit-dagster

Forward Dagster run status to Convalesce, unchanged.

Install

pip install convalesce-emit-dagster

Wire it up

The package exports a sensor body rather than a decorated sensor, because Dagster's decorator signatures move between versions and this package does not depend on Dagster. Apply the decorator in your own definitions:

from dagster import DagsterRunStatus, Definitions, run_status_sensor
from convalesce_emit_dagster import convalesce_sensor


@run_status_sensor(run_status=DagsterRunStatus.SUCCESS)
def convalesce_on_success(context):
    convalesce_sensor(context)


@run_status_sensor(run_status=DagsterRunStatus.FAILURE)
def convalesce_on_failure(context):
    convalesce_sensor(context)


@run_status_sensor(run_status=DagsterRunStatus.CANCELED)
def convalesce_on_canceled(context):
    convalesce_sensor(context)


defs = Definitions(
    sensors=[convalesce_on_success, convalesce_on_failure, convalesce_on_canceled]
)

Each fires with the run, the event and the sensor name, as Dagster produced them. A cancelled run is recorded as skipped. Set CONVALESCE_INGEST_KEY where the daemon runs.

Set CONVALESCE_DAGSTER_URL where your sensor runs to the address you open the Dagster UI at, such as https://dagster.example.com, or https://my-org.dagster.cloud on Dagster+. Each job, op, run and step in Convalesce then links to its page in Dagster. On Dagster+ the link goes through the deployment the run ran in, a branch deployment included.

What each step ran

With the run, the sensor sends one entry per executed step:

  • the source of the op or asset function behind it, read from your definitions;
  • the SQL statements it ran through SQLAlchemy or a database driver, as text, with the dialect and database and without bound values;
  • the configuration it was resolved with.

The statements and the configuration are noted in the process that runs the step and written to the run's event log as one engine event per step, which the sensor reads back. This starts when your definitions import convalesce_emit_dagster, on the multiprocess and the in-process executor alike. Secrets are masked before anything is written or sent.

Each is on by default and has its own switch, set where your steps and your sensor run: CONVALESCE_SEND_SOURCE, CONVALESCE_SQL_CAPTURE and CONVALESCE_SEND_ARGUMENTS (false turns one off).

What an asset's author attached

Metadata on a materialisation, an observation, an asset check and a Failure is sent in two parts:

  • the entries that describe a table, as they are: row counts, the table name and URI, the column schema and column lineage, the code version and the SQL an asset ran;
  • every other entry whose value is a number, a flag or a timestamp, under its own name: MetadataValue.int, .float, .bool and .timestamp, or the bare value. Up to 50 per event, with names up to 128 characters.

Text, markdown, JSON, tables, paths and links are replaced by a count of what was withheld. Set CONVALESCE_DAGSTER_SEND_METADATA=false where your sensor runs to send the first part only.

The path an IO manager records is sent when it is the URI of a place in an object store, such as s3://my-bucket/orders, which names a dataset. A path on a local disk is counted with what was withheld. Set CONVALESCE_DAGSTER_SEND_LOCAL_PATHS=true where your sensor runs to send local paths too.

What identifies the deployment

On Dagster+ the sensor sends the deployment name, whether it is a branch deployment, the code location, the commit and branch, the repository and its URL, and the pull request number and status, as the agent sets them in DAGSTER_CLOUD_* variables. The commit's author and message stay where they are.

A run's tags are sent, yours and Dagster's dagster/ ones. Of the .dagster/ tags Dagster keeps for itself, the scheduled execution time and the repository are sent. The login of whoever launched the run, the agent's id and label, the process id, and the agent's environment variables stay where they are.

Declare what an op reads and writes

An asset names its own table. For an op whose datasets appear nowhere in its code or metadata, pass them to the sensor as lineage, keyed by op name:

LINEAGE = {
    "load_orders": {
        "inputs": ["s3://my-bucket/exports/orders"],
        "outputs": [
            "urn:cvl:dataset:(urn:cvl:dataPlatform:snowflake,my_db.my_schema.orders,PROD)"
        ],
    },
}


@run_status_sensor(run_status=DagsterRunStatus.SUCCESS)
def convalesce_on_success(context):
    convalesce_sensor(context, lineage=LINEAGE)

A dataset is named by its urn, as in the convalesce.inputs and convalesce.outputs metadata of an op's inputs and outputs, or by the URI of a path in an object store. lineage may also be a function of the sensor's context that returns such a mapping, for a declaration that depends on the run.

Settings

Set CONVALESCE_SEND_SETTINGS=true where your steps run and each step's entry also carries the environment variables its process had. It is off by default.

The settings are read in the process that runs the step, so a step on the multiprocess executor or behind a step launcher reports its own environment. They travel in the same engine event as the rest of what the step ran, already in the form they are sent in. Set CONVALESCE_INGEST_KEY or CONVALESCE_FINGERPRINT_KEY where your steps run, so there is a key to hash with there.

A setting whose name or value reads as a credential, and any value longer than 300 characters, is sent as a fingerprint: a keyed hash, sixteen hex characters long, made in your process. It says that the value changed between two runs and nothing of what the value is. Every other setting is sent as its value.

The hash is keyed with CONVALESCE_FINGERPRINT_KEY where you set one, and with a key derived from your ingest key otherwise. The fingerprint key is only ever read in your process and is never sent. keyed_by identifies the key the hashes were made under, so hashes are compared only between runs that used the same one.

Set CONVALESCE_SETTINGS_SKIP to a comma-separated list of names to keep those settings out in either form, such as CONVALESCE_SETTINGS_SKIP=HOSTNAME,INTERNAL_REGION.

Each step's entry then holds:

{
  "settings": {
    "items": [
      {"kind": "environment", "name": "API_KEY", "fingerprint": "5d1c0a9e7b3f2468"},
      {"kind": "environment", "name": "WAREHOUSE", "value": "analytics"}
    ],
    "keyed_by": "9f3b6c1d2e4a5b70"
  }
}

Supported

Dagster 1.7 and later, on Python 3.9 and later. Verified on real installs: see version-support.md.

Configure

Read from the environment: see convalesce-emit.

Metadata

Release files for convalesce-emit-dagster 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for convalesce-emit-dagster 0.3.0
File Size Uploaded
convalesce_emit_dagster-0.3.0.tar.gz 60.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for convalesce-emit-dagster 0.3.0
File Interpreter ABI Platform
convalesce_emit_dagster-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 98.8 kB

Release files / convalesce_emit_dagster-0.3.0.tar.gz

Download URL convalesce_emit_dagster-0.3.0.tar.gz
Size 60.5 kB
Tags Source
SHA-256 checksum
How to use checksums
fb1fbb74a95c9124eaf6bfb91e2441afb7c47c89093b0ec33b58f0f99bf74a61
BLAKE2b-256 checksum
How to use checksums
d4bfa979c892b24bc02ef3c14a777ad69878ca5ffa45fbf8222c5e4571c0725c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 10, 2026.

Transparency log

Release files / convalesce_emit_dagster-0.3.0-py3-none-any.whl

Download URL convalesce_emit_dagster-0.3.0-py3-none-any.whl
Size 38.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5a0e5f7f16bd5835f66a7d19ffb29fd9813744c77c8bd195aad8799dbe93fe21
BLAKE2b-256 checksum
How to use checksums
34d64a1adc2d04e5b833fb71a7480d0b12103666de8fe9553d979df408689153
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 10, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.0

2 release files

This release

0.3.0 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page