Skip to content

Dynamic configuration with variables

Variables make dashboards dynamic by parameterizing configuration values.

Variable types

Lumen supports three types of variables:

Type Syntax Scope Evaluated
Internal variables $variables.name Within spec Dynamically at runtime
Source references $source.table.field Within spec Dynamically at runtime
External variables {{env("VAR")}} From environment Once at initialization

Use $ for internal dynamic references. Use {{}} for external values resolved at startup.

Internal variables

Internal variables create reusable parameters within your specification.

Variables section

Define variables in the variables section:

variables:
  my_variable:
    type: widget              # Makes it interactive
    kind: Select              # Widget type
    value: default_value      # Initial value
    options: [opt1, opt2]     # Available choices

Reference them anywhere using $variables.name:

sources:
  data:
    type: file
    tables:
      table: $variables.my_variable  # Uses the variable value

Widget-driven variables

Create interactive variables with widgets:

variables:
  columns:
    type: widget
    kind: MultiSelect
    value: [Open, High, Low, Close]
    options: [Open, High, Low, Close, Volume, Adj Close]
    size: 7

sources:
  stock_data:
    type: file
    tables:
      ticker: https://raw.githubusercontent.com/matplotlib/sample_data/master/aapl.csv
    kwargs:
      index_col: Date
      parse_dates: [Date]

pipelines:
  ticker_pipe:
    source: stock_data
    table: ticker
    transforms:
      - type: columns
        columns: $variables.columns    # Uses selected columns

layouts:
  - title: Stock Data
    pipeline: ticker_pipe
    views:
      - type: hvplot
        kind: line
  • Widget appears in sidebar for selecting columns
  • Changing selection updates the plot
  • Only selected columns pass through pipeline

Variable widget types

Common widget types for variables:

Widget Purpose Example
TextInput Free text entry File names, search terms
Select Single selection Category, region
MultiSelect Multiple selections Columns, tags
IntSlider Integer range Years, counts
FloatSlider Float range Thresholds, ratios
DatePicker Date selection Start/end dates
Checkbox Boolean toggle Enable/disable features

Text input variable

variables:
  ticker:
    type: widget
    kind: TextInput
    value: AAPL.csv
    placeholder: Enter ticker symbol

sources:
  stock_data:
    type: file
    tables:
      data: $variables.ticker  # Uses entered filename

Slider variable

variables:
  year:
    type: widget
    kind: IntSlider
    value: 2023
    start: 2020
    end: 2025
    step: 1

pipelines:
  filtered:
    source: data_source
    table: data
    filters:
      - type: constant
        field: year
        value: $variables.year  # Filters by slider value

Date picker variable

variables:
  start_date:
    type: widget
    kind: DatePicker
    value: '2023-01-01'
  end_date:
    type: widget
    kind: DatePicker
    value: '2023-12-31'

pipelines:
  date_filtered:
    source: data_source
    table: data
    filters:
      - type: constant
        field: date
        value: {start: $variables.start_date, end: $variables.end_date}

Source references

Reference data from sources to create dynamic relationships.

Reference syntax

Source references use $ notation:

Syntax References
$source_name The entire source object
$source_name.table_name A specific table from the source
$source_name.table_name.column Unique values from a column

Column value references

Reference unique values from a column:

sources:
  websites_csv:
    type: file
    tables:
      websites: websites.csv

  live_checker:
    type: live
    urls: $websites_csv.websites.url  # Gets unique URLs from CSV

layouts:
  - title: Website Status
    source: live_checker
    views:
      - type: table
url
https://google.com
https://python.org
https://anaconda.com

The live source checks status of all URLs found in the CSV's url column.

Chaining references

Use one source's data to configure another:

sources:
  config:
    type: file
    tables:
      settings: config.csv

  data:
    type: file
    tables:
      main: $config.settings.data_path  # Path from config
    cache_dir: $config.settings.cache_dir

Dynamic source selection

Reference sources in pipelines:

variables:
  data_source:
    type: widget
    kind: Select
    value: source_a
    options: [source_a, source_b, source_c]

pipelines:
  dynamic:
    source: $variables.data_source  # Uses selected source
    table: data

External variables (templating)

External variables inject values from outside the specification using Jinja2 syntax.

Environment variables

Read from system environment:

sources:
  database:
    type: duckdb
    uri: {{ env("DATABASE_URL") }}  # From environment

layouts:
  - title: Data for {{ env("USER") }}
    source: database
    views:
      - type: table
export DATABASE_URL="postgresql://localhost/mydb"
export USER="alice"
lumen serve dashboard.yaml

Command-line arguments

Pass variables when serving:

sources:
  data:
    type: file
    tables:
      table: {{ DATA_FILE }}  # From command line

layouts:
  - title: Dashboard for {{ USER }}
    source: data
    views:
      - type: table
lumen serve dashboard.yaml --template-vars="{'DATA_FILE': 'sales.csv', 'USER': 'Bob'}"

Shell commands

Execute shell commands for values:

sources:
  data:
    type: file
    tables:
      table: data.csv

layouts:
  - title: {{ shell("echo 'Dashboard created on $(date +%Y-%m-%d)'") }}
    source: data
    views:
      - type: table

Title becomes: "Dashboard created on 2024-01-15"

HTTP cookies

Read from request cookies:

layouts:
  - title: Dashboard for {{ cookie("username") }}
    source: data
    views:
      - type: table

HTTP headers

Read from request headers:

sources:
  data:
    type: file
    tables:
      table: data_{{ header("X-Region") }}.csv  # Region-specific file

OAuth tokens

Access OAuth user information:

config:
  auth:
    type: oauth

layouts:
  - title: Dashboard for {{ oauth("user") }}
    source: data
    views:
      - type: table

Variable scope and resolution

Resolution timing

Variable Type When Resolved
External ({{}}) Once at dashboard initialization
Internal ($) Dynamically on each update

Example:

variables:
  threshold:
    type: widget
    value: 100

sources:
  data:
    type: file
    tables:
      # Resolved once at startup
      table: {{ env("DATA_FILE") }}

pipelines:
  filtered:
    source: data
    table: table
    transforms:
      - type: query
        # Resolved dynamically when threshold changes
        query: "value > $variables.threshold"

Variable precedence

When multiple variable sources exist:

  1. External variables resolve first (initialization)
  2. Internal variables resolve during execution
  3. Later references can use earlier variables
# This works:
variables:
  base_path:
    type: widget
    value: {{ env("DATA_DIR") }}  # External first

sources:
  data:
    type: file
    tables:
      table: $variables.base_path/data.csv  # Then internal

Common patterns

User-selectable data file

variables:
  dataset:
    type: widget
    kind: Select
    value: penguins
    options: [penguins, iris, stocks]

sources:
  data:
    type: file
    tables:
      table: https://datasets.holoviz.org/$variables.dataset/v1/$variables.dataset.csv

layouts:
  - title: $variables.dataset Analysis
    source: data
    views:
      - type: table
        table: table

Dynamic filtering threshold

variables:
  min_value:
    type: widget
    kind: IntSlider
    value: 100
    start: 0
    end: 1000
    step: 10

pipelines:
  filtered:
    source: data_source
    table: data
    transforms:
      - type: query
        query: "sales >= $variables.min_value"

layouts:
  - title: Sales Above $variables.min_value
    pipeline: filtered
    views:
      - type: hvplot
        kind: bar

Configuration from file

setting,value
data_path,/data/sales.csv
cache_enabled,true
theme,dark
sources:
  config:
    type: file
    tables:
      settings: config.csv

  data:
    type: file
    tables:
      sales: $config.settings.data_path
    cache_dir: cache

config:
  theme: $config.settings.theme

layouts:
  - title: Sales Dashboard
    source: data
    views:
      - type: table

Multi-source federation

sources:
  source_list:
    type: file
    tables:
      sources: sources.csv  # Contains: name, url

  federated:
    type: file
    tables: $source_list.sources.name  # Table per row
    urls: $source_list.sources.url     # URLs from CSV

layouts:
  - title: All Sources
    source: federated
    views:
      - type: table

Environment-specific configuration

config:
  title: {{ env("APP_NAME", "My Dashboard") }}  # With default

sources:
  data:
    type: {{ env("DB_TYPE", "file") }}
    uri: {{ env("DATABASE_URL") }}
    cache_dir: {{ env("CACHE_DIR", ".cache") }}

layouts:
  - title: {{ env("ENVIRONMENT") }} Environment
    source: data
    views:
      - type: table

Best practices

When to use each type

Use Case Variable Type Why
User selections Internal ($variables) Dynamic updates
Data relationships Source references ($source) Automatic synchronization
Deployment config External ({{env()}}) Separation of concerns
Secrets External ({{env()}}) Security
Dynamic paths Both Flexibility

Security considerations

Never hardcode secrets

Don't put API keys, passwords, or tokens directly in YAML:

# ❌ Bad - secret in file
sources:
  api:
    token: "secret-api-key-12345"

# ✅ Good - secret from environment
sources:
  api:
    token: {{ env("API_KEY") }}

Set secrets via environment variables:

export API_KEY="secret-api-key-12345"
lumen serve dashboard.yaml

Variable naming

Use clear, descriptive names:

# ❌ Bad - unclear
variables:
  v1:
    type: widget
    value: 100

# ✅ Good - descriptive
variables:
  sales_threshold:
    type: widget
    value: 100

Default values

Always provide sensible defaults:

variables:
  year:
    type: widget
    kind: IntSlider
    value: 2023        # Default value
    start: 2020
    end: 2025

Next steps

Now that you can use variables: