Skip to content

Feat: Add lifecycle hooks to PrefectDbtRunner and PrefectDbtOrchestrator#21523

Open
harsh21234i wants to merge 5 commits intoPrefectHQ:mainfrom
harsh21234i:feat/dbt-lifecycle-hooks-21493
Open

Feat: Add lifecycle hooks to PrefectDbtRunner and PrefectDbtOrchestrator#21523
harsh21234i wants to merge 5 commits intoPrefectHQ:mainfrom
harsh21234i:feat/dbt-lifecycle-hooks-21493

Conversation

@harsh21234i
Copy link
Copy Markdown

@harsh21234i harsh21234i commented Apr 13, 2026

Fixes #21493 I’ve implemented this on a local branch and verified the focused prefect-dbt test suite.

Completed in this pass:

  • Added failure-safe Python lifecycle hooks to PrefectDbtRunner
  • Added failure-safe Python lifecycle hooks to PrefectDbtOrchestrator
  • Added invocation, selector, node, orchestration, and wave-level hook support
  • Added docs and release note coverage
  • Added focused tests for the new hook behavior

Verification:

  • uv run pytest tests/core/test_runner.py tests/core/test_orchestrator_per_wave.py tests/core/test_orchestrator_per_node.py -q
  • 229 passed

@github-actions github-actions bot added docs enhancement An improvement of an existing feature integrations Related to integrations with other services labels Apr 13, 2026
Copy link
Copy Markdown
Member

@desertaxle desertaxle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for submitting a PR @harsh21234i!

I would take a slightly different approach to the interface. I think a decorator-based API would be better for readability and type checking.

Here's the shape I think this should take:

from prefect_dbt import PrefectDbtRunner, DbtHookContext

runner = PrefectDbtRunner()

@runner.on_run_start                        
def before_build(ctx: DbtHookContext): ...

@runner.post_model(select="tag:critical")
def on_critical_done(ctx: DbtHookContext):
    if ctx.status == "error":
        publish_metric(...)

@runner.on_run_end(select="tag:marts")
def after_marts(ctx: DbtHookContext): ...

runner.invoke(["build"])

@harsh21234i
Copy link
Copy Markdown
Author

Thanks, that makes sense. I’ll follow the decorator-based API shape and keep the implementation aligned between PrefectDbtRunner and PrefectDbtOrchestrator. I’ll start by defining a typed DbtHookContext and wiring the run/model hook registration and execution path.

@harsh21234i
Copy link
Copy Markdown
Author

Hello @desertaxle I updated the implementation to the decorator-based API you suggested. PrefectDbtRunner and PrefectDbtOrchestrator now expose decorator hooks with a typed DbtHookContext, including select=... filtering, and I added focused tests for registration, execution, filtering, and hook-failure isolation.

Harsh Thakare added 2 commits April 13, 2026 23:14
# Conflicts:
#	src/integrations/prefect-dbt/prefect_dbt/core/_orchestrator.py
#	src/integrations/prefect-dbt/prefect_dbt/core/runner.py
@harsh21234i
Copy link
Copy Markdown
Author

I updated the implementation to the decorator-based API you suggested. PrefectDbtRunner now supports on_run_start, post_model(select=...), and on_run_end(select=...) with a typed DbtHookContext, and I applied the same hook shape to PrefectDbtOrchestrator as well. I also added focused tests for registration, execution, filtering, and hook-failure isolation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs enhancement An improvement of an existing feature integrations Related to integrations with other services

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Python Lifecycle Hooks to PrefectDbtRunner and PrefectDbtOrchestrator

2 participants