snowflake-cli 3.11.0__py3-none-any.whl → 3.13.0__py3-none-any.whl

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 (56) hide show
  1. snowflake/cli/__about__.py +1 -1
  2. snowflake/cli/_app/cli_app.py +43 -1
  3. snowflake/cli/_app/commands_registration/builtin_plugins.py +1 -1
  4. snowflake/cli/_app/commands_registration/command_plugins_loader.py +14 -1
  5. snowflake/cli/_app/printing.py +153 -19
  6. snowflake/cli/_app/telemetry.py +25 -10
  7. snowflake/cli/_plugins/auth/__init__.py +0 -2
  8. snowflake/cli/_plugins/connection/commands.py +1 -78
  9. snowflake/cli/_plugins/dbt/commands.py +44 -19
  10. snowflake/cli/_plugins/dbt/constants.py +1 -1
  11. snowflake/cli/_plugins/dbt/manager.py +252 -47
  12. snowflake/cli/_plugins/dcm/commands.py +65 -90
  13. snowflake/cli/_plugins/dcm/manager.py +137 -50
  14. snowflake/cli/_plugins/logs/commands.py +7 -0
  15. snowflake/cli/_plugins/logs/manager.py +21 -1
  16. snowflake/cli/_plugins/nativeapp/entities/application_package.py +4 -1
  17. snowflake/cli/_plugins/nativeapp/sf_sql_facade.py +3 -1
  18. snowflake/cli/_plugins/object/manager.py +1 -0
  19. snowflake/cli/_plugins/snowpark/common.py +1 -0
  20. snowflake/cli/_plugins/snowpark/package/anaconda_packages.py +29 -5
  21. snowflake/cli/_plugins/snowpark/package_utils.py +44 -3
  22. snowflake/cli/_plugins/spcs/services/commands.py +19 -1
  23. snowflake/cli/_plugins/spcs/services/manager.py +17 -4
  24. snowflake/cli/_plugins/spcs/services/service_entity_model.py +5 -0
  25. snowflake/cli/_plugins/sql/lexer/types.py +1 -0
  26. snowflake/cli/_plugins/sql/repl.py +100 -26
  27. snowflake/cli/_plugins/sql/repl_commands.py +607 -0
  28. snowflake/cli/_plugins/sql/statement_reader.py +44 -20
  29. snowflake/cli/_plugins/streamlit/streamlit_entity.py +28 -2
  30. snowflake/cli/_plugins/streamlit/streamlit_entity_model.py +24 -4
  31. snowflake/cli/api/artifacts/bundle_map.py +32 -2
  32. snowflake/cli/api/artifacts/regex_resolver.py +54 -0
  33. snowflake/cli/api/artifacts/upload.py +5 -1
  34. snowflake/cli/api/artifacts/utils.py +12 -1
  35. snowflake/cli/api/cli_global_context.py +7 -0
  36. snowflake/cli/api/commands/decorators.py +7 -0
  37. snowflake/cli/api/commands/flags.py +24 -1
  38. snowflake/cli/api/console/abc.py +13 -2
  39. snowflake/cli/api/console/console.py +20 -0
  40. snowflake/cli/api/constants.py +9 -0
  41. snowflake/cli/api/entities/utils.py +10 -6
  42. snowflake/cli/api/feature_flags.py +3 -2
  43. snowflake/cli/api/identifiers.py +18 -1
  44. snowflake/cli/api/project/schemas/entities/entities.py +0 -6
  45. snowflake/cli/api/rendering/sql_templates.py +2 -0
  46. {snowflake_cli-3.11.0.dist-info → snowflake_cli-3.13.0.dist-info}/METADATA +7 -7
  47. {snowflake_cli-3.11.0.dist-info → snowflake_cli-3.13.0.dist-info}/RECORD +51 -54
  48. snowflake/cli/_plugins/auth/keypair/__init__.py +0 -0
  49. snowflake/cli/_plugins/auth/keypair/commands.py +0 -153
  50. snowflake/cli/_plugins/auth/keypair/manager.py +0 -331
  51. snowflake/cli/_plugins/dcm/dcm_project_entity_model.py +0 -59
  52. snowflake/cli/_plugins/sql/snowsql_commands.py +0 -331
  53. /snowflake/cli/_plugins/auth/{keypair/plugin_spec.py → plugin_spec.py} +0 -0
  54. {snowflake_cli-3.11.0.dist-info → snowflake_cli-3.13.0.dist-info}/WHEEL +0 -0
  55. {snowflake_cli-3.11.0.dist-info → snowflake_cli-3.13.0.dist-info}/entry_points.txt +0 -0
  56. {snowflake_cli-3.11.0.dist-info → snowflake_cli-3.13.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,331 +0,0 @@
1
- import enum
2
- import re
3
- import time
4
- from dataclasses import dataclass
5
- from datetime import datetime
6
- from typing import Any, Dict, Generator, Iterable, List, Tuple
7
- from urllib.parse import urlencode
8
-
9
- from snowflake.cli._app.printing import print_result
10
- from snowflake.cli.api.output.types import CollectionResult, QueryResult
11
- from snowflake.connector import SnowflakeConnection
12
-
13
- VALID_UUID_RE = re.compile(
14
- r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
15
- )
16
-
17
-
18
- class CommandType(enum.Enum):
19
- QUERIES = "queries"
20
- UNKNOWN = "unknown"
21
- URL = "url"
22
-
23
-
24
- class SnowSQLCommand:
25
- def execute(self, connection: SnowflakeConnection):
26
- """Executes command and prints the result."""
27
- raise NotImplementedError
28
-
29
- @classmethod
30
- def from_args(cls, args, kwargs) -> "CompileCommandResult":
31
- """Validates arguments and creates command ready for execution."""
32
- raise NotImplementedError
33
-
34
-
35
- def _print_result_to_stdout(headers: Iterable[str], rows: Iterable[Iterable[Any]]):
36
- formatted_rows: Generator[Dict[str, Any], None, None] = (
37
- {key: value for key, value in zip(headers, row)} for row in rows
38
- )
39
- print_result(CollectionResult(formatted_rows))
40
-
41
-
42
- @dataclass
43
- class CompileCommandResult:
44
- command: SnowSQLCommand | None = None
45
- error_message: str | None = None
46
-
47
-
48
- @dataclass
49
- class QueriesCommand(SnowSQLCommand):
50
- help_mode: bool = False
51
- from_current_session: bool = False
52
- amount: int = 25
53
- user: str | None = None
54
- warehouse: str | None = None
55
- start_timestamp_ms: int | None = None
56
- end_timestamp_ms: int | None = None
57
- duration: str | None = None
58
- stmt_type: str | None = None
59
- status: str | None = None
60
-
61
- def execute(self, connection: SnowflakeConnection) -> None:
62
- if self.help_mode:
63
- self._execute_help()
64
- else:
65
- self._execute_queries(connection)
66
-
67
- def _execute_help(self):
68
- headers = ["FILTER", "ARGUMENT", "DEFAULT"]
69
- filters = [
70
- ["amount", "integer", "25"],
71
- ["status", "string", "any"],
72
- ["warehouse", "string", "any"],
73
- ["user", "string", "any"],
74
- [
75
- "start_date",
76
- "datetime in ISO format (for example YYYY-MM-DDTHH:mm:ss.sss)",
77
- "any",
78
- ],
79
- [
80
- "end_date",
81
- "datetime in ISO format (for example YYYY-MM-DDTHH:mm:ss.sss)",
82
- "any",
83
- ],
84
- ["start", "timestamp in milliseconds (integer)", "any"],
85
- ["end", "timestamp in milliseconds (integer)", "any"],
86
- ["type", "string", "any"],
87
- ["duration", "time in milliseconds", "any"],
88
- ["session", "No arguments", "any"],
89
- ]
90
- _print_result_to_stdout(headers, filters)
91
-
92
- def _execute_queries(self, connection: SnowflakeConnection) -> None:
93
- url_parameters = {
94
- "_dc": f"{time.time()}",
95
- "includeDDL": "false",
96
- "max": self.amount,
97
- }
98
- if self.user:
99
- url_parameters["user"] = self.user
100
- if self.warehouse:
101
- url_parameters["wh"] = self.warehouse
102
- if self.start_timestamp_ms:
103
- url_parameters["start"] = self.start_timestamp_ms
104
- if self.end_timestamp_ms:
105
- url_parameters["end"] = self.end_timestamp_ms
106
- if self.duration:
107
- url_parameters["min_duration"] = self.duration
108
- if self.from_current_session:
109
- url_parameters["session_id"] = connection.session_id
110
- if self.status:
111
- url_parameters["subset"] = self.status
112
- if self.stmt_type:
113
- url_parameters["stmt_type"] = self.stmt_type
114
-
115
- url = "/monitoring/queries?" + urlencode(url_parameters)
116
- ret = connection.rest.request(url=url, method="get", client="rest")
117
- if ret.get("data") and ret["data"].get("queries"):
118
- _result: Generator[Tuple[str, str, str, str], None, None] = (
119
- (
120
- query["id"],
121
- query["sqlText"],
122
- query["state"],
123
- query["totalDuration"],
124
- )
125
- for query in ret["data"]["queries"]
126
- )
127
- _print_result_to_stdout(
128
- ["QUERY ID", "SQL TEXT", "STATUS", "DURATION_MS"], _result
129
- )
130
-
131
- @classmethod
132
- def from_args(cls, args: List[str], kwargs: Dict[str, Any]) -> CompileCommandResult:
133
- if "help" in args:
134
- return CompileCommandResult(command=cls(help_mode=True))
135
-
136
- # "session" is set by default if no other arguments are provided
137
- from_current_session = "session" in args or not kwargs
138
- amount = kwargs.pop("amount", "25")
139
- if not amount.isdigit():
140
- return CompileCommandResult(
141
- error_message=f"Invalid argument passed to 'amount' filter: {amount}"
142
- )
143
- user = kwargs.pop("user", None)
144
- warehouse = kwargs.pop("warehouse", None)
145
- duration = kwargs.pop("duration", None)
146
-
147
- start_timestamp_ms = kwargs.pop("start", None)
148
- if start_timestamp_ms:
149
- try:
150
- start_timestamp_ms = int(start_timestamp_ms)
151
- except ValueError:
152
- return CompileCommandResult(
153
- error_message=f"Invalid argument passed to 'start' filter: {start_timestamp_ms}"
154
- )
155
- end_timestamp_ms = kwargs.pop("end", None)
156
- if end_timestamp_ms:
157
- try:
158
- end_timestamp_ms = int(end_timestamp_ms)
159
- except ValueError:
160
- return CompileCommandResult(
161
- error_message=f"Invalid argument passed to 'end' filter: {end_timestamp_ms}"
162
- )
163
-
164
- start_date = kwargs.pop("start_date", None)
165
- if start_date:
166
- if start_timestamp_ms:
167
- return CompileCommandResult(
168
- error_message=f"'start_date' filter cannot be used with 'start' filter"
169
- )
170
- try:
171
- seconds = datetime.fromisoformat(start_date).timestamp()
172
- start_timestamp_ms = int(seconds * 1000) # convert to milliseconds
173
- except ValueError:
174
- return CompileCommandResult(
175
- error_message=f"Invalid date format passed to 'start_date' filter: {start_date}"
176
- )
177
- end_date = kwargs.pop("end_date", None)
178
- if end_date:
179
- if end_timestamp_ms:
180
- return CompileCommandResult(
181
- error_message=f"'end_date' filter cannot be used with 'end' filter"
182
- )
183
- try:
184
- seconds = datetime.fromisoformat(end_date).timestamp()
185
- end_timestamp_ms = int(seconds * 1000) # convert to milliseconds
186
- except ValueError:
187
- return CompileCommandResult(
188
- error_message=f"Invalid date format passed to 'end_date' filter: {end_date}"
189
- )
190
-
191
- stmt_type = kwargs.pop("type", None)
192
- if stmt_type:
193
- stmt_type = stmt_type.upper()
194
- if stmt_type not in [
195
- "ANY",
196
- "SELECT",
197
- "INSERT",
198
- "UPDATE",
199
- "DELETE",
200
- "MERGE",
201
- "MULTI_TABLE_INSERT",
202
- "COPY",
203
- "COMMIT",
204
- "ROLLBACK",
205
- "BEGIN_TRANSACTION",
206
- "SHOW",
207
- "GRANT",
208
- "CREATE",
209
- "ALTER",
210
- ]:
211
- return CompileCommandResult(
212
- error_message=f"Invalid argument passed to 'type' filter: {stmt_type}"
213
- )
214
-
215
- status = kwargs.pop("status", None)
216
- if status:
217
- status = status.upper()
218
- if status not in [
219
- "RUNNING",
220
- "SUCCEEDED",
221
- "FAILED",
222
- "BLOCKED",
223
- "QUEUED",
224
- "ABORTED",
225
- ]:
226
- return CompileCommandResult(
227
- error_message=f"Invalid argument passed to 'status' filter: {status}"
228
- )
229
-
230
- for arg in args:
231
- if arg.lower() not in ["session", "help"]:
232
- return CompileCommandResult(
233
- error_message=f"Invalid argument passed to 'queries' command: {arg}"
234
- )
235
- if kwargs:
236
- key, value = kwargs.popitem()
237
- return CompileCommandResult(
238
- error_message=f"Invalid argument passed to 'queries' command: {key}={value}"
239
- )
240
-
241
- return CompileCommandResult(
242
- command=cls(
243
- help_mode=False,
244
- from_current_session=from_current_session,
245
- amount=int(amount),
246
- user=user,
247
- warehouse=warehouse,
248
- start_timestamp_ms=start_timestamp_ms,
249
- end_timestamp_ms=end_timestamp_ms,
250
- duration=duration,
251
- stmt_type=stmt_type,
252
- status=status,
253
- )
254
- )
255
-
256
-
257
- def _validate_only_arg_is_query_id(
258
- command_name: str, args: List[str], kwargs: Dict[str, Any]
259
- ) -> str | None:
260
- if kwargs:
261
- key, value = kwargs.popitem()
262
- return f"Invalid argument passed to '{command_name}' command: {key}={value}"
263
- if len(args) != 1:
264
- amount = "Too many" if args else "No"
265
- return f"{amount} arguments passed to '{command_name}' command. Usage: `!{command_name} <query id>`"
266
-
267
- qid = args[0]
268
- if not VALID_UUID_RE.match(qid):
269
- return f"Invalid query ID passed to '{command_name}' command: {qid}"
270
-
271
- return None
272
-
273
-
274
- @dataclass
275
- class ResultCommand(SnowSQLCommand):
276
- query_id: str
277
-
278
- def execute(self, connection: SnowflakeConnection):
279
- cursor = connection.cursor()
280
- cursor.query_result(self.query_id)
281
- print_result(QueryResult(cursor=cursor))
282
-
283
- @classmethod
284
- def from_args(cls, args, kwargs) -> CompileCommandResult:
285
- error_msg = _validate_only_arg_is_query_id("result", args, kwargs)
286
- if error_msg:
287
- return CompileCommandResult(error_message=error_msg)
288
- return CompileCommandResult(command=cls(args[0]))
289
-
290
-
291
- @dataclass
292
- class AbortCommand(SnowSQLCommand):
293
- query_id: str
294
-
295
- def execute(self, connection: SnowflakeConnection):
296
- cursor = connection.cursor()
297
- cursor.execute(f"SELECT SYSTEM$CANCEL_QUERY('{self.query_id}')")
298
- print_result(QueryResult(cursor=cursor))
299
-
300
- @classmethod
301
- def from_args(cls, args, kwargs) -> CompileCommandResult:
302
- error_msg = _validate_only_arg_is_query_id("abort", args, kwargs)
303
- if error_msg:
304
- return CompileCommandResult(error_message=error_msg)
305
- return CompileCommandResult(command=cls(args[0]))
306
-
307
-
308
- def compile_snowsql_command(command: str, cmd_args: List[str]):
309
- """Parses command into SQL query"""
310
- args = []
311
- kwargs = {}
312
- for cmd_arg in cmd_args:
313
- if "=" not in cmd_arg:
314
- args.append(cmd_arg)
315
- else:
316
- key, val = cmd_arg.split("=", maxsplit=1)
317
- if key in kwargs:
318
- return CompileCommandResult(
319
- error_message=f"duplicated argument '{key}' for command '{command}'",
320
- )
321
- kwargs[key] = val
322
-
323
- match command.lower():
324
- case "!queries":
325
- return QueriesCommand.from_args(args, kwargs)
326
- case "!result":
327
- return ResultCommand.from_args(args, kwargs)
328
- case "!abort":
329
- return AbortCommand.from_args(args, kwargs)
330
- case _:
331
- return CompileCommandResult(error_message=f"Unknown command '{command}'")