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
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 readSELECT, writeSELECT, MODIFY, allALL PRIVILEGES, manageMANAGE.

$ 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

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.8.0.tar.gz (50.1 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.8.0-py3-none-any.whl (63.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sleepybricks-1.8.0.tar.gz
  • Upload date:
  • Size: 50.1 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.8.0.tar.gz
Algorithm Hash digest
SHA256 2b5270d6522ec0aae1be1c4a05cd6ebcc93b4a91715229702c7d4fc14fea46c5
MD5 e4db3c5f88a86f66532a3039f360e8a0
BLAKE2b-256 d6a592eb6a09ca733b47a8d4a7eeeb46f31c59f66b35b08b6c0e772b6a94a48e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: sleepybricks-1.8.0-py3-none-any.whl
  • Upload date:
  • Size: 63.0 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.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5f9798a6e2f5e0afc161016f30fd310c43bfe2f389386197d6953b99f35c7229
MD5 c91b4fc8a92f0ca1c1a259a30e8eb4be
BLAKE2b-256 82dd9c3d32c98fa728828c00c30e3cce12d22be671ffe6227193b6e516133378

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