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.1

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.1
File Size Uploaded Provenance
looker_sync-0.2.1.tar.gz 24.2 kB With provenance Details

Built distribution (wheel)

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

Total release size: 49.0 kB

Release files / looker_sync-0.2.1.tar.gz

Download URL looker_sync-0.2.1.tar.gz
Size 24.2 kB
Tags Source
SHA-256 checksum
How to use checksums
ec323262a3a08c3bd24ffa88e27624813189c7654a5262a2cf70c69f88138624
BLAKE2b-256 checksum
How to use checksums
68eda8f5f6537375093e3251eede233399c2b986ce543d7b9c3cb78656c141d2
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.1-py3-none-any.whl

Download URL looker_sync-0.2.1-py3-none-any.whl
Size 24.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e9d605558540b17d1de3762a9edb1993e505daf673c0c3623333ef9ffcdbe775
BLAKE2b-256 checksum
How to use checksums
47f7adda067eb30be73d606d3c38419bcd6cb9dd522ae0a435852c796d6ea98a
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.1

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.1.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