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,461 @@
1
+ """
2
+ Compute/Resource Dashboard Template
3
+
4
+ A resource consumption dashboard demonstrating:
5
+ - Multiple metric cards in a grid layout
6
+ - @st.fragment for independent widget updates
7
+ - Popover filters for each metric card
8
+ - Chart/table view toggle
9
+ - Time range filtering (1M, 6M, 1Y, QTD, YTD, All)
10
+ - Percentage normalization toggle
11
+ - Multiple breakdown dimensions
12
+
13
+ This template uses synthetic data. Replace generate_*_data()
14
+ with your actual data source (e.g., Snowflake queries, cloud APIs, etc.)
15
+ """
16
+
17
+ from datetime import date, timedelta
18
+ import numpy as np
19
+ import pandas as pd
20
+ import streamlit as st
21
+ import altair as alt
22
+
23
+ st.set_page_config(
24
+ page_title="Compute Dashboard",
25
+ page_icon=":material/bolt:",
26
+ layout="wide",
27
+ )
28
+
29
+
30
+ # =============================================================================
31
+ # Constants
32
+ # =============================================================================
33
+
34
+ TIME_RANGES = ["1M", "6M", "1Y", "QTD", "YTD", "All"]
35
+ ACCOUNT_TYPES = ["Paying", "Trial", "Internal"]
36
+ INSTANCE_TYPES = ["Standard", "High Memory", "High CPU", "GPU"]
37
+ REGIONS = ["us-west-2", "us-east-1", "eu-west-1", "ap-northeast-1"]
38
+ CHART_HEIGHT = 350
39
+
40
+
41
+ # =============================================================================
42
+ # Synthetic Data Generation
43
+ # =============================================================================
44
+
45
+
46
+ def generate_time_series(
47
+ categories: list[str],
48
+ category_name: str,
49
+ start_date: date,
50
+ end_date: date,
51
+ base_values: dict[str, float] | None = None,
52
+ ) -> pd.DataFrame:
53
+ """Generate synthetic time series data by category."""
54
+ np.random.seed(hash(category_name) % 2**32)
55
+
56
+ dates = pd.date_range(start=start_date, end=end_date, freq="D")
57
+ records = []
58
+
59
+ for category in categories:
60
+ base = base_values.get(category, 1000) if base_values else np.random.randint(500, 5000)
61
+ growth = np.random.uniform(0.001, 0.005)
62
+
63
+ for i, dt in enumerate(dates):
64
+ trend = base * (1 + growth) ** i
65
+ if dt.dayofweek >= 5:
66
+ trend *= 0.4
67
+
68
+ daily = max(0, trend * np.random.uniform(0.8, 1.2))
69
+
70
+ records.append({
71
+ "ds": dt,
72
+ category_name: category,
73
+ "daily_credits": daily,
74
+ })
75
+
76
+ df = pd.DataFrame(records)
77
+
78
+ # Add 7-day moving average
79
+ df["credits_7d_ma"] = (
80
+ df.groupby(category_name)["daily_credits"]
81
+ .transform(lambda x: x.rolling(7, min_periods=1).mean())
82
+ )
83
+
84
+ return df
85
+
86
+
87
+ @st.cache_data(ttl=3600)
88
+ def load_account_type_data() -> pd.DataFrame:
89
+ """Load credits by account type."""
90
+ end_date = date.today() - timedelta(days=1)
91
+ start_date = end_date - timedelta(days=730) # 2 years
92
+ return generate_time_series(
93
+ ACCOUNT_TYPES, "account_type", start_date, end_date,
94
+ base_values={"Paying": 8000, "Trial": 2000, "Internal": 1000},
95
+ )
96
+
97
+
98
+ @st.cache_data(ttl=3600)
99
+ def load_instance_type_data() -> pd.DataFrame:
100
+ """Load credits by instance type."""
101
+ end_date = date.today() - timedelta(days=1)
102
+ start_date = end_date - timedelta(days=730)
103
+ return generate_time_series(
104
+ INSTANCE_TYPES, "instance_type", start_date, end_date,
105
+ base_values={"Standard": 5000, "High Memory": 3000, "High CPU": 2000, "GPU": 1500},
106
+ )
107
+
108
+
109
+ @st.cache_data(ttl=3600)
110
+ def load_region_data() -> pd.DataFrame:
111
+ """Load credits by region."""
112
+ end_date = date.today() - timedelta(days=1)
113
+ start_date = end_date - timedelta(days=730)
114
+ return generate_time_series(
115
+ REGIONS, "region", start_date, end_date,
116
+ base_values={"us-west-2": 4000, "us-east-1": 3500, "eu-west-1": 2500, "ap-northeast-1": 1500},
117
+ )
118
+
119
+
120
+ # =============================================================================
121
+ # Chart Utilities
122
+ # =============================================================================
123
+
124
+
125
+ def filter_by_time_range(df: pd.DataFrame, x_col: str, time_range: str) -> pd.DataFrame:
126
+ """Filter dataframe by time range."""
127
+ if time_range == "All" or df.empty:
128
+ return df
129
+
130
+ df = df.copy()
131
+ df[x_col] = pd.to_datetime(df[x_col])
132
+ max_date = df[x_col].max()
133
+
134
+ if time_range == "1M":
135
+ min_date = max_date - timedelta(days=30)
136
+ elif time_range == "6M":
137
+ min_date = max_date - timedelta(days=180)
138
+ elif time_range == "1Y":
139
+ min_date = max_date - timedelta(days=365)
140
+ elif time_range == "QTD":
141
+ quarter_month = ((max_date.month - 1) // 3) * 3 + 1
142
+ min_date = pd.Timestamp(date(max_date.year, quarter_month, 1))
143
+ elif time_range == "YTD":
144
+ min_date = pd.Timestamp(date(max_date.year, 1, 1))
145
+ else:
146
+ return df
147
+
148
+ return df[df[x_col] >= min_date]
149
+
150
+
151
+ def create_line_chart(
152
+ df: pd.DataFrame,
153
+ x_col: str,
154
+ y_col: str,
155
+ color_col: str,
156
+ height: int,
157
+ show_percent: bool = False,
158
+ ) -> alt.Chart:
159
+ """Create a line chart."""
160
+ y_format = ".1%" if show_percent else ",.0f"
161
+
162
+ return (
163
+ alt.Chart(df)
164
+ .mark_line()
165
+ .encode(
166
+ x=alt.X(f"{x_col}:T", title=None),
167
+ y=alt.Y(f"{y_col}:Q", title="Credits", axis=alt.Axis(format=y_format)),
168
+ color=alt.Color(f"{color_col}:N", legend=alt.Legend(orient="bottom")),
169
+ tooltip=[
170
+ alt.Tooltip(f"{x_col}:T", title="Date", format="%Y-%m-%d"),
171
+ alt.Tooltip(f"{color_col}:N", title=color_col.replace("_", " ").title()),
172
+ alt.Tooltip(f"{y_col}:Q", title="Credits", format=y_format),
173
+ ],
174
+ )
175
+ .properties(height=height)
176
+ .interactive()
177
+ )
178
+
179
+
180
+ def create_bar_chart(
181
+ df: pd.DataFrame,
182
+ x_col: str,
183
+ y_col: str,
184
+ color_col: str,
185
+ height: int,
186
+ show_percent: bool = False,
187
+ ) -> alt.Chart:
188
+ """Create a stacked bar chart."""
189
+ y_format = ".1%" if show_percent else ",.0f"
190
+
191
+ return (
192
+ alt.Chart(df)
193
+ .mark_bar()
194
+ .encode(
195
+ x=alt.X(f"{x_col}:T", title=None),
196
+ y=alt.Y(
197
+ f"{y_col}:Q",
198
+ title="Credits",
199
+ stack="normalize" if show_percent else True,
200
+ axis=alt.Axis(format=y_format),
201
+ ),
202
+ color=alt.Color(f"{color_col}:N", legend=alt.Legend(orient="bottom")),
203
+ tooltip=[
204
+ alt.Tooltip(f"{x_col}:T", title="Date", format="%Y-%m-%d"),
205
+ alt.Tooltip(f"{color_col}:N"),
206
+ alt.Tooltip(f"{y_col}:Q", format=",.0f"),
207
+ ],
208
+ )
209
+ .properties(height=height)
210
+ )
211
+
212
+
213
+ # =============================================================================
214
+ # Page Header Component
215
+ # =============================================================================
216
+
217
+
218
+ def render_page_header(title: str):
219
+ """Render page header with title and reset button."""
220
+ with st.container(
221
+ horizontal=True, horizontal_alignment="distribute", vertical_alignment="center"
222
+ ):
223
+ st.markdown(title)
224
+ if st.button(":material/restart_alt: Reset", type="tertiary"):
225
+ st.session_state.clear()
226
+ st.rerun()
227
+
228
+
229
+ # =============================================================================
230
+ # Metric Card Components (using @st.fragment)
231
+ # =============================================================================
232
+
233
+
234
+ @st.fragment
235
+ def account_type_metric():
236
+ """Account type metric card with independent state."""
237
+ data = load_account_type_data()
238
+
239
+ with st.container(border=True):
240
+ with st.container(horizontal=True, horizontal_alignment="distribute", vertical_alignment="center"):
241
+ st.markdown("**Credits by account type**")
242
+
243
+ view_mode = st.segmented_control(
244
+ "View",
245
+ options=[":material/show_chart:", ":material/table:"],
246
+ default=":material/show_chart:",
247
+ key="acct_view",
248
+ label_visibility="collapsed",
249
+ )
250
+
251
+ with st.popover("Filters", type="tertiary"):
252
+ selected_types = st.pills(
253
+ "Account types",
254
+ options=ACCOUNT_TYPES,
255
+ default=["Paying"],
256
+ selection_mode="multi",
257
+ key="acct_types",
258
+ )
259
+ line_options = st.pills(
260
+ "Lines",
261
+ options=["Daily", "7-day MA"],
262
+ default=["7-day MA"],
263
+ selection_mode="multi",
264
+ key="acct_lines",
265
+ )
266
+ chart_type = st.segmented_control(
267
+ "Chart type",
268
+ options=[":material/show_chart: Line", ":material/bar_chart: Bar"],
269
+ default=":material/show_chart: Line",
270
+ key="acct_chart",
271
+ )
272
+ show_percent = st.toggle(
273
+ "Show %", value=False, key="acct_pct",
274
+ disabled="Line" in (chart_type or ""),
275
+ )
276
+ time_range = st.segmented_control(
277
+ "Time range",
278
+ options=TIME_RANGES,
279
+ default="All",
280
+ key="acct_time",
281
+ )
282
+
283
+ # Filter data
284
+ selected_types = selected_types or ["Paying"]
285
+ line_options = line_options or ["7-day MA"]
286
+ filtered = data[data["account_type"].isin(selected_types)]
287
+ filtered = filter_by_time_range(filtered, "ds", time_range)
288
+
289
+ # Determine y column
290
+ y_col = "credits_7d_ma" if "7-day MA" in line_options else "daily_credits"
291
+
292
+ if "table" in (view_mode or ""):
293
+ st.dataframe(filtered, height=CHART_HEIGHT, hide_index=True)
294
+ else:
295
+ if "Bar" in (chart_type or ""):
296
+ st.altair_chart(
297
+ create_bar_chart(filtered, "ds", y_col, "account_type", CHART_HEIGHT, show_percent),
298
+ )
299
+ else:
300
+ st.altair_chart(
301
+ create_line_chart(filtered, "ds", y_col, "account_type", CHART_HEIGHT),
302
+ )
303
+
304
+
305
+ @st.fragment
306
+ def instance_type_metric():
307
+ """Instance type metric card with independent state."""
308
+ data = load_instance_type_data()
309
+
310
+ with st.container(border=True):
311
+ with st.container(horizontal=True, horizontal_alignment="distribute", vertical_alignment="center"):
312
+ st.markdown("**Credits by instance type**")
313
+
314
+ view_mode = st.segmented_control(
315
+ "View",
316
+ options=[":material/show_chart:", ":material/table:"],
317
+ default=":material/show_chart:",
318
+ key="inst_view",
319
+ label_visibility="collapsed",
320
+ )
321
+
322
+ with st.popover("Filters", type="tertiary"):
323
+ selected_types = st.pills(
324
+ "Instance types",
325
+ options=INSTANCE_TYPES,
326
+ default=INSTANCE_TYPES,
327
+ selection_mode="multi",
328
+ key="inst_types",
329
+ )
330
+ line_options = st.pills(
331
+ "Lines",
332
+ options=["Daily", "7-day MA"],
333
+ default=["7-day MA"],
334
+ selection_mode="multi",
335
+ key="inst_lines",
336
+ )
337
+ chart_type = st.segmented_control(
338
+ "Chart type",
339
+ options=[":material/show_chart: Line", ":material/bar_chart: Bar"],
340
+ default=":material/show_chart: Line",
341
+ key="inst_chart",
342
+ )
343
+ show_percent = st.toggle(
344
+ "Show %", value=False, key="inst_pct",
345
+ disabled="Line" in (chart_type or ""),
346
+ )
347
+ time_range = st.segmented_control(
348
+ "Time range",
349
+ options=TIME_RANGES,
350
+ default="All",
351
+ key="inst_time",
352
+ )
353
+
354
+ # Filter data
355
+ selected_types = selected_types or INSTANCE_TYPES
356
+ line_options = line_options or ["7-day MA"]
357
+ filtered = data[data["instance_type"].isin(selected_types)]
358
+ filtered = filter_by_time_range(filtered, "ds", time_range)
359
+
360
+ y_col = "credits_7d_ma" if "7-day MA" in line_options else "daily_credits"
361
+
362
+ if "table" in (view_mode or ""):
363
+ st.dataframe(filtered, height=CHART_HEIGHT, hide_index=True)
364
+ else:
365
+ if "Bar" in (chart_type or ""):
366
+ st.altair_chart(
367
+ create_bar_chart(filtered, "ds", y_col, "instance_type", CHART_HEIGHT, show_percent),
368
+ )
369
+ else:
370
+ st.altair_chart(
371
+ create_line_chart(filtered, "ds", y_col, "instance_type", CHART_HEIGHT),
372
+ )
373
+
374
+
375
+ @st.fragment
376
+ def region_metric():
377
+ """Region metric card with independent state."""
378
+ data = load_region_data()
379
+
380
+ with st.container(border=True):
381
+ with st.container(horizontal=True, horizontal_alignment="distribute", vertical_alignment="center"):
382
+ st.markdown("**Credits by region**")
383
+
384
+ view_mode = st.segmented_control(
385
+ "View",
386
+ options=[":material/show_chart:", ":material/table:"],
387
+ default=":material/show_chart:",
388
+ key="region_view",
389
+ label_visibility="collapsed",
390
+ )
391
+
392
+ with st.popover("Filters", type="tertiary"):
393
+ selected_regions = st.pills(
394
+ "Regions",
395
+ options=REGIONS,
396
+ default=REGIONS,
397
+ selection_mode="multi",
398
+ key="region_select",
399
+ )
400
+ line_options = st.pills(
401
+ "Lines",
402
+ options=["Daily", "7-day MA"],
403
+ default=["7-day MA"],
404
+ selection_mode="multi",
405
+ key="region_lines",
406
+ )
407
+ chart_type = st.segmented_control(
408
+ "Chart type",
409
+ options=[":material/show_chart: Line", ":material/bar_chart: Bar"],
410
+ default=":material/bar_chart: Bar",
411
+ key="region_chart",
412
+ )
413
+ show_percent = st.toggle(
414
+ "Show %", value=False, key="region_pct",
415
+ disabled="Line" in (chart_type or ""),
416
+ )
417
+ time_range = st.segmented_control(
418
+ "Time range",
419
+ options=TIME_RANGES,
420
+ default="All",
421
+ key="region_time",
422
+ )
423
+
424
+ # Filter data
425
+ selected_regions = selected_regions or REGIONS
426
+ line_options = line_options or ["7-day MA"]
427
+ filtered = data[data["region"].isin(selected_regions)]
428
+ filtered = filter_by_time_range(filtered, "ds", time_range)
429
+
430
+ y_col = "credits_7d_ma" if "7-day MA" in line_options else "daily_credits"
431
+
432
+ if "table" in (view_mode or ""):
433
+ st.dataframe(filtered, height=CHART_HEIGHT, hide_index=True)
434
+ else:
435
+ if "Bar" in (chart_type or ""):
436
+ st.altair_chart(
437
+ create_bar_chart(filtered, "ds", y_col, "region", CHART_HEIGHT, show_percent),
438
+ )
439
+ else:
440
+ st.altair_chart(
441
+ create_line_chart(filtered, "ds", y_col, "region", CHART_HEIGHT),
442
+ )
443
+
444
+
445
+ # =============================================================================
446
+ # Page Layout
447
+ # =============================================================================
448
+
449
+ render_page_header("# :material/bolt: Compute Dashboard")
450
+
451
+ # Row 1: Two metrics
452
+ col1, col2 = st.columns(2)
453
+
454
+ with col1:
455
+ account_type_metric()
456
+
457
+ with col2:
458
+ instance_type_metric()
459
+
460
+ # Row 2: One metric (full width for region breakdown)
461
+ region_metric()
@@ -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-compute-snowflake"
3
+ version = "1.0.0"
4
+ description = "Compute dashboard template with Snowflake connection"
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_COMPUTE_SNOWFLAKE:
4
+ type: streamlit
5
+ identifier:
6
+ name: DASHBOARD_COMPUTE_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