Skip to main content

looker-sync

Move LookML between a local folder and your own Looker dev workspace, with verification. Python 3.9+, standard library only, nothing to install beyond uv.

uvx looker-sync init --project <name>

Quick start

  1. In an empty folder, run uvx looker-sync init --project <your Looker project id>.
  2. It writes a .env template and adds .env and .looker-sync/ to .gitignore, then stops with exit code 2. Fill in the three values below.
  3. Run the same init command again. It writes .looker-sync/config.json and pulls the project files into the folder.
  4. Edit the LookML, then uvx looker-sync push --dry-run and uvx looker-sync push.

.env holds an API key that belongs to your own Looker user:

LOOKER_URL=https://<your-instance>.looker.com
LOOKER_CLIENT_ID=...
LOOKER_CLIENT_SECRET=...

Create the key in Looker under Admin, Users, your user, Edit Keys. The tool looks for the env file in this order: --env-file, the LOOKER_SYNC_ENV variable, the env_file in .looker-sync/config.json, then .env in the project folder. Credentials are never printed and never written anywhere else.

Commands

command what it does
init [--project P] [--mode dev|prod] [--branch B] [--git-remote NAME | --no-git] set up a folder (it may be empty), then a first pull. --no-pull writes metadata only; --force takes Looker's copy over files already there. In a git clone it links the folder to a remote (asks on a terminal, else tries origin); --no-git skips
link [--remote NAME] link an existing folder to a git remote of its clone (default origin), so git and Looker stay on the same branch
pull [--force] [--dry-run] copy Looker files to disk; never deletes local files
status show what differs on each side, and how far the dev branch is ahead of and behind its remote; writes nothing
push [--force] [--delete] [--dry-run] write local changes, read every file back, then validate
switch (--branch B | --mode dev|prod) [--force] move Looker and the folder to another branch or mode. --force = back up local changes and confirm. In a linked folder it also stashes a dirty tree, checks out B in git and fast-forwards it to Looker's commit; it never pops the stash
skill [--path] print the full usage guide written for agents

Global options: -C <project folder> (default: the current folder) and --env-file <path>. --help is the short reference; looker-sync skill is the long one.

Exit codes: 0 ok, 1 Looker or network error, 2 refused by a guard, 3 validation errors.

What it guarantees

  • push writes your changes, reads every file back and compares bytes, then runs LookML validation and prints file:line message.
  • It refuses to overwrite a file edited in Looker since your last sync (--force to override).
  • pull never deletes local files and refuses to overwrite unpushed local work.
  • push never deletes files in Looker without --delete, and never writes in prod mode.
  • A push that stops partway records what it wrote; the next push retries only the rest.

What it does not do

It never commits, pushes to git, deploys, resets or creates branches. In a linked folder it only reads, fetches, stashes, checks out and fast-forwards local git; status warns and pull/push refuse when git is on another branch, printing the switch command that fixes it. Looker's API has no commit or push endpoint, and the official Looker VS Code extension commits through local git too. Pushed files show up in the dev workspace as uncommitted changes; commit them from the Looker IDE or your own git checkout of the remote.

One key, one branch at a time

The checked-out dev branch belongs to the Looker user, not to an API token. A second client on another branch is refused by a branch-mismatch guard; only switch moves the branch, and the browser IDE follows.

For agents and Claude Code

uvx looker-sync skill prints the complete guide: the loop, every guard and what a refusal means. The repo is also a Claude plugin, and skills/looker-sync/SKILL.md is the one authoritative copy, shipped both in the plugin and inside the package.

Development

python3 -m unittest discover -s scripts -p 'test_looker_sync.py'

The tests run the CLI against a fake Looker with no network. A release is a v*.*.* tag that matches the version in pyproject.toml; the workflow in .github/workflows/release.yml tests, builds and publishes to PyPI with trusted publishing, using notes from releases/.

License

MIT

Metadata

Release files for looker-sync 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for looker-sync 0.2.0
File Size Uploaded Provenance
looker_sync-0.2.0.tar.gz 23.7 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for looker-sync 0.2.0
File Interpreter ABI Platform
looker_sync-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.1 kB

Release files / looker_sync-0.2.0.tar.gz

Download URL looker_sync-0.2.0.tar.gz
Size 23.7 kB
Tags Source
SHA-256 checksum
How to use checksums
15ce65a20f0e331d7b65e77c7b31a1a4a70e74912a1f2aafe94ee1335ac2cdb4
BLAKE2b-256 checksum
How to use checksums
66c90aa6838f466e1fe91678184f547398227d8fd51f8d5c6f107f910afa922a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / looker_sync-0.2.0-py3-none-any.whl

Download URL looker_sync-0.2.0-py3-none-any.whl
Size 24.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
62ec455a5e693c74ea8a0025df6f4b78b3c99566db66c4c17a42ac7c3fa91bb7
BLAKE2b-256 checksum
How to use checksums
649e6d55751c4d7d2b97e8392656e79c93afc89b84bac8d803e10ba0c268cd53
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for looker-sync 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for looker_sync-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page