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¶
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¶
requirements.txt¶
Data Explorer¶
A two-step app: load sample data, then filter it with a dropdown and display a chart.
Project Structure¶
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¶
requirements.txt¶
Interactive Dashboard¶
A dashboard step with Infographic metrics, multiple plots, and a table — all in a grid layout.
Project Structure¶
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¶
requirements.txt¶
Button Callbacks¶
Demonstrates all five callback types: standard event, page update, drilldown, container toggle, and asset download.
Project Structure¶
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])