Scenarios and jobs
A scenario is a project's scheduled or on-demand sequence of steps; a job run is one execution recorded by the platform. Scenarios are managed through Scenario handles; runs, pipeline triggers and logs through client.jobs. Scenario endpoints need org-admin permission. See Scheduler for the concepts.
Scenarios
project.list_scenarios()
sc = project.get_scenario("daily_refresh") # by name or display name
sc = project.get_scenario(42) # or by id
sc = project.create_scenario(
"daily_refresh",
display_name="Daily refresh",
trigger_type="manual",
steps=[{"type": "run_scenario", "config": {"scenario_id": 41}}],
)
create_scenario(name, *, display_name=None, description="", trigger_type="manual", steps=None, is_active=False, **extra) sends any extra keyword as a field of the scenario. sc.update(**fields) changes fields (for example steps=[...] or is_active=True), sc.delete() removes it, and sc.get_settings() returns the cached record.
Run and wait
run = sc.run() # {run_id, status, steps}
final = client.jobs.wait(run["run_id"], poll_interval=10, timeout=3600)
final = sc.run_and_wait(poll_interval=10.0, timeout=3600.0) # the same, in one call
print(final["status"])
sc.get_last_runs(limit=5) # recent runs from the scenario record
run_and_wait triggers the scenario and polls the run until it reaches a terminal status (below). When the timeout passes first, it returns the last-seen run, still running; the run continues on the server either way.
Triggers
A scenario can carry several triggers. Adding the first stored trigger supersedes the scenario's legacy single trigger_type field.
trig = sc.add_trigger("temporal", config={"cron": "0 6 * * *"}, name="every morning")
sc.add_trigger("sql_query", config={
"sql": "SELECT 1 FROM staging.orders_raw WHERE customer_id IS NULL HAVING COUNT(*) > 100",
})
for t in sc.list_triggers():
print(t["trigger_id"], t["trigger_type"], t["active"])
sc.update_trigger(trig["trigger_id"], "temporal", config={"cron": "0 7 * * *"}) # full replace
sc.delete_trigger(trig["trigger_id"])
Trigger types include temporal (cron), sql_query, dataset_modified and after_scenario; config is specific to the type.
Reporters
Reporters send a notification when a run starts or ends.
rep = sc.add_reporter(
"mail", "notify ops",
send_on="end", # start | end
trigger="failure", # always | success | failure | custom
channel_config={"to": "ops@your-domain.com"},
template_body="${scenarioName}: ${outcome}",
)
sc.test_reporter(rep["id"]) # sends a sample success notification now
sc.list_reporters()
sc.update_reporter(rep["id"], active=False)
sc.delete_reporter(rep["id"])
kind is mail, slack, teams or webhook; channel_config carries that channel's settings. With trigger="custom", the reporter evaluates run_condition_formula.
Jobs
client.jobs is a JobsAPI object.
Runs
runs = client.jobs.list_runs(status="failed", limit=50, offset=0) # newest first
run = client.jobs.get_run(run_id) # full detail, including log_output
client.jobs.abort_run(run_id)
final = client.jobs.wait(run_id, poll_interval=5.0, timeout=1800.0,
raise_on_timeout=True)
list_runs accepts job_type and status filters; limit must be 1–200 (the server's page size cap; anything else raises ValueError, 0.1.8+) and offset pages further.
wait polls get_run until the status is terminal. On timeout it returns the last-seen detail, or raises TimeoutError with raise_on_timeout=True (0.1.8+).
Terminal statuses
A run is finished when its status is one of:
success · failed · aborted · error · done · skipped
skipped is what the still-open child steps of an aborted run become (0.1.8+ adds it to the terminal set). The set is available as JobsAPI.TERMINAL_STATUSES.
Pipeline triggers
client.jobs.trigger("dbt_run", select="stg_sales+")
# {"status": "triggered", "job_name": "dbt_run", "triggered_by": ...}
run = client.jobs.trigger_and_wait("dbt_run", select="stg_sales+", timeout=3600)
print(run["status"], run.get("duration_sec"))
print(client.jobs.logs("dbt_run", lines=100)) # the tail of the job's log
trigger(job_name, *, project_id=None, **opts) starts extract_incremental, extract_organization or dbt_run, passing options such as select, mode, tables, organization, start_date, end_date or schedule_at. It returns as soon as the job is started; the response carries no run id. With schedule_at, the response is "scheduled" with the scheduled time.
trigger_and_wait (0.1.8+) closes that gap: it notes the existing pipeline runs, triggers, finds the new run of the job started by the same user, and polls it until it is no longer running, queued or pending. It raises TimeoutError when no run appears within start_timeout (default 120 s), and refuses schedule_at. Both need org admin.
list_pipeline_runs(status=None, limit=20) and get_pipeline_run(run_id) (0.1.8+) read the pipeline-run rows directly.
Verified against honeyframeapi 0.1.8.