Python client and CLI for Loom workspace data and sync workflows.
Project description
loom-data
loom-data publishes the loom Python package and the loom CLI.
It is used to:
- read raw Loom data with a local cache
- scan
loom_rawdatasets into summarizedloom_exploreoutputs - review and confirm local workspace changes
- push and pull workspaces against a Loom sync server
The install name is loom-data, but the Python import stays import loom and the command stays loom.
What Loom does
Loom turns raw datasets under test-project/loom/loom_raw into structured summaries under test-project/loom/loom_explore.
This lets agents and people read generated overviews, profiles, and data cards first, instead of opening every raw CSV directly.
Directory layout
Loom expects this workspace layout:
test-project/loom/loom_raw/<topic>: raw source datasetstest-project/loom/loom_explore/<topic>: generated scan outputtest-project/loom/.loom/raw/<workspace>: local raw cache
In this repository:
- client package source:
packages/loom/src/loom - server package source:
packages/loom-server/src/loom_server
Dataset rule
If a directory contains loom.md, Loom treats that directory as a dataset root.
That dataset includes CSV files under the directory and its children. If a nested child directory also has its own loom.md, it becomes a separate dataset and is not folded into the parent dataset scan.
Install
Install from PyPI:
pip install loom-data
For local development in this repository:
uv sync
uv pip install -e .
If you also want the FastAPI sync server and loom-server CLI:
uv pip install -e packages/loom-server
Initial setup
Run this once in a workspace to install the local Codex skill and initialize loom_explore as a separate git repository:
loom install
Or, if you want to be explicit:
loom install --workspace-root /path/to/workspace
This setup is what enables the scan workflow to show pending changes and later confirm them into the loom_explore git history.
Python API
Read one raw file and make sure it exists in the local raw cache:
import loom
local_path = loom.get("energy/technology-data/costs.csv")
print(local_path)
Refresh a workspace raw cache:
import loom
loom.pull("energy")
Parse chat text into a Loom request:
import loom
request = loom.parse_chat_request("loom scan energy")
print(request)
CLI overview
Main commands:
loom install
loom set-api https://loom-api-free.onrender.com
loom scan <topic>
loom route "<message>"
loom get <workspace/path/to/file>
loom pull-raw [workspace]
loom status [workspace]
loom confirm [workspace]
loom push [workspace]
loom pull [workspace]
If workspace is omitted for push, pull, or pull-raw, Loom uses all available top-level workspaces where that behavior is supported.
Scan a topic
Run a local scan:
loom scan energy
This scan is local Python logic only. It will:
- inspect
test-project/loom/loom_raw/energy - find dataset roots via
loom.md - read CSV files
- generate dataset summaries and cards
- write outputs to
test-project/loom/loom_explore/energy - print the resulting pending changes
You can also test whether a chat message would route into a Loom action:
loom route "loom scan energy"
Review and confirm scan output
After a scan:
loom status energy
loom confirm energy
loom status shows pending files plus sync metadata.
loom confirm creates a commit inside the separate loom_explore git repository so the workspace has a local confirmed state before syncing.
Read raw data
Use the CLI:
loom get energy/technology-data/costs.csv
Use the Python API:
import loom
path = loom.get("energy/technology-data/costs.csv")
Lookup behavior:
- Loom first checks
test-project/loom/.loom/raw/... - if the file is already cached locally, that path is reused
- if a matching file already exists under
test-project/loom/loom_raw/...or.raw_data/..., Loom links it into.loom/raw - otherwise Loom fetches the latest version from the Loom sync server
Repeated reads reuse the local cache.
Refresh raw cache
Refresh one workspace:
loom pull-raw energy
Or in Python:
import loom
loom.pull("energy")
loom pull-raw and loom.pull(...) compare the remote raw manifest by path + sha256 and only refresh changed or deleted files.
Push and pull workspaces
Push one workspace:
loom push energy
Pull one workspace:
loom pull energy
Pull all workspaces:
loom pull
By default, the published client now points at the current Render API:
https://loom-api-free.onrender.com
You can persist a different default per machine:
loom set-api https://loom-api-free.onrender.com
Or override it for one shell session:
export LOOM_SERVER_URL=http://127.0.0.1:8765
Current sync behavior is rebase-oriented:
pushauto-confirms pending local changes before sending- if the remote has advanced,
pushrebases local confirmed work first, then continues pullfast-forwards when possible- if local confirmed commits exist,
pullrebases them on top of the latest remote revision - rebase conflicts return a non-zero exit code and keep conflict markers in
loom_explore
After resolving a conflict, run:
loom confirm <workspace>
loom push <workspace>
Optional server commands
The published loom-data package focuses on client workflows. Server commands require the separate loom-server package.
Install it first:
pip install loom-server
Or in this repository:
uv pip install -e packages/loom-server
Then you can use:
loom server-init-db
loom server-run
Default server URL:
https://loom-api-free.onrender.com
Default database URL:
postgresql+psycopg2://loom@127.0.0.1:5432/loom
Initialize the server database:
loom server-init-db
Run the server:
loom server-run --storage-root /tmp/loom-server-storage
Scan outputs
After scanning, Loom writes files such as:
README.md: topic-level entry fileoverview.md: dataset overviewprofile.json: dataset-level machine-readable summary*.card.md: per-CSV data card*.profile.json: per-CSV machine-readable profile
Release
Bump the version in the root pyproject.toml, then build distributions:
uv build
Optionally verify the artifacts locally:
uv publish --dry-run
Upload to TestPyPI first if you want a rehearsal:
uv publish --publish-url https://test.pypi.org/legacy/
Upload to PyPI:
uv publish
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file loom_data-0.1.1.tar.gz.
File metadata
- Download URL: loom_data-0.1.1.tar.gz
- Upload date:
- Size: 40.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c585e9141deaa7d08c0a4783117a7025fc6247bfac10aff2072cf3e94d863828
|
|
| MD5 |
335a61dde1c63b80e0c43b3f97b8f0a0
|
|
| BLAKE2b-256 |
9d60306ad410dbb90fafb73e6ad448f57d643755d146750a783525f03f3d8681
|
File details
Details for the file loom_data-0.1.1-py3-none-any.whl.
File metadata
- Download URL: loom_data-0.1.1-py3-none-any.whl
- Upload date:
- Size: 43.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d61656a6109c3bd35f9ef746c5a0d1c7d42a2754512a93253111459d84d0a18
|
|
| MD5 |
ee8f23f1bf6848ec45534631eb343f37
|
|
| BLAKE2b-256 |
fe7a17e11b5017d171a41e97f7d19cba23b318414c18820f9b3fc028c036be31
|