Skip to main content

⚡ sleepybricks

Run databricks operations across many workspaces from one terse CLI.

PyPI Python License

sleepybricks wraps the databricks SDK with a Typer CLI so a single command fans out across all your workspaces — run SQL, trigger jobs, sync secrets, publish notebooks, audit groups, and more. It authenticates from your existing ~/.databrickscfg and prints a tidy per-workspace table for every operation.

Install

uv tool install sleepybricks     # or: pipx install sleepybricks

Optional, for the impatient: alias bricks='sleepybricks'.

-v / --version prints the version and best-effort checks PyPI for a newer release — it works even when placed within another command (sleepybricks sql … --version).

Authenticate

Profiles come from ~/.databrickscfg — the same file the databricks CLI uses. Most commands take a comma-separated profile list (dev,stg,us); groups-audit is the account-scoped exception. A missing file or unknown profile fails fast with a clear message.

databricks configure --token     # once per workspace/profile

Output is a per-workspace table styled by your config, decorated with a per-profile emoji + name. Add --json to any command for structured, pipeline-friendly output.

Configure

sleepybricks is a sleepy util and reads its settings from the shared ~/sleepyconfig/params.yml, using the bricks_ key prefix. If the file is absent it writes only its own section (below) and says so; if a value it needs is missing it prints this snippet and asks you to verify your config.

# sleepybricks
bricks_table_style: simple                                  # any tabulate style (rounded_grid, github, …)
bricks_serverless_warehouse_name: <env>_serverless_warehouse # <env> → the active profile name
bricks_env_emojis:
  dev: "👩‍💻"
  stg: "🔧"
  us: "🇺🇸"
bricks_display_names:
  dev: "Development"
  stg: "Staging"
  us: "United States"
bricks_personal_cluster_name: personal_cluster              # ensured by update-clusters
bricks_personal_cluster_policy: "Personal Compute"          # must already exist in the workspace
  • bricks_table_style — any tabulate table style.
  • bricks_serverless_warehouse_name — SQL warehouse for sql; the <env> token becomes the active profile name (use a static value if it's the same everywhere).
  • bricks_env_emojis / bricks_display_names — how each profile is labeled in output.
  • bricks_personal_cluster_name / bricks_personal_cluster_policy — used only by update-clusters.

Commands at a glance

Command What it does
sql Run a SQL statement (or .sql file) on each workspace's serverless warehouse
run-job Trigger a job by exact name in each workspace
dash-links Print a dashboard's published link in each workspace
groups-audit Audit account-level groups and their users
write-secret / create-scope Manage secret scopes + secrets everywhere
pull-repo Pull the latest commit for a git repo in each workspace
put-file Upload a local file/notebook to each workspace
propagate-file Copy a file/notebook from one workspace to the others
create-workspace-folder Make a workspace folder in each workspace
update-clusters Ensure a pinned, latest-LTS personal cluster in each workspace
snippets Local cheat sheets (paths, workspaces)

sql

Run one statement across workspaces on each one's serverless SQL warehouse (resolved from config).

$ sleepybricks sql -s "select region, count(*) tenants from tenants group by region" dev,stg

─── 👩‍💻 Development (dev) ───
region     tenants
---------  -------
us-west-2     1043
eu-west-1      512

─── 🔧 Staging (stg) ───
region     tenants
---------  -------
us-west-2       12

--sum <column> — totals a column per workspace and across all of them:

$ sleepybricks sql -s "select amount from invoices" dev,stg --sum amount

Workspace              sum(amount)
---------------------  -----------
👩‍💻 Development (dev)     182500.75
🔧 Staging (stg)             432.10
TOTAL                     182932.85

--out <path> — write every workspace's rows to one CSV (leading profile column; .csv enforced):

$ sleepybricks sql -f ./audit.sql dev,stg --out ./audit

Workspace              Rows written
---------------------  ------------
👩‍💻 Development (dev)   1555
🔧 Staging (stg)          12

Wrote 1567 rows to audit.csv

Also: --as-sp <application_id> runs the query as a service principal (OAuth M2M; secret from $SLEEPYBRICKS_SP_SECRET) instead of you, and --json emits structured results. --out and --sum are mutually exclusive.

run-job

Trigger a job by exact, case-sensitive name. Job names aren't unique — if more than one matches in a workspace, nothing runs there and the count is reported.

$ sleepybricks run-job "Nightly ETL" dev,stg,eu

Workspace              Job ID  Status
---------------------  ------  -------------------------------------------
👩‍💻 Development (dev)   42      ✅ started: https://dev…/jobs/42/runs/9107
🔧 Staging (stg)        -       (not found)
🇺🇸 United States (eu)   -       ⚠️ 2 jobs share this name — not run

dash-links

Find a dashboard's published link everywhere (case-sensitive; first match per workspace, with a warning on duplicates).

$ sleepybricks dash-links "Triage Device Metrics" dev,eu

✨ Triage Device Metrics ✨

Workspace              Link
---------------------  ---------------------------------------------------
👩‍💻 Development (dev)   https://dev…/dashboardsv3/a1b2c3/published
🇺🇸 United States (eu)   https://eu…/dashboardsv3/d4e5f6/published

groups-audit

Account-scoped (no profile list): list each account group with its users. The account profile is auto-detected from ~/.databrickscfg. --inactive keeps only deactivated users (likely departed); --users <emails> filters to specific people. Either filter hides groups with no matches.

$ sleepybricks groups-audit --inactive

=== Engineering (1) ===
Email          Display Name    Active
-------------  --------------  ------
bob@corp.com   Bob Stone       False

=== Data (1) ===
Email           Display Name    Active
--------------  --------------  ------
carol@corp.com  Carol Diaz      False

write-secret / create-scope

Create secret scopes and write secrets across workspaces. The secret value is never a CLI argument — it's read from $SLEEPYBRICKS_SECRET_STAGE (keeps it out of shell history and ps).

$ sleepybricks create-scope quant dev,stg

Workspace              Scope   Status
---------------------  ------  -----------------
👩‍💻 Development (dev)   quant   ✅ created
🔧 Staging (stg)        quant   ↩️ already existed

$ export SLEEPYBRICKS_SECRET_STAGE='s3cr3t-value'
$ sleepybricks write-secret quant.api_key dev,stg

Workspace              Scope   Key      Status
---------------------  ------  -------  ----------
👩‍💻 Development (dev)   quant   api_key  ✅ written
🔧 Staging (stg)        quant   api_key  ✅ written

pull-repo

Pull the latest commit for a git repo (matched by name within its workspace path) in each workspace.

$ sleepybricks pull-repo databricks_templates dev,stg

Workspace              Repo                                        Branch  Status
---------------------  ------------------------------------------  ------  ----------------
👩‍💻 Development (dev)   /Repos/dingus@company.com/databricks_…      main    ✅ pulled @ 3f9a1c2
🔧 Staging (stg)        /Repos/dingus@company.com/databricks_…      main    ✅ pulled @ 3f9a1c2

put-file

Upload a local file/notebook to the same path in each workspace (overwrites). Notebook source (.py, .sql, .scala, .r, .ipynb) sent to a workspace path lands as a notebook; DBFS//FileStore paths go to DBFS.

$ sleepybricks put-file ./tools/audit.py /Users/dingus@company.com/Tools/audit dev,stg

Workspace              Target                                     Status
---------------------  -----------------------------------------  ----------------------
👩‍💻 Development (dev)   /Users/dingus@company.com/Tools/audit      ✅ uploaded → notebook
🔧 Staging (stg)        /Users/dingus@company.com/Tools/audit      ✅ uploaded → notebook

propagate-file

Edit a notebook in one workspace, then push it to the others at the same path (overwrites; a notebook stays a notebook). Reports created vs. overwritten per target.

$ sleepybricks propagate-file dev /Users/dingus@company.com/Tools/audit qa,stg

Propagating '/Users/dingus@company.com/Tools/audit' from 'dev' to 2 workspace(s)...

Workspace              Path                                       Status
---------------------  -----------------------------------------  --------------
🧪 QA (qa)              /Users/dingus@company.com/Tools/audit      ✅ created
🔧 Staging (stg)        /Users/dingus@company.com/Tools/audit      ✅ overwritten

create-workspace-folder

Make a workspace folder in each workspace (idempotent — existing folders are skipped).

$ sleepybricks create-workspace-folder /Shared/quant dev,stg

Workspace              Path            Status
---------------------  --------------  -----------------
👩‍💻 Development (dev)   /Shared/quant   ✅ created
🔧 Staging (stg)        /Shared/quant   ↩️ already existed

update-clusters

Ensure a pinned, single-user, latest-LTS personal cluster (name + policy from config) in each workspace. Creates it when missing, rebuilds it when on an old runtime, or just (re)pins it when current.

$ sleepybricks update-clusters dev,stg

Workspace              Cluster ID          Status
---------------------  ------------------  ------------------------------------------
👩‍💻 Development (dev)   0729-1a2b3c-abcd    ✅ created + pinned
🔧 Staging (stg)        0729-9z8y7x-wxyz    ✅ rebuilt to 15.4.x-scala2.12 (was 13.3…)

snippets

Local cheat sheets — no workspace calls for paths; workspaces summarizes your configured profiles.

$ sleepybricks snippets workspaces

Display Name    Profile  URL                                 Cloud  Region
--------------  -------  ----------------------------------  -----  ---------
Development     dev      https://dev…cloud.databricks.com     aws    us-west-2
Staging         stg      https://stg…cloud.databricks.com     aws    us-west-2

$ sleepybricks snippets paths     # workspace vs dbfs:/ vs /dbfs/ vs /Volumes reference

Development

uv venv
uv pip install -e ".[dev]"
uv run pytest          # or ./tools/test.sh

Tests use fakes for the databricks client and never touch a real workspace.

Documentation

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sleepybricks-1.7.2.tar.gz (44.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sleepybricks-1.7.2-py3-none-any.whl (56.1 kB view details)

Uploaded Python 3

File details

Details for the file sleepybricks-1.7.2.tar.gz.

File metadata

  • Download URL: sleepybricks-1.7.2.tar.gz
  • Upload date:
  • Size: 44.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.13.5 Darwin/25.5.0

File hashes

Hashes for sleepybricks-1.7.2.tar.gz
Algorithm Hash digest
SHA256 521da6cf350d5eeb629a973150929bc4fec456ec2af2c124d9a09326b1c32a96
MD5 634896369e8c0e5701cbbc6e96128c19
BLAKE2b-256 643b3509e56e09533ed1a841a90c6c13d4d8fbb6d223e61dd575a76dd54bf9ee

See more details on using hashes here.

File details

Details for the file sleepybricks-1.7.2-py3-none-any.whl.

File metadata

  • Download URL: sleepybricks-1.7.2-py3-none-any.whl
  • Upload date:
  • Size: 56.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.13.5 Darwin/25.5.0

File hashes

Hashes for sleepybricks-1.7.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5c7fd8fca563697c90a0a72cade9ab170b95e22d924a1b325d712eb233518b5b
MD5 1404176ab3d7eda0f41fdede7af65862
BLAKE2b-256 0ad058e55bee9c9fe6e1b9083e287363aa158467ca43dd4a0201b722a1f090f1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page