Python package and CLI for the ChartCoach visualization guideline catalog.
Project description
chartcoach
Python package and CLI for the ChartCoach Guideline Catalog.
Read the package docs at docs.chartcoach.dev/docs/packages/python.
For agent use, install the ChartCoach skill once, then ask the current agent to use it:
npx skills add chartcoach/skills --skill chartcoach
codex 'Use $chartcoach to access visualization design guidelines. Start by giving me a thematic overview of the catalog.'
The skill points agents to version-matched CLI-served skills. The CLI exposes catalog primitives, and task guidance lives in chartcoach skills get <name>.
The base package loads manifest-described catalog bundles, parses guidelines, and exposes typed records, Polars dataframe views, and native DuckDB SQL connections.
For application imports, add the package from the application root:
uv add chartcoach
uv add 'chartcoach[index]'
uv add 'chartcoach[mcp,index]'
from chartcoach import Catalog
catalog = Catalog.open()
catalog.guidelines().select("id", "title")
conn = catalog.duckdb()
conn.sql("select id, title from guidelines limit 5").pl()
conn.close()
Install chartcoach[index] when code needs a LanceDB table over catalog documents:
from chartcoach.search import index, search
table = index(catalog, "scratch/chartcoach-index")
docs = (
table.search("overplotted scatter plots", query_type="fts", fts_columns="text")
.where("role = 'overview'")
.limit(3)
.to_list()
)
hits = search(catalog, table, "overplotted scatter plots").to_dict()["rows"]
index(catalog, uri) writes a LanceDB table over catalog documents at the path you provide and returns the native LanceDB Table. Without an embedding function it creates a full-text table over the text column. Pass any LanceDB embedding function instance when you want LanceDB to fill the vector column from text:
from chartcoach.search import index
table = index(
catalog,
"scratch/chartcoach-index",
embedding=embedding_function,
)
Use open("scratch/chartcoach-index") for an existing table. Use chartcoach.search.lance.documents(catalog) when your code already owns a LanceDB connection and wants to call db.create_table(...) directly. Caller-owned tables should expose the catalog document columns id, parent_id, role, labels, content_hash, and text.
model(embedding_function) returns the LanceDB model used by index(..., embedding=...). It defines id, parent_id, role, labels, content_hash, text, and vector, with text bound to embedding_function.SourceField() and vector bound to embedding_function.VectorField().
Use DuckDB directly when notebooks, scripts, or agents need SQL joins over the derived catalog tables:
from chartcoach.duckdb import connect_catalog
conn = connect_catalog(catalog)
conn.sql("""
select g.id, g.title, s.content, gs.source_title
from guidelines g
join sections s on s.guideline_id = g.id
left join guideline_sources gs on gs.guideline_id = g.id
where list_contains(g.labels, 'chart:scatter:avoid')
limit 5
""").pl()
conn.close()
Write a DuckDB database file when another tool needs durable SQL tables:
duckdb_path = "scratch/catalog.duckdb"
catalog.write_duckdb(duckdb_path, overwrite=True)
The LanceDB index root can also be attached through DuckDB's Lance extension:
INSTALL lance;
LOAD lance;
ATTACH 'scratch/chartcoach-index' AS cc_index (TYPE LANCE);
select id, parent_id, role
from cc_index.main.catalog_documents
limit 5;
Run one-off CLI commands with uvx chartcoach --help.
These commands read the package-pinned default catalog artifact, inspect table schemas, write DuckDB tables, read guideline sections, and query indexed guideline rows.
uvx chartcoach catalog manifest --format markdown
uvx chartcoach catalog schema --tables --row-counts --format jsonl
uvx chartcoach catalog schema guidelines --format jsonl
uvx chartcoach catalog values labels \
--contains chart: --format jsonl
uvx chartcoach catalog sql \
"select id, title from guidelines where list_contains(labels, 'chart:bar')" \
--format jsonl
DUCKDB_PATH=scratch/catalog.duckdb
uvx chartcoach catalog export duckdb \
--out "$DUCKDB_PATH"
duckdb "$DUCKDB_PATH" \
-c "select id, title from guidelines where list_contains(labels, 'chart:bar')"
uvx chartcoach catalog query \
--label chart:bar --format jsonl
uvx chartcoach catalog read <guideline-id> \
--section <role-from-manifest> --source-detail minimal --format jsonl
uvx chartcoach catalog cite <guideline-id> \
--format markdown
INDEX_PATH=scratch/chartcoach-index
uvx --from 'chartcoach[index]' chartcoach catalog index create --index "$INDEX_PATH"
uvx --from 'chartcoach[index]' chartcoach catalog find \
--index "$INDEX_PATH" \
--where "role = 'overview'" \
"overplotted scatter plot with too many points" --format jsonl
Every row-oriented command supports --format jsonl, so shell tools can handle projection and token control. Human table output uses rounded, wrapped columns for terminal scanning. JSON, JSONL, and CSV keep machine-readable stdout.
uvx chartcoach catalog schema --format jsonl |
jq 'select(.table == "sections")'
The default catalog comes from package-pinned release metadata under https://artifacts.chartcoach.dev/catalog/releases/<version>/<digest>/metadata.json and is cached under the user's platform cache directory. The local cache mirrors the release layout at catalog/releases/<version>/<digest>/. Normal catalog reads download MANIFEST.md and entries.parquet. Heavier derived artifacts such as LanceDB indexes stay described in metadata until a caller asks for them. First-download notices go to stderr, so JSON, JSONL, and CSV stdout stay parseable. catalog export duckdb creates a DuckDB database file with the derived catalog tables. Use catalog schema, catalog values, and catalog roles before writing SQL against an unfamiliar catalog. catalog read returns deterministic catalog records. catalog find deduplicates indexed document matches to guideline-level typed rows.
Run catalog-only MCP tools with chartcoach[mcp]. Include index when agents
will call search tools.
uvx --from 'chartcoach[mcp]' chartcoach mcp serve
uvx --from 'chartcoach[mcp,index]' chartcoach mcp serve \
--index scratch/chartcoach-index
Without an index, the MCP server exposes only sql. Pass --index to also register search against an existing LanceDB table.
Run package tests from the repository root:
uv run --package chartcoach --all-extras pytest packages/catalog-python/tests
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
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 chartcoach-0.1.2.tar.gz.
File metadata
- Download URL: chartcoach-0.1.2.tar.gz
- Upload date:
- Size: 65.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a532676fe16b57803362d7bfb2d28252479461930ffe2d934c2297c51015b10d
|
|
| MD5 |
4bb08258603418a10e5523be650e622a
|
|
| BLAKE2b-256 |
5b5f999f124df9f6e57c57d9f683ba99817ceb44e2dc9ac1bc8f7bbb8ce612c1
|
File details
Details for the file chartcoach-0.1.2-py3-none-any.whl.
File metadata
- Download URL: chartcoach-0.1.2-py3-none-any.whl
- Upload date:
- Size: 90.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac3ae1c3cdd0ef27ae77906a0bddf6df6b62360a54d66a11f826b65807eeb2d1
|
|
| MD5 |
28da97edb170648feb16b2c1dee78a13
|
|
| BLAKE2b-256 |
2164e293234f3b1a1a7051612de18bfaa683cf1860119c4b7104aa0415ff4350
|