Skip to main content

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/python. Read the catalog contract at docs.chartcoach.dev/catalog.

For agent use, install the chartcoach skill once, then ask the current agent to use it:

npx skills add chartcoach/skills
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 indexed discovery. With the Default Catalog, open the package-pinned LanceDB index from the chartcoach platformdirs cache:

from chartcoach.catalog import default_index_path
from chartcoach.search import open as open_index, search

table = open_index(default_index_path(table_name="catalog_documents"))

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"]

The first default_index_path() call downloads and extracts the default index under artifacts/catalog/releases/<version>/<digest>/indexes/lancedb/<provider>/<model>/. The cache keeps index.tar.gz at the same relative path as the published object and extracts the LanceDB table into the sibling db/ directory. Later calls reuse the local cache when the archive matches release metadata and the LanceDB table is present.

Use index(catalog, uri) when code needs to create a caller-owned LanceDB table. It writes the table 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,
    "./chartcoach-index",
    embedding=embedding_function,
)

Use open("./chartcoach-index") for an existing caller-owned 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 = "./chartcoach-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 './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@latest --help.

These commands read the package-pinned Default Catalog release, inspect table schemas, write DuckDB tables, read guideline sections, and query indexed guideline rows. The @latest selector follows the newest published package. Use chartcoach@0.1.3 when output must stay tied to the 0.1.3 Default Catalog release.

uvx chartcoach@latest catalog manifest --format markdown
uvx chartcoach@latest catalog schema --tables --row-counts --format jsonl
uvx chartcoach@latest catalog schema guidelines --format jsonl
uvx chartcoach@latest catalog values labels \
  --contains chart: --format jsonl
uvx chartcoach@latest catalog sql \
  "select id, title from guidelines where list_contains(labels, 'chart:bar')" \
  --format jsonl
DUCKDB_PATH=./chartcoach-catalog.duckdb
uvx chartcoach@latest catalog export duckdb \
  --out "$DUCKDB_PATH"
duckdb "$DUCKDB_PATH" \
  -c "select id, title from guidelines where list_contains(labels, 'chart:bar')"
uvx chartcoach@latest catalog query \
  --label chart:bar --format jsonl
GUIDELINE_ID="$(
  uvx chartcoach@latest catalog query \
    --contains "pie chart" \
    --limit 1 \
    --format json |
    jq -r '.[0].id'
)"
uvx chartcoach@latest catalog read "$GUIDELINE_ID" \
  --source-detail minimal --format jsonl
uvx chartcoach@latest catalog cite "$GUIDELINE_ID" \
  --format markdown
uvx --from 'chartcoach[index]@latest' chartcoach catalog find \
  --mode fts \
  --limit 3 \
  "overplotted scatter plot with too many points" --format jsonl
uvx --from 'chartcoach[index]@latest' chartcoach catalog index info \
  --format json
uvx chartcoach@latest catalog cache versions --format jsonl
uvx chartcoach@latest catalog cache list
uvx chartcoach@latest catalog cache clear
uvx --from 'chartcoach[index]@latest' chartcoach catalog cache pull
INDEX_PATH=./chartcoach-index
uvx --from 'chartcoach[index]@latest' chartcoach catalog index create --index "$INDEX_PATH"
uvx --from 'chartcoach[index]@latest' chartcoach catalog find \
  --index "$INDEX_PATH" \
  --where "role = 'overview'" \
  "overplotted scatter plot with too many points" --format jsonl

The package selector after --from installs the package with extras. The following chartcoach token is the executable to run. With the Default Catalog, indexed find can resolve the package-pinned default index when --index is omitted. The first default indexed command downloads and extracts the LanceDB archive below the chartcoach artifact cache root: artifacts/catalog/releases/<version>/<digest>/indexes/lancedb/<provider>/<model>/. Later default indexed commands reuse that local copy. The default examples use --mode fts so no embedding credential is needed. Pass --index for a caller-owned local index or a custom catalog source.

catalog cache versions reads the root artifact index at https://artifacts.chartcoach.dev/index.json. catalog cache pull downloads the newest listed release into the chartcoach artifact cache. By default it also downloads and extracts the release's default LanceDB archive.

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@latest catalog schema --format jsonl |
  jq 'select(.table == "sections")'

The Default Catalog is the package-pinned chartcoach Guideline Catalog release. It comes from release metadata under https://artifacts.chartcoach.dev/catalog/releases/<version>/<digest>/metadata.json and is cached under the artifacts/ directory inside the user's platform cache directory. The local cache mirrors the release layout at artifacts/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. All chartcoach-owned default artifacts use this platformdirs cache layout. Print the exact artifact root for the current user with:

uvx --from chartcoach@latest python -c "from chartcoach.catalog.remote import cache_root; print(cache_root() / 'artifacts')"

The current Default Catalog contains 781 guideline records and 262 source references. It follows the curation scheme described in Structured Visualization Design Knowledge for Grounding Generative Reasoning and Situated Feedback, combining 100+ visualization perception and cognitive science papers, accessibility criteria, data journalism, rhetorical visualization research, and 36 practitioner posts from Datawrapper's Data Vis Do's & Don'ts series.

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]@latest' chartcoach mcp serve
uvx --from 'chartcoach[mcp,index]@latest' chartcoach mcp serve \
  --index ./chartcoach-index

Without an index, the MCP server exposes only sql. Pass --index to also register search against a caller-owned 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chartcoach-0.1.3.tar.gz (69.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chartcoach-0.1.3-py3-none-any.whl (95.5 kB view details)

Uploaded Python 3

File details

Details for the file chartcoach-0.1.3.tar.gz.

File metadata

  • Download URL: chartcoach-0.1.3.tar.gz
  • Upload date:
  • Size: 69.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for chartcoach-0.1.3.tar.gz
Algorithm Hash digest
SHA256 83675096942868d0f4f666a1729696217f3cc061b15144c5eb9be082104e81b3
MD5 cae0aceb15c4a2fc06b459f84af9224b
BLAKE2b-256 c4d974c0b6a11b3df32fd8afdffa49ea71eb9d940ad5664567a057fae5120665

See more details on using hashes here.

File details

Details for the file chartcoach-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: chartcoach-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 95.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for chartcoach-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 e8c4752dd50cb102e639e36fc56fa4f4d86c2d2de6c65f2c722c27a9160e1f47
MD5 913563db9f16deeadabdb55cd2370e05
BLAKE2b-256 61e9443f6db73c6ee5a39d89692592cc191a0e2cd1c80f8547606f820c7501b7

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 Pingdom Monitoring Sentry Error logging StatusPage Status page