Yu(Irene) Chen
06/15/2026, 3:10 AMfrom prefect import flow, task
from prefect_datahub.dataset import Dataset
from prefect_datahub.datahub_emitter import DatahubEmitter
datahub_emitter = DatahubEmitter.load("MY-DATAHUB-BLOCK")
@task(name="Transform", description="Transform the data")
def transform(data):
data = data.split(" ")
datahub_emitter.add_task(
inputs=[Dataset("snowflake", "mydb.schema.tableA")],
outputs=[Dataset("snowflake", "mydb.schema.tableC")],
)
return data
@flow(name="ETL flow", description="Extract transform load flow")
def etl():
data = transform("This is data")
datahub_emitter.emit_flow()Marvin
06/15/2026, 3:10 AMMarvin
06/15/2026, 3:15 AMdatahub_emitter.emit_flow() at the bottom of the flow, it will be skipped whenever the flow errors before reaching that line.
Use the flow hooks:
- on_completion
- on_failure
- optionally on_crashed
- optionally on_cancellation
Example:
python
from prefect import flow, task
from prefect_datahub.dataset import Dataset
from prefect_datahub.datahub_emitter import DatahubEmitter
datahub_emitter = DatahubEmitter.load("MY-DATAHUB-BLOCK")
@task(name="Transform", description="Transform the data")
def transform(data):
data = data.split(" ")
datahub_emitter.add_task(
inputs=[Dataset("snowflake", "mydb.schema.tableA")],
outputs=[Dataset("snowflake", "mydb.schema.tableC")],
)
return data
def emit_datahub(flow, flow_run, state):
try:
datahub_emitter.emit_flow()
except Exception as exc:
# optional: log this somewhere
print(f"Failed to emit DataHub metadata: {exc}")
@flow(
name="ETL flow",
description="Extract transform load flow",
on_completion=[emit_datahub],
on_failure=[emit_datahub],
on_crashed=[emit_datahub],
on_cancellation=[emit_datahub],
)
def etl():
data = transform("This is data")
return data
A couple of notes:
- add_task(...) should still happen inside your tasks, as you’re already doing.
- emit_flow() should not be relied on at the end of the flow body if you need it to happen on failures too.
- Wrapping emit_flow() in try/except inside the hook is a good idea so DataHub emission problems do not mask the real flow result.
If you want, I can also show a version that only emits on completed + failed, or help verify this against the exact prefect-datahub version you’re using.Yu(Irene) Chen
06/15/2026, 3:16 AMMarvin
06/15/2026, 3:16 AMMarvin
06/15/2026, 3:21 AMprefect-datahub implementation.
You can trigger something when the flow enters RUNNING using Prefect’s on_running hook, but the current DatahubEmitter.emit_flow() implementation does not appear to fully model flow lifecycle transitions like “running now, finished later” for flows.
So the answer is:
- Prefect side: yes, you can hook into RUNNING
- DataHub emitter side: likely not enough by itself to show a proper running → finished transition in DataHub UI for flow runs
Example of the Prefect hook:
python
from prefect import flow, task
from prefect_datahub.dataset import Dataset
from prefect_datahub.datahub_emitter import DatahubEmitter
datahub_emitter = DatahubEmitter.load("MY-DATAHUB-BLOCK")
@task
def transform(data):
datahub_emitter.add_task(
inputs=[Dataset("snowflake", "mydb.schema.tableA")],
outputs=[Dataset("snowflake", "mydb.schema.tableC")],
)
return data.split(" ")
def emit_running(flow, flow_run, state):
datahub_emitter.emit_flow()
def emit_terminal(flow, flow_run, state):
datahub_emitter.emit_flow()
@flow(
name="ETL flow",
on_running=[emit_running],
on_completion=[emit_terminal],
on_failure=[emit_terminal],
on_crashed=[emit_terminal],
on_cancellation=[emit_terminal],
)
def etl():
return transform("This is data")
But a few important caveats:
- This may emit multiple times, but that does not necessarily mean DataHub will render it as “running first, then completed/failed”.
- From the current integration behavior, emit_flow() seems oriented around emitting the flow metadata/run event, but not a full state-transition lifecycle for flows the same way you’re hoping.
- So calling it in on_running and again at the end may create duplicate emissions rather than a nice status progression in the UI.
If your goal is specifically:
“I want DataHub UI to show a flow run as RUNNING while it executes, then COMPLETED/FAILED when done”
then this likely requires an enhancement to prefect-datahub, not just a different Prefect hook setup.
Useful Prefect docs on hooks:
- State change hooks
- Flow API
If you want, I can help you with either:
1. a best-effort hook pattern for today, or
2. a small custom emitter patch to support running/final state emission more explicitly.Yu(Irene) Chen
06/15/2026, 3:25 AMMarvin
06/15/2026, 3:26 AMMarvin
06/15/2026, 3:28 AMDatahubEmitter.emit_flow(). So you cannot use an automation to directly call the DataHub emitter inside your flow environment.
What automations can do:
- trigger on flow run events like:
- prefect.flow-run.running
- prefect.flow-run.completed
- prefect.flow-run.failed
- then execute supported actions such as:
- CallWebhook
- notifications
- flow/deployment control actions
So the workable pattern is:
1. Prefect Automation watches flow state changes
2. Automation sends a webhook
3. Your webhook service calls DataHub
So for your use case:
- If you want “running” and “finished” events: yes, automations can trigger on those states
- If you want to call DatahubEmitter.emit_flow() itself: no, not from the automation alone
A typical setup would be:
text
Prefect flow-run event
-> Automation
-> Webhook
-> Your service
-> DataHub API / custom emitter logic
This is useful if you want DataHub updates without modifying flow code, but there’s a tradeoff:
- automations know about flow state changes
- they do not automatically have the same in-process lineage context that prefect-datahub collects from add_task(...)
So if your lineage depends on:
python
datahub_emitter.add_task(inputs=[...], outputs=[...])
then doing everything purely from automations may not reproduce the same rich lineage data unless your webhook service reconstructs it some other way.
Recommendation:
- Use flow hooks if you want to preserve prefect-datahub task/dataset lineage behavior
- Use automations + webhook if your goal is mostly status syncing to DataHub (running, completed, failed)
Relevant docs:
- Automations
- Events
- Automation actions
If you want, I can draft:
1. a Prefect Automation webhook payload for flow state changes, or
2. a recommended hook-based approach for prefect-datahub lineage plus status emission.