Skip to content

Example Gallery

Complete, copy-pasteable example apps to learn Virtualitics SDK patterns.

Hello World

The simplest possible app — a single step that displays a greeting.

Project Structure

hello_world/
├── __init__.py
├── app.py
└── requirements.txt

app.py

from virtualitics_sdk import App, Step, StepType, Page, Section, Card, RichText

class HelloStep(Step):
    """A simple step that displays a greeting."""

    def run(self, flow_metadata):
        return Page(
            title="Hello World",
            sections=[
                Section(
                    title="Welcome",
                    cards=[
                        Card(
                            title="Greeting",
                            content=[
                                RichText("# Hello from Virtualitics SDK!\n\n"
                                         "This is your first app. Edit the `run()` method "
                                         "to build something amazing.")
                            ]
                        )
                    ]
                )
            ]
        )

# --- App definition ---

hello_step = HelloStep(
    title="Hello",
    description="A simple greeting",
    parent="Main",
    type=StepType.RESULTS,
    page=Page(title="Loading...", sections=[])
)

app = App(
    name="Hello World",
    description="My first Virtualitics app"
)
app.chain([hello_step])

__init__.py

from .app import app

__all__ = ["app"]

requirements.txt

virtualitics-sdk>=1.54.0

Data Explorer

A two-step app: load sample data, then filter it with a dropdown and display a chart.

Project Structure

data_explorer/
├── __init__.py
├── app.py
└── requirements.txt

app.py

from virtualitics_sdk import (
    App, Step, StepType, Page, Section, Card,
    Table, PlotlyPlot, SingleDropdown, Dataset
)
import pandas as pd
import plotly.express as px


class LoadDataStep(Step):
    """Load sample sales data and display it."""

    def run(self, flow_metadata):
        df = pd.DataFrame({
            "Month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
            "Region": ["North", "South", "North", "West", "East", "South"],
            "Product": ["Widget A", "Widget B", "Widget A", "Widget C", "Widget B", "Widget A"],
            "Sales": [1200, 800, 1500, 950, 1100, 1350],
        })

        self._outLink.sales_data = Dataset(name="Sales Data", data=df)

        return Page(
            title="Data Loaded",
            sections=[
                Section(
                    title="Sales Data",
                    cards=[
                        Card(
                            title=f"Loaded {len(df)} rows",
                            content=[Table(data=df)]
                        )
                    ]
                )
            ]
        )


class FilterStep(Step):
    """Filter data by region and visualize."""

    def run(self, flow_metadata):
        df = self._inLink.sales_data.data
        regions = sorted(df["Region"].unique().tolist())

        dropdown = SingleDropdown(
            id="region_filter",
            title="Select Region",
            options=regions,
            default=regions[0]
        )

        # Show all data initially
        fig = px.bar(df, x="Month", y="Sales", color="Product", title="Sales by Month")

        return Page(
            title="Filter & Visualize",
            sections=[
                Section(
                    title="Filters",
                    cards=[Card(title="Region", content=[dropdown])]
                ),
                Section(
                    title="Results",
                    cards=[
                        Card(title="Chart", content=[PlotlyPlot(figure=fig)]),
                        Card(title="Data", content=[Table(data=df)])
                    ]
                )
            ]
        )

    def action(self, flow_metadata):
        df = self._inLink.sales_data.data
        selected = self.page.get_element_by_id("region_filter").value

        filtered = df[df["Region"] == selected]

        fig = px.bar(
            filtered, x="Month", y="Sales", color="Product",
            title=f"Sales in {selected}"
        )

        regions = sorted(df["Region"].unique().tolist())
        dropdown = SingleDropdown(
            id="region_filter",
            title="Select Region",
            options=regions,
            default=selected
        )

        return Page(
            title=f"Region: {selected}",
            sections=[
                Section(
                    title="Filters",
                    cards=[Card(title="Region", content=[dropdown])]
                ),
                Section(
                    title=f"Results for {selected}",
                    cards=[
                        Card(title="Chart", content=[PlotlyPlot(figure=fig)]),
                        Card(title="Data", content=[Table(data=filtered)])
                    ]
                )
            ]
        )


# --- App definition ---

load_step = LoadDataStep(
    title="Load Data",
    description="Load sales data",
    parent="Data",
    type=StepType.INPUT,
    page=Page(title="Loading...", sections=[])
)

filter_step = FilterStep(
    title="Explore",
    description="Filter and visualize",
    parent="Analysis",
    type=StepType.DASHBOARD,
    page=Page(title="Loading...", sections=[])
)

app = App(
    name="Data Explorer",
    description="Load, filter, and chart sales data",
    is_shareable=True
)
app.chain([load_step, filter_step])

__init__.py

from .app import app

__all__ = ["app"]

requirements.txt

virtualitics-sdk>=1.54.0
pandas>=2.0.0
plotly>=5.0.0

Interactive Dashboard

A dashboard step with Infographic metrics, multiple plots, and a table — all in a grid layout.

Project Structure

dashboard_app/
├── __init__.py
├── app.py
└── requirements.txt

app.py

from virtualitics_sdk import (
    App, Step, StepType, Page, Section, Card, Dataset,
    Table, PlotlyPlot, Dashboard, Row, Column, DashboardOrientation,
    Infographic, InfographData, InfographDataType, InfographicOrientation,
    RichText
)
import pandas as pd
import plotly.express as px


class PrepareDataStep(Step):
    """Generate and store sample data."""

    def run(self, flow_metadata):
        df = pd.DataFrame({
            "Date": pd.date_range("2025-01-01", periods=90, freq="D"),
            "Revenue": [round(100 + i * 2.5 + (i % 7) * 10, 2) for i in range(90)],
            "Orders": [10 + i % 15 for i in range(90)],
            "Category": ["Electronics" if i % 3 == 0 else "Clothing" if i % 3 == 1 else "Food" for i in range(90)],
        })

        self._outLink.data = Dataset(name="Daily Metrics", data=df)

        return Page(
            title="Data Ready",
            sections=[
                Section(
                    title="Preview",
                    cards=[Card(title="Sample", content=[Table(data=df.head(10))])]
                )
            ]
        )


class DashboardStep(Step):
    """Display a rich dashboard with metrics, charts, and data."""

    def run(self, flow_metadata):
        df = self._inLink.data.data

        # Metrics
        metrics = Infographic(
            id="kpi_metrics",
            title="Key Metrics",
            data=[
                InfographData(
                    label="Total Revenue",
                    value=f"${df['Revenue'].sum():,.0f}",
                    type=InfographDataType.CURRENCY
                ),
                InfographData(
                    label="Total Orders",
                    value=str(df["Orders"].sum()),
                    type=InfographDataType.NUMBER
                ),
                InfographData(
                    label="Avg Order Value",
                    value=f"${df['Revenue'].sum() / df['Orders'].sum():,.2f}",
                    type=InfographDataType.CURRENCY
                ),
            ],
            orientation=InfographicOrientation.HORIZONTAL
        )

        # Trend line
        trend_fig = px.line(df, x="Date", y="Revenue", title="Revenue Trend")
        trend_plot = PlotlyPlot(id="trend_plot", figure=trend_fig)

        # Category breakdown
        cat_summary = df.groupby("Category")["Revenue"].sum().reset_index()
        cat_fig = px.pie(cat_summary, names="Category", values="Revenue", title="Revenue by Category")
        cat_plot = PlotlyPlot(id="category_plot", figure=cat_fig)

        # Data table
        data_table = Table(id="data_table", data=df)

        # Assemble dashboard
        dashboard = Dashboard(
            id="main_dashboard",
            title="Sales Dashboard",
            orientation=DashboardOrientation.VERTICAL,
            content=[
                Row(content=[metrics]),
                Row(content=[
                    Column(content=[trend_plot]),
                    Column(content=[cat_plot])
                ]),
                Row(content=[data_table])
            ]
        )

        return Page(
            title="Dashboard",
            sections=[
                Section(
                    title="Sales Overview",
                    cards=[Card(title="Dashboard", content=[dashboard])]
                )
            ]
        )


# --- App definition ---

prep_step = PrepareDataStep(
    title="Prepare Data",
    description="Generate sample metrics",
    parent="Data",
    type=StepType.INPUT,
    page=Page(title="Loading...", sections=[])
)

dash_step = DashboardStep(
    title="Dashboard",
    description="View dashboard",
    parent="Results",
    type=StepType.DASHBOARD,
    page=Page(title="Loading...", sections=[])
)

app = App(
    name="Interactive Dashboard",
    description="A dashboard with KPIs, charts, and data",
    is_shareable=True
)
app.chain([prep_step, dash_step])

__init__.py

from .app import app

__all__ = ["app"]

requirements.txt

virtualitics-sdk>=1.54.0
pandas>=2.0.0
plotly>=5.0.0

Button Callbacks

Demonstrates all five callback types: standard event, page update, drilldown, container toggle, and asset download.

Project Structure

callback_demo/
├── __init__.py
├── app.py
└── requirements.txt

app.py

from virtualitics_sdk import (
    App, Step, StepType, Page, Section, Card, Container,
    Button, ButtonStyle, ButtonColor, RichText, Table, StoreInterface
)
from virtualitics_sdk.types.callbacks import (
    standard_event_callback,
    page_update_callback,
    drilldown_callback,
    ContainerToggleCallback,
    AssetDownloadCallback,
)
from virtualitics_sdk.page.drilldown import DrilldownType, DrilldownSize
from virtualitics_sdk.store.drilldown_store_interface import DrilldownStoreInterface
import pandas as pd
from datetime import datetime


# --- Callbacks ---

@standard_event_callback
async def notify_user(store_interface: StoreInterface) -> str:
    """Returns a message displayed as a toast notification."""
    return f"Action completed at {datetime.now().strftime('%H:%M:%S')}"


@page_update_callback
async def refresh_timestamp(store_interface: StoreInterface) -> None:
    """Modifies the page in place — changed elements re-render automatically."""
    page = await store_interface.get_page()
    text_elem = page.get_element_by_id("timestamp_text")
    text_elem.content = f"**Last refreshed:** {datetime.now().strftime('%H:%M:%S')}"


@drilldown_callback(
    drilldown_type=DrilldownType.FAST_MODAL,
    drilldown_size=DrilldownSize.LARGE
)
async def show_detail_modal(
    card: Card,
    input_data: dict[str, str | float | int],
    store_interface: DrilldownStoreInterface
) -> None:
    """Opens a modal overlay with custom content."""
    sample_df = pd.DataFrame({
        "Metric": ["Accuracy", "Precision", "Recall", "F1"],
        "Value": [0.94, 0.91, 0.89, 0.90],
    })
    card.add_content([
        RichText(content="## Model Performance Details\n\n"
                         "Below are the detailed evaluation metrics."),
        Table(data=sample_df)
    ])


class CallbackDemoStep(Step):
    """Showcases all five callback types."""

    def run(self, flow_metadata):
        # Hidden container toggled by a button
        detail_container = Container(
            id="extra_details",
            title="Extra Details",
            visible=False
        )
        detail_container.add_content([
            RichText(content="This content was hidden and revealed by "
                             "a **ContainerToggleCallback**.")
        ])

        return Page(
            title="Callback Demo",
            sections=[
                # 1. Standard Event
                Section(
                    title="1. Standard Event Callback",
                    cards=[
                        Card(
                            title="Toast Notification",
                            content=[
                                RichText("Clicking this button returns a message "
                                         "without re-rendering the page."),
                                Button(
                                    id="notify_btn",
                                    title="Notify",
                                    label="Show Notification",
                                    style=ButtonStyle.PRIMARY,
                                    color=ButtonColor.ACCENT,
                                    show_confirmation=False,
                                    on_click=notify_user
                                )
                            ]
                        )
                    ]
                ),
                # 2. Page Update
                Section(
                    title="2. Page Update Callback",
                    cards=[
                        Card(
                            title="Live Refresh",
                            content=[
                                RichText(
                                    id="timestamp_text",
                                    content="**Last refreshed:** never"
                                ),
                                Button(
                                    id="refresh_btn",
                                    title="Refresh",
                                    label="Update Timestamp",
                                    style=ButtonStyle.SECONDARY,
                                    color=ButtonColor.ACCENT,
                                    show_confirmation=False,
                                    on_click=refresh_timestamp
                                )
                            ]
                        )
                    ]
                ),
                # 3. Drilldown
                Section(
                    title="3. Drilldown Callback",
                    cards=[
                        Card(
                            title="Modal Details",
                            content=[
                                RichText("Opens a modal overlay with a table."),
                                Button(
                                    id="drilldown_btn",
                                    title="Details",
                                    label="View Details",
                                    style=ButtonStyle.PRIMARY,
                                    color=ButtonColor.BLUE,
                                    show_confirmation=False,
                                    on_click=show_detail_modal
                                )
                            ]
                        )
                    ]
                ),
                # 4. Container Toggle
                Section(
                    title="4. Container Toggle Callback",
                    cards=[
                        Card(
                            title="Show / Hide Content",
                            content=[
                                RichText("Toggle the container below without "
                                         "a full page refresh."),
                                Button(
                                    id="toggle_btn",
                                    title="Toggle",
                                    label="Show Details",
                                    style=ButtonStyle.SECONDARY,
                                    color=ButtonColor.NEUTRAL,
                                    show_confirmation=False,
                                    on_click=ContainerToggleCallback(
                                        visible=True,
                                        container_id="extra_details"
                                    )
                                )
                            ]
                        ),
                        detail_container
                    ]
                ),
                # 5. Asset Download
                Section(
                    title="5. Asset Download Callback",
                    cards=[
                        Card(
                            title="Download a File",
                            content=[
                                RichText("Triggers a file download when clicked."),
                                Button(
                                    id="download_btn",
                                    title="Download",
                                    label="Download CSV",
                                    style=ButtonStyle.PRIMARY,
                                    color=ButtonColor.GREEN,
                                    show_confirmation=False,
                                    on_click=AssetDownloadCallback(),
                                    extension=".csv",
                                    mime_type="text/csv"
                                )
                            ]
                        )
                    ]
                ),
            ]
        )


# --- App definition ---

demo_step = CallbackDemoStep(
    title="Callbacks",
    description="Explore callback types",
    parent="Demo",
    type=StepType.RESULTS,
    page=Page(title="Loading...", sections=[])
)

app = App(
    name="Button Callback Demo",
    description="Demonstrates all five callback types"
)
app.chain([demo_step])

__init__.py

from .app import app

__all__ = ["app"]

requirements.txt

virtualitics-sdk>=1.54.0
pandas>=2.0.0