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/--versionprints 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 forsql; 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 byupdate-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 |
grant |
Grant Unity Catalog privileges to a principal 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) |
about |
Print the project's PyPI + GitHub links |
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
grant
Grant Unity Catalog privileges to a user, group, or sp (service principal) across workspaces. The object's granularity sets the blast radius — a table grants on that table, a schema grants on every table in it, a catalog grants on every table in every (non-system) schema — and the prerequisite USE_CATALOG / USE_SCHEMA traversal grants are always issued. Access maps to read → SELECT, write → SELECT, MODIFY, all → ALL PRIVILEGES, manage → MANAGE.
$ sleepybricks grant group data_science write my_catalog.sales.orders dev,stg
Granting write on my_catalog.sales.orders to group 'data_science'…
Workspace Tables Statements Status
--------------------- ------ ---------- ----------
👩💻 Development (dev) 1 3 ✅ granted
🔧 Staging (stg) 1 3 ✅ granted
--dry-run — preview the exact statements per workspace without executing them (handy before a catalog-wide grant):
$ sleepybricks grant sp 390ecd65-2698-4249-9cd4-833bb5032f5b manage my_catalog.sales dev --dry-run
─── 👩💻 Development (dev) ───
GRANT USE_CATALOG ON CATALOG my_catalog TO `390ecd65-2698-4249-9cd4-833bb5032f5b`;
GRANT USE_SCHEMA ON SCHEMA my_catalog.sales TO `390ecd65-2698-4249-9cd4-833bb5032f5b`;
GRANT MANAGE ON TABLE my_catalog.sales.orders TO `390ecd65-2698-4249-9cd4-833bb5032f5b`;
GRANT MANAGE ON TABLE my_catalog.sales.refunds TO `390ecd65-2698-4249-9cd4-833bb5032f5b`;
Add --json for structured output. Grants run on each workspace's serverless warehouse (same one sql uses).
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
about
Print the installed version alongside the project's public PyPI and GitHub links — no workspace calls.
$ sleepybricks about
sleepybricks 1.7.1
PyPI: https://pypi.org/project/sleepybricks/
GitHub: https://github.com/anthonybench/bricks
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
- Specification — what the tool does
- Project outline — repository layout
- Test drive — setup, testing, and CLI usage
- Adding a command — how to extend the CLI
- Publishing — release to PyPI
Metadata
Release files for sleepybricks 1.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sleepybricks-1.8.0.tar.gz | 50.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sleepybricks-1.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 113.1 kB
Release files / sleepybricks-1.8.0.tar.gz
| Download URL | sleepybricks-1.8.0.tar.gz |
|---|---|
| Size | 50.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2b5270d6522ec0aae1be1c4a05cd6ebcc93b4a91715229702c7d4fc14fea46c5
|
|
BLAKE2b-256 checksum How to use checksums |
d6a592eb6a09ca733b47a8d4a7eeeb46f31c59f66b35b08b6c0e772b6a94a48e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.13.5 Darwin/25.5.0
|
Release files / sleepybricks-1.8.0-py3-none-any.whl
| Download URL | sleepybricks-1.8.0-py3-none-any.whl |
|---|---|
| Size | 63.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5f9798a6e2f5e0afc161016f30fd310c43bfe2f389386197d6953b99f35c7229
|
|
BLAKE2b-256 checksum How to use checksums |
82dd9c3d32c98fa728828c00c30e3cce12d22be671ffe6227193b6e516133378
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.13.5 Darwin/25.5.0
|