axiom-coding-agent-setup 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.agents/skills/agent-browser/SKILL.md +55 -0
  2. package/.agents/skills/developing-with-streamlit/SKILL.md +220 -0
  3. package/.agents/skills/developing-with-streamlit/skills/building-streamlit-chat-ui/SKILL.md +195 -0
  4. package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/SKILL.md +233 -0
  5. package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/references/packaged-components.md +212 -0
  6. package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/references/state-sync.md +149 -0
  7. package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/references/theme-css-variables.md +243 -0
  8. package/.agents/skills/developing-with-streamlit/skills/building-streamlit-custom-components-v2/references/troubleshooting.md +121 -0
  9. package/.agents/skills/developing-with-streamlit/skills/building-streamlit-dashboards/SKILL.md +147 -0
  10. package/.agents/skills/developing-with-streamlit/skills/building-streamlit-multipage-apps/SKILL.md +218 -0
  11. package/.agents/skills/developing-with-streamlit/skills/choosing-streamlit-selection-widgets/SKILL.md +139 -0
  12. package/.agents/skills/developing-with-streamlit/skills/connecting-streamlit-to-snowflake/SKILL.md +188 -0
  13. package/.agents/skills/developing-with-streamlit/skills/creating-streamlit-themes/SKILL.md +486 -0
  14. package/.agents/skills/developing-with-streamlit/skills/displaying-streamlit-data/SKILL.md +199 -0
  15. package/.agents/skills/developing-with-streamlit/skills/improving-streamlit-design/SKILL.md +191 -0
  16. package/.agents/skills/developing-with-streamlit/skills/optimizing-streamlit-performance/SKILL.md +323 -0
  17. package/.agents/skills/developing-with-streamlit/skills/organizing-streamlit-code/SKILL.md +91 -0
  18. package/.agents/skills/developing-with-streamlit/skills/setting-up-streamlit-environment/SKILL.md +128 -0
  19. package/.agents/skills/developing-with-streamlit/skills/using-streamlit-cli/SKILL.md +165 -0
  20. package/.agents/skills/developing-with-streamlit/skills/using-streamlit-custom-components/SKILL.md +170 -0
  21. package/.agents/skills/developing-with-streamlit/skills/using-streamlit-layouts/SKILL.md +229 -0
  22. package/.agents/skills/developing-with-streamlit/skills/using-streamlit-markdown/SKILL.md +207 -0
  23. package/.agents/skills/developing-with-streamlit/skills/using-streamlit-session-state/SKILL.md +144 -0
  24. package/.agents/skills/developing-with-streamlit/templates/.gitattributes +3 -0
  25. package/.agents/skills/developing-with-streamlit/templates/apps/README.md +188 -0
  26. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-companies/pyproject.toml +12 -0
  27. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-companies/streamlit_app.py +365 -0
  28. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute/pyproject.toml +12 -0
  29. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute/streamlit_app.py +461 -0
  30. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute-snowflake/.streamlit/secrets.toml.example +20 -0
  31. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute-snowflake/pyproject.toml +11 -0
  32. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute-snowflake/snowflake.yml +18 -0
  33. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-compute-snowflake/streamlit_app.py +527 -0
  34. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-feature-usage/pyproject.toml +12 -0
  35. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-feature-usage/streamlit_app.py +307 -0
  36. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics/pyproject.toml +12 -0
  37. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics/streamlit_app.py +426 -0
  38. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics-snowflake/.streamlit/secrets.toml.example +20 -0
  39. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics-snowflake/pyproject.toml +11 -0
  40. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics-snowflake/snowflake.yml +18 -0
  41. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-metrics-snowflake/streamlit_app.py +463 -0
  42. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-seattle-weather/pyproject.toml +12 -0
  43. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-seattle-weather/streamlit_app.py +252 -0
  44. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers/pyproject.toml +12 -0
  45. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers/streamlit_app.py +342 -0
  46. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers-snowflake/.streamlit/secrets.toml.example +20 -0
  47. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers-snowflake/pyproject.toml +11 -0
  48. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers-snowflake/snowflake.yml +18 -0
  49. package/.agents/skills/developing-with-streamlit/templates/apps/dashboard-stock-peers-snowflake/streamlit_app.py +384 -0
  50. package/.agents/skills/developing-with-streamlit/templates/themes/README.md +128 -0
  51. package/.agents/skills/developing-with-streamlit/templates/themes/_configs/dracula.toml +39 -0
  52. package/.agents/skills/developing-with-streamlit/templates/themes/_configs/github.toml +37 -0
  53. package/.agents/skills/developing-with-streamlit/templates/themes/_configs/minimal.toml +39 -0
  54. package/.agents/skills/developing-with-streamlit/templates/themes/_configs/nord.toml +39 -0
  55. package/.agents/skills/developing-with-streamlit/templates/themes/_configs/snowflake.toml +42 -0
  56. package/.agents/skills/developing-with-streamlit/templates/themes/_configs/solarized-light.toml +38 -0
  57. package/.agents/skills/developing-with-streamlit/templates/themes/_configs/spotify.toml +34 -0
  58. package/.agents/skills/developing-with-streamlit/templates/themes/_configs/stripe.toml +35 -0
  59. package/.agents/skills/developing-with-streamlit/templates/themes/_shared/streamlit_app.py +336 -0
  60. package/.agents/skills/developing-with-streamlit/templates/themes/_templates/pyproject.toml.tmpl +12 -0
  61. package/.agents/skills/developing-with-streamlit/templates/themes/dracula/.streamlit/config.toml +39 -0
  62. package/.agents/skills/developing-with-streamlit/templates/themes/dracula/pyproject.toml +10 -0
  63. package/.agents/skills/developing-with-streamlit/templates/themes/dracula/streamlit_app.py +337 -0
  64. package/.agents/skills/developing-with-streamlit/templates/themes/github/.streamlit/config.toml +37 -0
  65. package/.agents/skills/developing-with-streamlit/templates/themes/github/pyproject.toml +10 -0
  66. package/.agents/skills/developing-with-streamlit/templates/themes/github/streamlit_app.py +337 -0
  67. package/.agents/skills/developing-with-streamlit/templates/themes/manage.py +332 -0
  68. package/.agents/skills/developing-with-streamlit/templates/themes/minimal/.streamlit/config.toml +39 -0
  69. package/.agents/skills/developing-with-streamlit/templates/themes/minimal/pyproject.toml +10 -0
  70. package/.agents/skills/developing-with-streamlit/templates/themes/minimal/streamlit_app.py +337 -0
  71. package/.agents/skills/developing-with-streamlit/templates/themes/nord/.streamlit/config.toml +39 -0
  72. package/.agents/skills/developing-with-streamlit/templates/themes/nord/pyproject.toml +10 -0
  73. package/.agents/skills/developing-with-streamlit/templates/themes/nord/streamlit_app.py +337 -0
  74. package/.agents/skills/developing-with-streamlit/templates/themes/snowflake/.streamlit/config.toml +42 -0
  75. package/.agents/skills/developing-with-streamlit/templates/themes/snowflake/pyproject.toml +10 -0
  76. package/.agents/skills/developing-with-streamlit/templates/themes/snowflake/streamlit_app.py +337 -0
  77. package/.agents/skills/developing-with-streamlit/templates/themes/solarized-light/.streamlit/config.toml +38 -0
  78. package/.agents/skills/developing-with-streamlit/templates/themes/solarized-light/pyproject.toml +10 -0
  79. package/.agents/skills/developing-with-streamlit/templates/themes/solarized-light/streamlit_app.py +337 -0
  80. package/.agents/skills/developing-with-streamlit/templates/themes/spotify/.streamlit/config.toml +34 -0
  81. package/.agents/skills/developing-with-streamlit/templates/themes/spotify/pyproject.toml +10 -0
  82. package/.agents/skills/developing-with-streamlit/templates/themes/spotify/streamlit_app.py +337 -0
  83. package/.agents/skills/developing-with-streamlit/templates/themes/stripe/.streamlit/config.toml +35 -0
  84. package/.agents/skills/developing-with-streamlit/templates/themes/stripe/pyproject.toml +10 -0
  85. package/.agents/skills/developing-with-streamlit/templates/themes/stripe/streamlit_app.py +337 -0
  86. package/.agents/skills/fastapi/SKILL.md +436 -0
  87. package/.agents/skills/fastapi/references/dependencies.md +142 -0
  88. package/.agents/skills/fastapi/references/other-tools.md +76 -0
  89. package/.agents/skills/fastapi/references/streaming.md +105 -0
  90. package/.agents/skills/frontend-design/LICENSE.txt +177 -0
  91. package/.agents/skills/frontend-design/SKILL.md +42 -0
  92. package/.agents/skills/gradio/SKILL.md +84 -0
  93. package/.agents/skills/gradio/references/api-signatures.md +115 -0
  94. package/.agents/skills/gradio/references/event-listeners.md +130 -0
  95. package/.agents/skills/gradio/references/examples.md +613 -0
  96. package/.agents/skills/ui-ux-pro-max/SKILL.md +659 -0
  97. package/.agents/skills/ui-ux-pro-max/data +1 -0
  98. package/.agents/skills/ui-ux-pro-max/scripts +1 -0
  99. package/.env.axiom +8 -0
  100. package/AGENTS.md +2 -1
  101. package/README.md +19 -3
  102. package/bin/cli.js +11 -1
  103. package/opencode.json +7 -4
  104. package/package.json +1 -1
  105. package/skills-lock.json +36 -0
  106. package/.agents/skills/n8n-patterns/SKILL.md +0 -272
@@ -0,0 +1,426 @@
1
+ """
2
+ Metrics Dashboard Template
3
+
4
+ A comprehensive metrics dashboard demonstrating:
5
+ - Time series visualization with Altair (line, area, bar, point charts)
6
+ - Metric cards with chart/table toggle and popover filters
7
+ - Time range filtering (1M, 6M, 1Y, QTD, YTD, All)
8
+ - Line options (Daily, 7-day MA)
9
+
10
+ This template uses synthetic data. Replace the generate_*_data() functions
11
+ with your own data sources (e.g., Snowflake queries, APIs, etc.)
12
+ """
13
+
14
+ from datetime import date, timedelta
15
+ import numpy as np
16
+ import pandas as pd
17
+ import streamlit as st
18
+ import altair as alt
19
+
20
+ st.set_page_config(
21
+ page_title="Metrics Dashboard",
22
+ page_icon=":material/monitoring:",
23
+ layout="wide",
24
+ )
25
+
26
+
27
+ # =============================================================================
28
+ # Constants
29
+ # =============================================================================
30
+
31
+ TIME_RANGES = ["1M", "6M", "1Y", "QTD", "YTD", "All"]
32
+ CHART_HEIGHT = 300
33
+
34
+
35
+ # =============================================================================
36
+ # Synthetic Data Generation (Replace with your data source)
37
+ # =============================================================================
38
+
39
+
40
+ def generate_metric_data(
41
+ metric_name: str,
42
+ start_date: date,
43
+ end_date: date,
44
+ base_value: float = 1000,
45
+ growth_rate: float = 0.001,
46
+ noise_factor: float = 0.1,
47
+ ) -> pd.DataFrame:
48
+ """Generate synthetic time series data for a metric.
49
+
50
+ Replace this function with your actual data source, e.g.:
51
+ - Snowflake query
52
+ - API call
53
+ - Database query
54
+ """
55
+ np.random.seed(hash(metric_name) % 2**32)
56
+
57
+ dates = pd.date_range(start=start_date, end=end_date, freq="D")
58
+ n_days = len(dates)
59
+
60
+ # Base trend with growth
61
+ trend = base_value * (1 + growth_rate) ** np.arange(n_days)
62
+
63
+ # Add weekly seasonality (lower on weekends)
64
+ day_of_week = dates.dayofweek
65
+ seasonality = np.where(day_of_week >= 5, 0.7, 1.0)
66
+ trend = trend * seasonality
67
+
68
+ # Add noise
69
+ noise = np.random.normal(1, noise_factor, n_days)
70
+ values = trend * noise
71
+
72
+ # Calculate rolling averages
73
+ df = pd.DataFrame({
74
+ "ds": dates,
75
+ "daily_value": values,
76
+ })
77
+ df["value_7d_ma"] = df["daily_value"].rolling(7, min_periods=1).mean()
78
+
79
+ return df
80
+
81
+
82
+ @st.cache_data(ttl=3600)
83
+ def load_all_metrics() -> dict[str, pd.DataFrame]:
84
+ """Load all metrics data. Replace with your data loading logic."""
85
+ end_date = date.today() - timedelta(days=1)
86
+ start_date = end_date - timedelta(days=730) # 2 years of data
87
+
88
+ return {
89
+ "users": generate_metric_data("users", start_date, end_date, base_value=5000, growth_rate=0.002),
90
+ "sessions": generate_metric_data("sessions", start_date, end_date, base_value=15000, growth_rate=0.003),
91
+ "revenue": generate_metric_data("revenue", start_date, end_date, base_value=50000, growth_rate=0.001),
92
+ "conversions": generate_metric_data("conversions", start_date, end_date, base_value=500, growth_rate=0.0015),
93
+ }
94
+
95
+
96
+ # =============================================================================
97
+ # Chart Utilities
98
+ # =============================================================================
99
+
100
+
101
+ def filter_by_time_range(df: pd.DataFrame, x_col: str, time_range: str) -> pd.DataFrame:
102
+ """Filter dataframe by time range."""
103
+ if time_range == "All" or df.empty:
104
+ return df
105
+
106
+ df = df.copy()
107
+ df[x_col] = pd.to_datetime(df[x_col])
108
+ max_date = df[x_col].max()
109
+
110
+ if time_range == "1M":
111
+ min_date = max_date - timedelta(days=30)
112
+ elif time_range == "6M":
113
+ min_date = max_date - timedelta(days=180)
114
+ elif time_range == "1Y":
115
+ min_date = max_date - timedelta(days=365)
116
+ elif time_range == "QTD":
117
+ quarter_month = ((max_date.month - 1) // 3) * 3 + 1
118
+ min_date = pd.Timestamp(date(max_date.year, quarter_month, 1))
119
+ elif time_range == "YTD":
120
+ min_date = pd.Timestamp(date(max_date.year, 1, 1))
121
+ else:
122
+ return df
123
+
124
+ return df[df[x_col] >= min_date]
125
+
126
+
127
+ def render_line_chart(
128
+ df: pd.DataFrame,
129
+ x_col: str,
130
+ y_cols: list[str],
131
+ labels: list[str],
132
+ height: int = CHART_HEIGHT,
133
+ ) -> alt.Chart:
134
+ """Render a multi-line chart."""
135
+ # Melt for Altair
136
+ melted = df.melt(
137
+ id_vars=[x_col],
138
+ value_vars=y_cols,
139
+ var_name="series",
140
+ value_name="value",
141
+ )
142
+
143
+ # Map to labels
144
+ label_map = dict(zip(y_cols, labels))
145
+ melted["series"] = melted["series"].map(label_map)
146
+
147
+ chart = (
148
+ alt.Chart(melted)
149
+ .mark_line()
150
+ .encode(
151
+ x=alt.X(f"{x_col}:T", title=None),
152
+ y=alt.Y("value:Q", title=None, scale=alt.Scale(zero=False)),
153
+ color=alt.Color("series:N", title=None, legend=alt.Legend(orient="bottom")),
154
+ strokeDash=alt.condition(
155
+ alt.datum.series == "7-day MA",
156
+ alt.value([5, 5]),
157
+ alt.value([0]),
158
+ ),
159
+ tooltip=[
160
+ alt.Tooltip(f"{x_col}:T", title="Date", format="%Y-%m-%d"),
161
+ alt.Tooltip("series:N", title="Series"),
162
+ alt.Tooltip("value:Q", title="Value", format=",.0f"),
163
+ ],
164
+ )
165
+ .properties(height=height)
166
+ )
167
+
168
+ return chart
169
+
170
+
171
+ def render_area_chart(
172
+ df: pd.DataFrame,
173
+ x_col: str,
174
+ y_cols: list[str],
175
+ labels: list[str],
176
+ height: int = CHART_HEIGHT,
177
+ ) -> alt.Chart:
178
+ """Render a stacked area chart."""
179
+ melted = df.melt(
180
+ id_vars=[x_col],
181
+ value_vars=y_cols,
182
+ var_name="series",
183
+ value_name="value",
184
+ )
185
+ label_map = dict(zip(y_cols, labels))
186
+ melted["series"] = melted["series"].map(label_map)
187
+
188
+ chart = (
189
+ alt.Chart(melted)
190
+ .mark_area(opacity=0.6, line=True)
191
+ .encode(
192
+ x=alt.X(f"{x_col}:T", title=None),
193
+ y=alt.Y("value:Q", title=None, scale=alt.Scale(zero=False)),
194
+ color=alt.Color("series:N", title=None, legend=alt.Legend(orient="bottom")),
195
+ tooltip=[
196
+ alt.Tooltip(f"{x_col}:T", title="Date", format="%Y-%m-%d"),
197
+ alt.Tooltip("series:N", title="Series"),
198
+ alt.Tooltip("value:Q", title="Value", format=",.0f"),
199
+ ],
200
+ )
201
+ .properties(height=height)
202
+ )
203
+ return chart
204
+
205
+
206
+ def render_bar_chart(
207
+ df: pd.DataFrame,
208
+ x_col: str,
209
+ y_cols: list[str],
210
+ labels: list[str],
211
+ height: int = CHART_HEIGHT,
212
+ ) -> alt.Chart:
213
+ """Render a bar chart (weekly aggregation for readability)."""
214
+ df = df.copy()
215
+ df[x_col] = pd.to_datetime(df[x_col])
216
+ df["week"] = df[x_col].dt.to_period("W").dt.start_time
217
+
218
+ # Aggregate by week
219
+ agg_df = df.groupby("week")[y_cols].mean().reset_index()
220
+
221
+ melted = agg_df.melt(
222
+ id_vars=["week"],
223
+ value_vars=y_cols,
224
+ var_name="series",
225
+ value_name="value",
226
+ )
227
+ label_map = dict(zip(y_cols, labels))
228
+ melted["series"] = melted["series"].map(label_map)
229
+
230
+ chart = (
231
+ alt.Chart(melted)
232
+ .mark_bar(opacity=0.8)
233
+ .encode(
234
+ x=alt.X("week:T", title=None),
235
+ y=alt.Y("value:Q", title=None, scale=alt.Scale(zero=False)),
236
+ color=alt.Color("series:N", title=None, legend=alt.Legend(orient="bottom")),
237
+ xOffset="series:N",
238
+ tooltip=[
239
+ alt.Tooltip("week:T", title="Week", format="%Y-%m-%d"),
240
+ alt.Tooltip("series:N", title="Series"),
241
+ alt.Tooltip("value:Q", title="Value", format=",.0f"),
242
+ ],
243
+ )
244
+ .properties(height=height)
245
+ )
246
+ return chart
247
+
248
+
249
+ def render_point_chart(
250
+ df: pd.DataFrame,
251
+ x_col: str,
252
+ y_cols: list[str],
253
+ labels: list[str],
254
+ height: int = CHART_HEIGHT,
255
+ ) -> alt.Chart:
256
+ """Render a scatter/point chart with trend line."""
257
+ melted = df.melt(
258
+ id_vars=[x_col],
259
+ value_vars=y_cols,
260
+ var_name="series",
261
+ value_name="value",
262
+ )
263
+ label_map = dict(zip(y_cols, labels))
264
+ melted["series"] = melted["series"].map(label_map)
265
+
266
+ points = (
267
+ alt.Chart(melted)
268
+ .mark_point(opacity=0.5, size=20)
269
+ .encode(
270
+ x=alt.X(f"{x_col}:T", title=None),
271
+ y=alt.Y("value:Q", title=None, scale=alt.Scale(zero=False)),
272
+ color=alt.Color("series:N", title=None, legend=alt.Legend(orient="bottom")),
273
+ tooltip=[
274
+ alt.Tooltip(f"{x_col}:T", title="Date", format="%Y-%m-%d"),
275
+ alt.Tooltip("series:N", title="Series"),
276
+ alt.Tooltip("value:Q", title="Value", format=",.0f"),
277
+ ],
278
+ )
279
+ )
280
+
281
+ # Add trend line for 7-day MA only
282
+ trend = (
283
+ alt.Chart(melted[melted["series"] == "7-day MA"])
284
+ .mark_line(strokeDash=[5, 5], strokeWidth=2)
285
+ .encode(
286
+ x=alt.X(f"{x_col}:T"),
287
+ y=alt.Y("value:Q"),
288
+ color=alt.Color("series:N"),
289
+ )
290
+ )
291
+
292
+ return (points + trend).properties(height=height)
293
+
294
+
295
+ # =============================================================================
296
+ # Metric Card Component
297
+ # =============================================================================
298
+
299
+
300
+ def metric_card(
301
+ title: str,
302
+ df: pd.DataFrame,
303
+ key_prefix: str,
304
+ chart_type: str = "line",
305
+ ):
306
+ """Display a metric card with chart/table toggle and popover filters.
307
+
308
+ Args:
309
+ title: Card title
310
+ df: DataFrame with ds, daily_value, value_7d_ma columns
311
+ key_prefix: Unique prefix for widget keys
312
+ chart_type: One of "line", "area", "bar", "point"
313
+ """
314
+ chart_renderers = {
315
+ "line": render_line_chart,
316
+ "area": render_area_chart,
317
+ "bar": render_bar_chart,
318
+ "point": render_point_chart,
319
+ }
320
+ render_chart = chart_renderers.get(chart_type, render_line_chart)
321
+
322
+ with st.container(border=True):
323
+ # Header row with title, view toggle, and filters
324
+ with st.container(
325
+ horizontal=True,
326
+ horizontal_alignment="distribute",
327
+ vertical_alignment="center",
328
+ ):
329
+ st.markdown(f"**{title}**")
330
+
331
+ view_mode = st.segmented_control(
332
+ "View",
333
+ options=[":material/show_chart:", ":material/table:"],
334
+ default=":material/show_chart:",
335
+ key=f"{key_prefix}_view",
336
+ label_visibility="collapsed",
337
+ )
338
+
339
+ with st.popover("Filters", type="tertiary"):
340
+ line_options = st.pills(
341
+ "Lines",
342
+ options=["Daily", "7-day MA"],
343
+ default=["Daily", "7-day MA"],
344
+ selection_mode="multi",
345
+ key=f"{key_prefix}_lines",
346
+ )
347
+ time_range = st.segmented_control(
348
+ "Time range",
349
+ options=TIME_RANGES,
350
+ default="All",
351
+ key=f"{key_prefix}_time",
352
+ )
353
+
354
+ # Apply filters
355
+ line_options = line_options or ["7-day MA"]
356
+ filtered_df = filter_by_time_range(df, "ds", time_range)
357
+
358
+ # Determine which columns to show
359
+ y_cols = []
360
+ labels = []
361
+ if "Daily" in line_options:
362
+ y_cols.append("daily_value")
363
+ labels.append("Daily")
364
+ if "7-day MA" in line_options:
365
+ y_cols.append("value_7d_ma")
366
+ labels.append("7-day MA")
367
+
368
+ # Render view
369
+ if "table" in (view_mode or ""):
370
+ st.dataframe(
371
+ filtered_df,
372
+ height=CHART_HEIGHT,
373
+ hide_index=True,
374
+ )
375
+ else:
376
+ if y_cols:
377
+ st.altair_chart(
378
+ render_chart(filtered_df, "ds", y_cols, labels),
379
+ )
380
+ else:
381
+ st.info("Select at least one line option.")
382
+
383
+
384
+ # =============================================================================
385
+ # Page Header Component
386
+ # =============================================================================
387
+
388
+
389
+ def render_page_header(title: str):
390
+ """Render page header with title and reset button."""
391
+ with st.container(
392
+ horizontal=True, horizontal_alignment="distribute", vertical_alignment="center"
393
+ ):
394
+ st.markdown(title)
395
+ if st.button(":material/restart_alt: Reset", type="tertiary"):
396
+ st.session_state.clear()
397
+ st.rerun()
398
+
399
+
400
+ # =============================================================================
401
+ # Page Layout
402
+ # =============================================================================
403
+
404
+ # Load data (cached)
405
+ metrics_data = load_all_metrics()
406
+
407
+ # Page header
408
+ render_page_header("# :material/monitoring: Metrics Dashboard")
409
+
410
+ # Row 1: Users and Sessions
411
+ row1 = st.columns(2)
412
+
413
+ with row1[0]:
414
+ metric_card("Active Users", metrics_data["users"], "users", chart_type="line")
415
+
416
+ with row1[1]:
417
+ metric_card("Sessions", metrics_data["sessions"], "sessions", chart_type="area")
418
+
419
+ # Row 2: Revenue and Conversions
420
+ row2 = st.columns(2)
421
+
422
+ with row2[0]:
423
+ metric_card("Revenue", metrics_data["revenue"], "revenue", chart_type="bar")
424
+
425
+ with row2[1]:
426
+ metric_card("Conversions", metrics_data["conversions"], "conversions", chart_type="point")
@@ -0,0 +1,20 @@
1
+ # Copy this file to secrets.toml and fill in your credentials
2
+ # NEVER commit secrets.toml to version control — it contains sensitive
3
+ # credentials that would be exposed in your repository.
4
+ #
5
+ # To find your account and host values, run:
6
+ # snow connection list
7
+ # Look for the "account" and "host" fields in your connection config.
8
+
9
+ [connections.snowflake]
10
+ account = "<YOUR_ACCOUNT>" # e.g., "ORGNAME-ACCTNAME" from `snow connection list`
11
+ host = "<YOUR_HOST>" # e.g., "myaccount.snowflakecomputing.com" (required for private link / internal accounts)
12
+ user = "<YOUR_USER>"
13
+ authenticator = "externalbrowser" # Opens browser for SSO login
14
+ warehouse = "<YOUR_WAREHOUSE>"
15
+ database = "<YOUR_DATABASE>"
16
+ schema = "<YOUR_SCHEMA>"
17
+
18
+ # Alternative: use password instead of SSO (less secure)
19
+ # password = "<YOUR_PASSWORD>"
20
+ # Remove the authenticator line above if using password
@@ -0,0 +1,11 @@
1
+ [project]
2
+ name = "dashboard-metrics-snowflake"
3
+ version = "1.0.0"
4
+ description = "A metrics dashboard template using Snowflake for data storage and retrieval"
5
+ requires-python = ">=3.11"
6
+ dependencies = [
7
+ "altair>=5.5.0",
8
+ "pandas>=2.2.3",
9
+ "snowflake-connector-python>=3.3.0",
10
+ "streamlit[snowflake]>=1.54.0",
11
+ ]
@@ -0,0 +1,18 @@
1
+ definition_version: 2
2
+ entities:
3
+ DASHBOARD_METRICS_SNOWFLAKE:
4
+ type: streamlit
5
+ identifier:
6
+ name: DASHBOARD_METRICS_SNOWFLAKE
7
+ database: <FROM_CONNECTION> # Use: snow connection list
8
+ schema: <FROM_CONNECTION>
9
+ query_warehouse: <FROM_CONNECTION>
10
+ runtime_name: SYSTEM$ST_CONTAINER_RUNTIME_PY3_11
11
+ # List available: SHOW EXTERNAL ACCESS INTEGRATIONS;
12
+ # Common: PYPI_ACCESS_INTEGRATION (verify exists)
13
+ external_access_integrations:
14
+ - <YOUR_PYPI_INTEGRATION>
15
+ main_file: streamlit_app.py
16
+ artifacts:
17
+ - streamlit_app.py
18
+ - pyproject.toml