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.5.0.tar.gz (895.5 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.5.0-py3-none-any.whl (803.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: shelves_bi-0.5.0.tar.gz
  • Upload date:
  • Size: 895.5 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.5.0.tar.gz
Algorithm Hash digest
SHA256 8ad22425adc11daa7b05d57089c68408d5128a1ef99317759463cf30c13170fb
MD5 edc9a639ac1f7aa6ab3b38e9730906f4
BLAKE2b-256 efcd6c6388485a8cdce1a2d747c2f1eaa33e3f032d47caf99a73df6e264cd80e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: shelves_bi-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 803.8 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.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0f77b5051f0ad83e2a6cecde3cacb8d3d17bed341cc05c0c4a59fb26e442e6dc
MD5 edf3ab1a81b6c19d350c75e4ee9bcd4a
BLAKE2b-256 2e6e0b89750e46acefa59a063d9f7d1d4ebca2d22b7e797b04bdf0220d5e5988

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