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.3.0.tar.gz (171.9 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.3.0-py3-none-any.whl (124.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: shelves_bi-0.3.0.tar.gz
  • Upload date:
  • Size: 171.9 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.3.0.tar.gz
Algorithm Hash digest
SHA256 9cf3fafc42b66c3040ea42cee81642f46ea98b55be3a4f5023739fd340a78095
MD5 d33539e444a96888bbaf506456771d1b
BLAKE2b-256 58a2f07b42c515348e60d4756c8013423d2b5a7ceb0927c9b64bd8cf7c0efccb

See more details on using hashes here.

File details

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

File metadata

  • Download URL: shelves_bi-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 124.5 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 33e56877d77044483406733843a960650283f7413feeb707867d04714a03cb5a
MD5 3f028873615a8c409b7ecd34d5eb831d
BLAKE2b-256 9e8afa60dc2846bb21dab7c3f5c1df37b6f9dbd02c79c235532c1c43dbe72cce

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