Skip to main content

AI-native declarative visual analytics — YAML DSL to Vega-Lite translator

Project description

shelves

Declarative visual analytics for semantic models.
Write charts and dashboards in YAML, render to Vega-Lite.

Shelves charts read from a semantic model — measures, dimensions, formats, and aggregations defined once and reused everywhere, so you never copy-paste field logic across dashboards. You can back that model two ways:

  • Start with a flat file. Point a model at a local CSV, Parquet, or JSON file and Shelves queries it directly with DuckDB. shelves-import can even generate the model for you. Zero infrastructure — go from a raw file to a chart in seconds.
  • Grow into a semantic layer. Point the same model at a Cube.dev instance when you want shared governed definitions across a team. Only the model's source block changes; your charts stay untouched.

The two paths use the identical model and chart schema, so a project can graduate from file to Cube without rewriting a single chart.

Install

pip install shelves-bi

For the flat-file path, install the optional DuckDB extra:

pip install 'shelves-bi[duckdb]'

Requires Python 3.11+.

Quick start (flat file)

Generate a model from a CSV — string columns become dimensions, numeric columns become measures, dates become temporal dimensions:

shelves-import sales.csv          # writes models/sales.yaml

The generated model points at your file:

# models/sales.yaml
model: sales
label: Sales

source:
  type: file
  path: sales.csv

measures:
  revenue:
    column: Revenue
    aggregation: sum
    label: Revenue
    format: "$,.0f"

dimensions:
  category:
    column: Category
    label: Category
  order_date:
    column: Order Date
    type: temporal
    label: Order Date
    defaultGrain: month

Write a chart that references the model by name, then render:

# charts/revenue_by_category.yaml
sheet: "Revenue by Category"
data: sales

cols: category
rows: revenue
marks: bar
color: category
sort:
  field: revenue
  order: descending
shelves-render charts/revenue_by_category.yaml --models-dir models/

Output goes to output/<sheet-name-slug>.html by default. Use --out to override.

Connect to Cube

When you're ready for a governed semantic layer, point the model's source at a Cube.dev instance instead. Set your credentials in a .env file or as environment variables:

CUBE_API_URL=http://localhost:4000
CUBE_API_TOKEN=your-cube-api-token

Only the source block changes — measures, dimensions, labels, and formats are declared the same way as the file model above:

# models/orders.yaml
model: orders
label: Orders

source:
  type: cube
  cube: orders

measures:
  net_sales:
    label: Net Sales
    format: "$,.0f"
    aggregation: sum

dimensions:
  category:
    label: Category
  order_date:
    type: temporal
    label: Order Date
    defaultGrain: month
    format:
      month: "%b %Y"

Your existing charts keep working unchanged.

Project structure

A typical Shelves project looks like this:

my-project/
  models/
    sales.yaml           # semantic model definitions (file or cube source)
  charts/
    revenue_by_category.yaml
    sales_over_time.yaml
  dashboards/
    overview.yaml
  .env                   # CUBE_API_URL / CUBE_API_TOKEN (only for the Cube path)

Dashboards

Dashboards compose multiple charts into a single HTML page with layout, text, and styling:

# dashboards/overview.yaml
dashboard: "Sales Overview"
canvas: { width: 1440, height: 900 }

root:
  orientation: vertical
  contains:
    - text: "Sales Overview"
      preset: title
    - horizontal:
        contains:
          - sheet: "charts/revenue_by_category.yaml"
            width: "60%"
          - sheet: "charts/sales_over_time.yaml"
            width: "40%"
# Dashboard (charts and models resolved from directories)
shelves-render dashboards/overview.yaml --chart-dir charts/ --models-dir models/

# Dev server with live reload
shelves-dev charts/revenue_by_category.yaml --models-dir models/

Python API

from shelves import parse_chart, translate_chart, merge_theme, render_html
from shelves.data.bind import resolve_data

spec   = parse_chart(yaml_string)          # YAML -> ChartSpec
vl     = translate_chart(spec)             # ChartSpec -> Vega-Lite dict
themed = merge_theme(vl)                   # apply default theme
final  = resolve_data(themed, spec)        # query the model's source and bind
html   = render_html(final)                # standalone HTML with vegaEmbed

Each step is independent and composable.

Documentation

Development

git clone https://github.com/shelveshq/shelves.git
cd shelves
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest

License

Apache 2.0

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

shelves_bi-0.4.0.tar.gz (241.0 kB view details)

Uploaded Source

Built Distribution

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

shelves_bi-0.4.0-py3-none-any.whl (172.4 kB view details)

Uploaded Python 3

File details

Details for the file shelves_bi-0.4.0.tar.gz.

File metadata

  • Download URL: shelves_bi-0.4.0.tar.gz
  • Upload date:
  • Size: 241.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for shelves_bi-0.4.0.tar.gz
Algorithm Hash digest
SHA256 5c46dc83601f9656cabedaa1e7becf10ea0db7448352502ccc318c6577fa7e63
MD5 0db254317371ed05ec75ea02c2d5d97c
BLAKE2b-256 70f35c2d89fcd40e3754ffbedf517cd937db5dbcc57aca280bb8f41b25b6945b

See more details on using hashes here.

File details

Details for the file shelves_bi-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: shelves_bi-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 172.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for shelves_bi-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6b0fca71e07da8f5f93906b4cf1240fbd4f90d424613cd61342da0798c40eabe
MD5 c4a0c86d0912fc00ad465fff2274bfd3
BLAKE2b-256 3f27607a3e6d8ce3e119d43466697df90c880b15fce66c0b59b15fc20d5ec959

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