snowglobe-cli 0.1.2__tar.gz → 0.1.4__tar.gz
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.
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/PKG-INFO +3 -3
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/README.md +1 -1
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/pyproject.toml +3 -3
- snowglobe_cli-0.1.4/snowglobe/tui/styles.tcss +410 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe_cli.egg-info/PKG-INFO +3 -3
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe_cli.egg-info/SOURCES.txt +1 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/LICENSE +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/setup.cfg +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/__main__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/access.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/app.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/context.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/cost.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/debug.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/diff.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/optimizer.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/prompts.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/report.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/shell.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/cli/shell_completer.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/collectors/access.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/collectors/query_history.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/collectors/query_profile.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/config/loader.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/core/access_service.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/core/cost_service.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/core/optimizer.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/core/query_service.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/core/report_service.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/core/risk_service.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/engines/access/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/engines/access/explainer.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/engines/access/resolver.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/engines/ai/cortex_optimizer.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/engines/optimizer/query_optimizer.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/graphs/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/graphs/role_graph.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/graphs/user_graph.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/models/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/models/access.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/models/access_path.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/models/object_ref.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/models/object_type.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/models/optimizer.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/models/privilege.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/models/query.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/output/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/output/cli.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/queries/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/queries/query_history.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/snowflake/connection.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/state/db.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/state/state.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/templates/report.md.j2 +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tests/access_tests.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/__main__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/app.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/screens/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/screens/access.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/screens/cost.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/screens/home.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/screens/refresh.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/screens/reports.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/screens/risk.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/screens/tune.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/widgets/__init__.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/widgets/access_paths.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/widgets/cache_badge.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/widgets/header.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe/tui/widgets/nav.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe_cli.egg-info/dependency_links.txt +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe_cli.egg-info/entry_points.txt +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe_cli.egg-info/requires.txt +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/snowglobe_cli.egg-info/top_level.txt +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/tests/test_access.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/tests/test_optimizer_engine.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/tests/test_output.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/tests/test_query_validation.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/tests/test_state_db.py +0 -0
- {snowglobe_cli-0.1.2 → snowglobe_cli-0.1.4}/tests/test_tui_tune.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: snowglobe-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Explainable cost and access visibility for Snowflake
|
|
5
5
|
Author-email: Jaryd Thornton <jaryd90@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
7
|
-
Requires-Python: >=3.12
|
|
7
|
+
Requires-Python: >=3.12.3
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Dist: cryptography==45.0.5
|
|
@@ -98,7 +98,7 @@ pip install -e '.[tui]'
|
|
|
98
98
|
|
|
99
99
|
## Requirements
|
|
100
100
|
|
|
101
|
-
- Python **3.12+**
|
|
101
|
+
- Python **3.12.3+**
|
|
102
102
|
- A Snowflake account
|
|
103
103
|
- A Snowflake role with `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE` (grants read access to `ACCOUNT_USAGE`)
|
|
104
104
|
- Optionally: `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE` for `ORGANIZATION_USAGE` to get your contracted storage rate
|
|
@@ -71,7 +71,7 @@ pip install -e '.[tui]'
|
|
|
71
71
|
|
|
72
72
|
## Requirements
|
|
73
73
|
|
|
74
|
-
- Python **3.12+**
|
|
74
|
+
- Python **3.12.3+**
|
|
75
75
|
- A Snowflake account
|
|
76
76
|
- A Snowflake role with `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE` (grants read access to `ACCOUNT_USAGE`)
|
|
77
77
|
- Optionally: `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE` for `ORGANIZATION_USAGE` to get your contracted storage rate
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "snowglobe-cli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.4"
|
|
4
4
|
description = "Explainable cost and access visibility for Snowflake"
|
|
5
5
|
readme = "README.md"
|
|
6
|
-
requires-python = ">=3.12"
|
|
6
|
+
requires-python = ">=3.12.3"
|
|
7
7
|
license = "Apache-2.0"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name = "Jaryd Thornton", email = "jaryd90@gmail.com" }
|
|
@@ -41,7 +41,7 @@ where = ["."]
|
|
|
41
41
|
include = ["snowglobe*"]
|
|
42
42
|
|
|
43
43
|
[tool.setuptools.package-data]
|
|
44
|
-
snowglobe = ["templates/*.j2"]
|
|
44
|
+
snowglobe = ["templates/*.j2", "tui/*.tcss"]
|
|
45
45
|
|
|
46
46
|
[build-system]
|
|
47
47
|
requires = ["setuptools>=80.9", "wheel"]
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
/* Snowglobe TUI — theme-aware styles.
|
|
2
|
+
|
|
3
|
+
Colour values come from the active Textual theme via $variables, so
|
|
4
|
+
Ctrl-P → "Change theme" actually repaints everything. The two branded
|
|
5
|
+
themes (`snowglobe-dark`, `snowglobe-light`) are registered on the
|
|
6
|
+
App; Textual's built-ins still work for comparison.
|
|
7
|
+
|
|
8
|
+
Brand mapping (both Snowglobe themes use the same accent values, only
|
|
9
|
+
background/foreground change between dark and light):
|
|
10
|
+
|
|
11
|
+
$primary Hero Blue — buttons, borders, accents
|
|
12
|
+
$secondary Deep Blue — reserved (rarely used directly)
|
|
13
|
+
$accent Yellow — highlights, stale-cache warnings
|
|
14
|
+
$panel Deep Blue (dark) / Sky (light) — header, nav, side panels
|
|
15
|
+
$surface elevated panels, table backgrounds
|
|
16
|
+
$warning Yellow / orange
|
|
17
|
+
$error red
|
|
18
|
+
$success green
|
|
19
|
+
$snowglobe-diff orange — risk-scan diff line (custom var; default below)
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/* Default for our custom variable so non-Snowglobe themes (nord, monokai,
|
|
23
|
+
the Textual built-ins) still resolve it on theme switch. The Snowglobe
|
|
24
|
+
themes override it via their `variables` dict to tune for light/dark. */
|
|
25
|
+
$snowglobe-diff: #FF7043;
|
|
26
|
+
|
|
27
|
+
Screen {
|
|
28
|
+
background: $background;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* --- App shell --- */
|
|
32
|
+
|
|
33
|
+
SnowglobeHeader {
|
|
34
|
+
height: 3;
|
|
35
|
+
background: $panel;
|
|
36
|
+
color: $foreground;
|
|
37
|
+
padding: 0 2;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
SnowglobeHeader .header-title {
|
|
41
|
+
color: $accent;
|
|
42
|
+
text-style: bold;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
SnowglobeHeader .header-meta {
|
|
46
|
+
color: $foreground;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
CacheBadge.fresh { color: $success; }
|
|
50
|
+
CacheBadge.stale { color: $warning; }
|
|
51
|
+
CacheBadge.missing { color: $error; text-style: bold; }
|
|
52
|
+
|
|
53
|
+
#main {
|
|
54
|
+
height: 1fr;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
NavSidebar {
|
|
58
|
+
width: 16;
|
|
59
|
+
background: $panel;
|
|
60
|
+
padding: 1 1;
|
|
61
|
+
border-right: solid $primary;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
NavSidebar ListView {
|
|
65
|
+
background: transparent;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
NavSidebar ListItem {
|
|
69
|
+
background: transparent;
|
|
70
|
+
color: $foreground;
|
|
71
|
+
padding: 0 1;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
NavSidebar ListItem.--highlight {
|
|
75
|
+
background: $primary;
|
|
76
|
+
color: white;
|
|
77
|
+
text-style: bold;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
#content {
|
|
81
|
+
padding: 1 2;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.screen-title {
|
|
85
|
+
text-style: bold;
|
|
86
|
+
color: $primary;
|
|
87
|
+
margin-bottom: 1;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.placeholder {
|
|
91
|
+
color: $foreground;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* --- Home screen --- */
|
|
95
|
+
|
|
96
|
+
#home-kpis {
|
|
97
|
+
height: 8;
|
|
98
|
+
margin-bottom: 1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.kpi-card {
|
|
102
|
+
width: 1fr;
|
|
103
|
+
height: 7;
|
|
104
|
+
border: round $primary;
|
|
105
|
+
padding: 0 1;
|
|
106
|
+
margin-right: 1;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.kpi-title {
|
|
110
|
+
color: $accent;
|
|
111
|
+
text-style: bold;
|
|
112
|
+
margin-bottom: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.kpi-body {
|
|
116
|
+
color: $foreground;
|
|
117
|
+
height: auto;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
#home-body {
|
|
121
|
+
height: 1fr;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
#home-actions {
|
|
125
|
+
width: 26;
|
|
126
|
+
margin-right: 1;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
#home-actions .actions-list {
|
|
130
|
+
color: $foreground;
|
|
131
|
+
padding: 0 1;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#home-queries {
|
|
135
|
+
width: 1fr;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
#home-queries-table {
|
|
139
|
+
height: 1fr;
|
|
140
|
+
background: $background;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* --- Access screen form (shared by all access tabs) --- */
|
|
144
|
+
|
|
145
|
+
#access-form,
|
|
146
|
+
.access-form {
|
|
147
|
+
height: auto;
|
|
148
|
+
margin-bottom: 1;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.form-row {
|
|
152
|
+
height: 3;
|
|
153
|
+
padding: 0 0;
|
|
154
|
+
margin-bottom: 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.form-label {
|
|
158
|
+
width: 14;
|
|
159
|
+
padding-top: 1;
|
|
160
|
+
color: $foreground;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.form-input,
|
|
164
|
+
.form-select {
|
|
165
|
+
width: 1fr;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
#run-btn {
|
|
169
|
+
margin-top: 1;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
#access-result,
|
|
173
|
+
#check-result,
|
|
174
|
+
#wa-result,
|
|
175
|
+
#cr-result,
|
|
176
|
+
#pa-result,
|
|
177
|
+
#dr-result {
|
|
178
|
+
height: 1fr;
|
|
179
|
+
border: round $primary;
|
|
180
|
+
padding: 0 1;
|
|
181
|
+
background: $background;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.hint {
|
|
185
|
+
color: $foreground;
|
|
186
|
+
text-style: italic;
|
|
187
|
+
padding: 0 1;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
TabbedContent {
|
|
191
|
+
height: 1fr;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
TabbedContent Tabs {
|
|
195
|
+
background: $panel;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
Tree {
|
|
199
|
+
background: transparent;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
Tree > .tree--label {
|
|
203
|
+
color: $foreground;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
Tree > .tree--label-highlighted {
|
|
207
|
+
background: $primary;
|
|
208
|
+
color: white;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* --- Refresh screen --- */
|
|
212
|
+
|
|
213
|
+
#refresh-top {
|
|
214
|
+
height: auto;
|
|
215
|
+
margin-bottom: 1;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.panel {
|
|
219
|
+
width: 1fr;
|
|
220
|
+
height: auto;
|
|
221
|
+
border: round $primary;
|
|
222
|
+
padding: 0 1;
|
|
223
|
+
margin-right: 1;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.panel-title {
|
|
227
|
+
color: $accent;
|
|
228
|
+
text-style: bold;
|
|
229
|
+
margin-bottom: 1;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.stats-text {
|
|
233
|
+
color: $foreground;
|
|
234
|
+
height: auto;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
#refresh-actions Button {
|
|
238
|
+
margin-bottom: 1;
|
|
239
|
+
width: 100%;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
#refresh-log {
|
|
243
|
+
height: 1fr;
|
|
244
|
+
border: round $panel;
|
|
245
|
+
padding: 0 1;
|
|
246
|
+
background: $background;
|
|
247
|
+
color: $foreground;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* --- Cost screen --- */
|
|
251
|
+
|
|
252
|
+
#cost-controls {
|
|
253
|
+
height: 3;
|
|
254
|
+
margin-bottom: 1;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.cost-window {
|
|
258
|
+
width: 20;
|
|
259
|
+
margin: 0 1;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
#cost-controls Button {
|
|
263
|
+
margin-left: 2;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
#cost-main {
|
|
267
|
+
height: 1fr;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
#cost-views-pane {
|
|
271
|
+
width: 28;
|
|
272
|
+
margin-right: 1;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
#cost-views-list {
|
|
276
|
+
background: transparent;
|
|
277
|
+
height: 1fr;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
#cost-content {
|
|
281
|
+
width: 1fr;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
#cost-status {
|
|
285
|
+
height: auto;
|
|
286
|
+
margin-bottom: 1;
|
|
287
|
+
color: $accent;
|
|
288
|
+
text-style: bold;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
#cost-table {
|
|
292
|
+
height: 1fr;
|
|
293
|
+
background: $background;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* --- Risk screen --- */
|
|
297
|
+
|
|
298
|
+
.actions-row {
|
|
299
|
+
height: 3;
|
|
300
|
+
margin-bottom: 1;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.actions-row Button {
|
|
304
|
+
margin-right: 1;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
#rs-summary {
|
|
308
|
+
color: $accent;
|
|
309
|
+
text-style: bold;
|
|
310
|
+
height: auto;
|
|
311
|
+
margin-bottom: 0;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
#rs-diff {
|
|
315
|
+
color: $snowglobe-diff;
|
|
316
|
+
text-style: italic;
|
|
317
|
+
height: auto;
|
|
318
|
+
margin-bottom: 1;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
#rs-table,
|
|
322
|
+
#dm-table,
|
|
323
|
+
#dg-table,
|
|
324
|
+
#un-table {
|
|
325
|
+
height: 1fr;
|
|
326
|
+
background: $background;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
#es-result {
|
|
330
|
+
height: 1fr;
|
|
331
|
+
border: round $primary;
|
|
332
|
+
padding: 0 1;
|
|
333
|
+
background: $background;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* --- Tune screen --- */
|
|
337
|
+
|
|
338
|
+
#tu-controls {
|
|
339
|
+
height: 3;
|
|
340
|
+
margin-bottom: 0;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
#tu-controls .form-input {
|
|
344
|
+
width: 1fr;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
#tu-controls Button {
|
|
348
|
+
margin-left: 1;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
#tu-status {
|
|
352
|
+
color: $accent;
|
|
353
|
+
text-style: italic;
|
|
354
|
+
height: auto;
|
|
355
|
+
margin-bottom: 1;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
#tu-body {
|
|
359
|
+
height: 1fr;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
#tu-sql-pane,
|
|
363
|
+
#tu-analysis-pane {
|
|
364
|
+
width: 1fr;
|
|
365
|
+
margin-right: 1;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
#tu-sql {
|
|
369
|
+
height: 1fr;
|
|
370
|
+
background: $background;
|
|
371
|
+
padding: 1;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
#tu-heuristics {
|
|
375
|
+
padding: 1;
|
|
376
|
+
color: $foreground;
|
|
377
|
+
height: 1fr;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
#tu-insights-table,
|
|
381
|
+
#tu-exp-table {
|
|
382
|
+
height: 1fr;
|
|
383
|
+
background: $background;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
#tu-tree {
|
|
387
|
+
background: $background;
|
|
388
|
+
height: 1fr;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
#tu-ai {
|
|
392
|
+
background: $background;
|
|
393
|
+
color: $foreground;
|
|
394
|
+
padding: 1;
|
|
395
|
+
height: 1fr;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* --- Reports screen --- */
|
|
399
|
+
|
|
400
|
+
#rp-form {
|
|
401
|
+
height: auto;
|
|
402
|
+
margin-bottom: 1;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
#rp-preview {
|
|
406
|
+
height: 1fr;
|
|
407
|
+
background: $background;
|
|
408
|
+
border: round $primary;
|
|
409
|
+
padding: 1;
|
|
410
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: snowglobe-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Explainable cost and access visibility for Snowflake
|
|
5
5
|
Author-email: Jaryd Thornton <jaryd90@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
7
|
-
Requires-Python: >=3.12
|
|
7
|
+
Requires-Python: >=3.12.3
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Dist: cryptography==45.0.5
|
|
@@ -98,7 +98,7 @@ pip install -e '.[tui]'
|
|
|
98
98
|
|
|
99
99
|
## Requirements
|
|
100
100
|
|
|
101
|
-
- Python **3.12+**
|
|
101
|
+
- Python **3.12.3+**
|
|
102
102
|
- A Snowflake account
|
|
103
103
|
- A Snowflake role with `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE` (grants read access to `ACCOUNT_USAGE`)
|
|
104
104
|
- Optionally: `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE` for `ORGANIZATION_USAGE` to get your contracted storage rate
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|