jobs_tools
Databricks job management utilities.
This module provides utilities for creating, scheduling, and monitoring Databricks jobs and for delivering Delta-backed Slack reminders.
Requires: - databricks-sdk - time
Author: Various contributors
jobs_tools.create_job(task_key, notebook_path, cluster_id, quartz_cron_expression, base_parameters=None, name=None)
Create a scheduled Databricks job.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_key
|
str
|
Unique identifier for the task. |
required |
notebook_path
|
str
|
Path to the notebook to execute. |
required |
cluster_id
|
str
|
Databricks cluster ID to run the job on. |
required |
quartz_cron_expression
|
str
|
Cron expression for job schedule (Quartz format). |
required |
base_parameters
|
dict
|
Parameters to pass to the notebook. Defaults to {"run_date": today's date}. |
None
|
name
|
str
|
Job name. Defaults to task_key if not provided. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
The created job's ID. |
Raises:
| Type | Description |
|---|---|
Exception
|
If job creation fails. |
Note
- All jobs scheduled in CET timezone
- Requires WorkspaceClient credentials
- Default run_date is today's date in YYYY-MM-DD format
Example
job_id = create_job( task_key="daily_analysis", notebook_path="/Users/me/notebooks/analysis", cluster_id="0123-456789-abc", quartz_cron_expression="0 0 * * * ?" )
jobs_tools.update_job_schedule(job_id, quartz_cron_expression=None)
Update the schedule of an existing Databricks job.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
job_id
|
int
|
ID of the job to update. |
required |
quartz_cron_expression
|
str
|
New cron expression (Quartz format). If not provided, does nothing. |
None
|
Returns:
| Type | Description |
|---|---|
|
None |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If job not found. |
Note
- Uses CET timezone for all schedules
- No-op if quartz_cron_expression is None
Example
update_job_schedule(123456, "0 12 * * * ?")
jobs_tools.wait_for_job_run(run_id, wait_seconds=10, maxtime=21600)
Wait for a Databricks job run to complete.
Polls the job run status at regular intervals until it reaches a terminal state (completed, failed, or skipped).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_id
|
int
|
ID of the job run to wait for. |
required |
wait_seconds
|
int
|
Seconds to wait between status checks. Defaults to 10. |
10
|
maxtime
|
int
|
Maximum seconds to wait before timing out. Defaults to 21600 (6 hours). |
21600
|
Returns:
| Name | Type | Description |
|---|---|---|
JobState |
The final state object of the completed job run. |
Raises:
| Type | Description |
|---|---|
TimeoutError
|
If job run does not complete within maxtime seconds. |
Note
Terminal states: TERMINATED, SKIPPED, INTERNAL_ERROR
Example
final_state = wait_for_job_run(987654321, wait_seconds=30) print(f"Job finished with result: {final_state.result_state}")
jobs_tools.submit_job_run(job_id, params)
Submit an ad-hoc run of an existing Databricks job.
Creates a one-time job run with the specified parameters, without affecting the job's schedule.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
job_id
|
int
|
ID of the job to run. |
required |
params
|
dict
|
Parameters to pass to the notebook. Parameter names should match those expected by the notebook. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
The run_id of the submitted job run. |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If job not found. |
Note
- Creates a one-off run with fixed name "one_off_run"
- Use wait_for_job_run(run_id) to wait for completion
- Returns the run_id for tracking purposes
Example
run_id = submit_job_run(123456, {"param1": "value1"}) final_state = wait_for_job_run(run_id)
jobs_tools.JobScheduler
Schedule and submit Databricks jobs using a Delta-backed registry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schedule_table
|
str
|
Fully qualified name of the Delta table that stores scheduled jobs. |
'`panel-management`.default.scheduled_jobs'
|
Attributes:
| Name | Type | Description |
|---|---|---|
schedule_table |
Fully qualified schedule table name. |
|
schedule |
Pandas DataFrame containing the locally loaded schedule. |
|
w |
Databricks workspace client used to submit job runs. |
Notes
This class requires an active Spark session, Delta Lake support, and valid Databricks workspace authentication. The schedule is collected to the driver as a pandas DataFrame and is intended for small scheduling tables.
jobs_tools.JobScheduler.__init__(schedule_table='`panel-management`.default.scheduled_jobs')
Initialize the scheduler and load its configured schedule table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schedule_table
|
str
|
Fully qualified name of the Delta table that stores scheduled jobs. |
'`panel-management`.default.scheduled_jobs'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
jobs_tools.JobScheduler._validate_job_id(job_id)
staticmethod
Validate and normalize a Databricks job identifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
job_id
|
int
|
Databricks job identifier. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Validated positive job identifier. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If |
jobs_tools.JobScheduler._validate_notebook_params(notebook_params)
staticmethod
Validate and copy parameters passed to a Databricks job.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
notebook_params
|
Optional[Dict[str, str]]
|
Job parameters whose keys and values must be strings, or |
required |
Returns:
| Type | Description |
|---|---|
dict or None
|
A shallow copy of the validated parameters, or |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the value is not a dictionary or contains a non-string key or value. |
jobs_tools.JobScheduler._empty_schedule()
classmethod
Return an empty pandas schedule with the required columns.
Returns:
| Type | Description |
|---|---|
DataFrame
|
Empty frame whose columns are :attr: |
jobs_tools.JobScheduler._validate_schedule(schedule)
Validate the columns and keys of an in-memory schedule.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schedule
|
DataFrame
|
Schedule rows to validate. |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If required columns, identifiers, statuses, or dates are invalid. |
jobs_tools.JobScheduler._new_schedule_id()
Return a positive 63-bit identifier not present in memory.
Returns:
| Type | Description |
|---|---|
int
|
Identifier in the range 1 to |
jobs_tools.JobScheduler._write_rows(rows)
Create the schedule table or merge selected rows into it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rows
|
DataFrame
|
Complete schedule rows to create or merge by |
required |
jobs_tools.JobScheduler._idempotency_token(schedule_id)
Return a stable Databricks idempotency token for a schedule row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
schedule_id
|
int
|
Identifier of the schedule row the token represents. |
required |
Returns:
| Type | Description |
|---|---|
str
|
SHA-256 hex digest of the table name and |
jobs_tools.JobScheduler.schedule_job(job_id, run_date, notebook_params=None, write_schedule=True)
Add a pending Databricks job run to the schedule.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
job_id
|
int
|
Positive identifier of the Databricks job to run. |
required |
run_date
|
Union[str, datetime, date]
|
Date on which the job should be submitted. Strings must use
|
required |
notebook_params
|
Optional[Dict[str, str]]
|
Optional job parameters with string keys and string values. |
None
|
write_schedule
|
bool
|
If |
True
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If |
jobs_tools.JobScheduler.read_schedule()
Load and validate the configured Delta schedule in memory.
Notes
The complete table is collected to the driver as a pandas DataFrame. If the table does not exist, an empty schedule with the expected columns is initialized. Calling this method discards unpersisted in-memory changes.
jobs_tools.JobScheduler.write_schedule()
Merge the complete in-memory schedule into the Delta table.
Notes
A missing table is created using the explicit schedule schema. Existing
rows are matched by schedule_id and updated; unmatched rows are
inserted. Normal scheduling and execution paths write only changed rows.
jobs_tools.JobScheduler.execute_scheduled_jobs(include_previous_days=False)
Submit pending jobs whose run dates are eligible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
include_previous_days
|
bool
|
If |
False
|
Notes
Each successful submission is persisted immediately with status
submitted. Stable idempotency tokens prevent the same schedule row
from creating another run when a submission is retried.
jobs_tools.JobScheduler.execute_job(job_id, notebook_params=None, idempotency_token=None)
Submit a configured Databricks job for immediate execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
job_id
|
int
|
Positive identifier of the Databricks job to submit. |
required |
notebook_params
|
Optional[Dict[str, str]]
|
Optional job parameters with string keys and string values. |
None
|
idempotency_token
|
Optional[str]
|
Optional token of at most 64 characters that prevents duplicate runs when the same request is retried. |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Identifier of the submitted Databricks run. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If an input has an invalid type. |
ValueError
|
If an identifier or idempotency token is invalid. |
jobs_tools.JobScheduler.get_pending_jobs(include_previous_days=False)
Return pending jobs whose run dates are eligible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
include_previous_days
|
bool
|
If |
False
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Eligible rows with status |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the in-memory schedule contains an invalid or null run date. |
jobs_tools.JobScheduler.delete_schedule(auto_confirm=False)
Delete every row from the configured schedule after confirmation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
auto_confirm
|
bool
|
If |
False
|
Notes
Confirmed deletion removes all active Delta rows and resets the in-memory schedule. Delta transaction history may still permit recovery according to the table's retention configuration.
jobs_tools.ReminderScheduler
Store and deliver Slack reminders from a Delta table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reminders_table
|
str
|
Fully qualified Delta table used to persist reminders. |
'`panel-management`.default.reminders_schedule'
|
secret_scope
|
str
|
Databricks secret scope containing the webhook mapping. |
'dame'
|
secret_key
|
str
|
Secret key containing a JSON object of webhook IDs and URLs. |
'webhooks'
|
max_attempts
|
int
|
Maximum number of delivery attempts for one reminder. |
3
|
claim_timeout_minutes
|
int
|
Minutes after which an interrupted delivery claim can be retried. |
30
|
Notes
Reminder dates use the Europe/Copenhagen calendar. Delivery is
at-least-once: row claiming prevents concurrent and repeated delivery after
success, but a process failure after Slack accepts a message and before the
Delta status update can still result in a retry.
jobs_tools.ReminderScheduler.__init__(reminders_table='`panel-management`.default.reminders_schedule', secret_scope='dame', secret_key='webhooks', max_attempts=3, claim_timeout_minutes=30)
Initialize the reminder registry and create it when missing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reminders_table
|
str
|
Fully qualified Delta table used to persist reminders. |
'`panel-management`.default.reminders_schedule'
|
secret_scope
|
str
|
Databricks secret scope containing the webhook mapping. |
'dame'
|
secret_key
|
str
|
Secret key containing a JSON object of webhook IDs and URLs. |
'webhooks'
|
max_attempts
|
int
|
Maximum number of delivery attempts for one reminder. |
3
|
claim_timeout_minutes
|
int
|
Minutes after which an interrupted delivery claim can be retried. |
30
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If a configuration value has an invalid type. |
ValueError
|
If a configuration value is empty or not positive, or an existing table has an incompatible schema. |
jobs_tools.ReminderScheduler._validate_non_empty_string(value, name)
staticmethod
Validate and strip a required string value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
str
|
Value to validate. |
required |
name
|
str
|
Human-readable field name used in error messages. |
required |
Returns:
| Type | Description |
|---|---|
str
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If |
jobs_tools.ReminderScheduler._ensure_table()
Create the reminders table or validate its existing schema.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the existing table has missing, unexpected, or type-incompatible
columns relative to :attr: |
Notes
The Delta schema and delivery statuses are part of this class's public operational contract, so an incompatible table is rejected rather than migrated.
jobs_tools.ReminderScheduler._load_webhooks()
Load and validate the webhook mapping from Databricks secrets.
Returns:
| Type | Description |
|---|---|
dict
|
Mapping of webhook ID to webhook URL, read from the configured secret scope and key. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the secret does not contain a JSON object, or if any webhook ID or URL is empty. |
TypeError
|
If any webhook ID or URL is not a string. |
Notes
Webhook URLs are secret values. Callers must keep them out of logs, exceptions, and the reminders table.
jobs_tools.ReminderScheduler._new_reminder_id()
Return a positive 63-bit identifier absent from the Delta table.
Returns:
| Type | Description |
|---|---|
int
|
Identifier in the range 1 to |
Notes
Each candidate costs one query against the reminders table. The check is not transactional, so concurrent writers can still pick the same identifier.
jobs_tools.ReminderScheduler._reset_stale_claims()
Release delivery claims left behind by interrupted senders.
jobs_tools.ReminderScheduler.submit_reminder(reminder_date, user, message, webhook_id=_DEFAULT_WEBHOOK_ID)
Persist a Slack reminder for delivery on or after a date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reminder_date
|
Union[datetime, date]
|
Copenhagen calendar date on which the reminder becomes eligible. A
|
required |
user
|
str
|
Username or recipient identifier included in the webhook payload. |
required |
message
|
str
|
Reminder text included in the webhook payload. |
required |
webhook_id
|
str
|
Key used to select a URL from the configured webhook secret. |
_DEFAULT_WEBHOOK_ID
|
Returns:
| Type | Description |
|---|---|
int
|
Unique reminder identifier stored in Delta. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If an argument has an invalid type. |
ValueError
|
If a string is empty or |
Examples:
>>> reminders = ReminderScheduler()
>>> reminders.submit_reminder(
... date(2026, 4, 15),
... "john.doe",
... "Review Q2 reports",
... )
jobs_tools.ReminderScheduler.send_reminders()
Send all eligible reminders and persist each delivery outcome.
Returns:
| Type | Description |
|---|---|
dict
|
Counts named |
Notes
Pending and previously failed reminders dated today or earlier are
eligible until max_attempts is reached. Each row is claimed atomically
before delivery, and successful rows are never selected again. Failures
are recorded and do not stop delivery of the remaining reminders.