snowflake-cli-labs 3.0.0rc2__py3-none-any.whl → 3.0.0rc4__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.
- snowflake/cli/__about__.py +1 -1
- snowflake/cli/_app/commands_registration/builtin_plugins.py +2 -0
- snowflake/cli/_app/secret.py +9 -0
- snowflake/cli/_app/snow_connector.py +39 -27
- snowflake/cli/_app/telemetry.py +28 -0
- snowflake/cli/_plugins/connection/commands.py +9 -4
- snowflake/cli/_plugins/git/manager.py +53 -7
- snowflake/cli/_plugins/helpers/commands.py +61 -0
- snowflake/cli/{api/project/schemas/snowpark/__init__.py → _plugins/helpers/plugin_spec.py} +17 -0
- snowflake/cli/_plugins/nativeapp/artifacts.py +10 -9
- snowflake/cli/_plugins/nativeapp/bundle_context.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/artifact_processor.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/compiler.py +6 -1
- snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/extension_function_utils.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/models.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +5 -1
- snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +4 -1
- snowflake/cli/_plugins/nativeapp/commands.py +87 -96
- snowflake/cli/_plugins/nativeapp/entities/__init__.py +0 -0
- snowflake/cli/{api/entities/application_entity.py → _plugins/nativeapp/entities/application.py} +264 -83
- snowflake/cli/_plugins/nativeapp/entities/application_package.py +1392 -0
- snowflake/cli/_plugins/nativeapp/exceptions.py +0 -9
- snowflake/cli/_plugins/nativeapp/manager.py +69 -185
- snowflake/cli/_plugins/nativeapp/policy.py +3 -0
- snowflake/cli/_plugins/nativeapp/project_model.py +2 -2
- snowflake/cli/_plugins/nativeapp/run_processor.py +17 -20
- snowflake/cli/_plugins/nativeapp/same_account_install_method.py +0 -4
- snowflake/cli/_plugins/nativeapp/teardown_processor.py +4 -6
- snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +122 -88
- snowflake/cli/_plugins/nativeapp/version/commands.py +7 -39
- snowflake/cli/_plugins/nativeapp/version/version_processor.py +46 -312
- snowflake/cli/_plugins/object/manager.py +36 -15
- snowflake/cli/_plugins/snowpark/commands.py +4 -4
- snowflake/cli/_plugins/snowpark/common.py +4 -4
- snowflake/cli/{api/entities → _plugins/snowpark}/snowpark_entity.py +2 -2
- snowflake/cli/{api/project/schemas/entities/snowpark_entity.py → _plugins/snowpark/snowpark_entity_model.py} +3 -6
- snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +1 -1
- snowflake/cli/_plugins/stage/manager.py +9 -4
- snowflake/cli/_plugins/streamlit/commands.py +15 -3
- snowflake/cli/_plugins/streamlit/manager.py +12 -4
- snowflake/cli/{api/entities → _plugins/streamlit}/streamlit_entity.py +2 -2
- snowflake/cli/{api/project/schemas/entities → _plugins/streamlit}/streamlit_entity_model.py +5 -12
- snowflake/cli/_plugins/workspace/commands.py +116 -36
- snowflake/cli/_plugins/workspace/plugin_spec.py +1 -1
- snowflake/cli/api/cli_global_context.py +7 -0
- snowflake/cli/api/commands/decorators.py +14 -0
- snowflake/cli/api/commands/flags.py +18 -0
- snowflake/cli/api/commands/snow_typer.py +1 -1
- snowflake/cli/api/config.py +25 -6
- snowflake/cli/api/connections.py +3 -1
- snowflake/cli/api/entities/common.py +4 -0
- snowflake/cli/api/entities/utils.py +3 -14
- snowflake/cli/api/errno.py +1 -0
- snowflake/cli/api/identifiers.py +4 -3
- snowflake/cli/api/metrics.py +92 -0
- snowflake/cli/api/project/definition_conversion.py +61 -18
- snowflake/cli/api/project/schemas/entities/common.py +17 -4
- snowflake/cli/api/project/schemas/entities/entities.py +11 -10
- snowflake/cli/api/project/schemas/project_definition.py +5 -7
- snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{identifier_model.py → v1/identifier_model.py} +0 -7
- snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{native_app → v1/native_app}/native_app.py +4 -4
- snowflake/cli/api/project/schemas/v1/snowpark/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/callable.py +2 -2
- snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/snowpark.py +2 -2
- snowflake/cli/api/project/schemas/v1/streamlit/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{streamlit → v1/streamlit}/streamlit.py +2 -1
- snowflake/cli/api/rendering/sql_templates.py +6 -0
- snowflake/cli/api/rest_api.py +11 -5
- snowflake/cli/api/sql_execution.py +6 -15
- snowflake/cli/api/utils/definition_rendering.py +24 -4
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/METADATA +9 -7
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/RECORD +83 -79
- snowflake/cli/_plugins/nativeapp/init.py +0 -345
- snowflake/cli/api/entities/application_package_entity.py +0 -658
- snowflake/cli/api/project/schemas/entities/application_entity_model.py +0 -56
- snowflake/cli/api/project/schemas/entities/application_package_entity_model.py +0 -94
- snowflake/cli/api/project/schemas/streamlit/__init__.py +0 -13
- /snowflake/cli/{api/project/schemas/native_app → _plugins/helpers}/__init__.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/application.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/package.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/path_mapping.py +0 -0
- /snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/argument.py +0 -0
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/entry_points.txt +0 -0
- {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/licenses/LICENSE +0 -0
|
@@ -48,15 +48,6 @@ class ApplicationCreatedExternallyError(ClickException):
|
|
|
48
48
|
)
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
class UnexpectedOwnerError(ClickException):
|
|
52
|
-
"""An operation is blocked because an object is owned by an unexpected role."""
|
|
53
|
-
|
|
54
|
-
def __init__(self, item: str, expected_owner: str, actual_owner: str):
|
|
55
|
-
super().__init__(
|
|
56
|
-
f"Cannot operate on {item}: owned by {actual_owner} (expected {expected_owner})"
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
|
|
60
51
|
class MissingScriptError(ClickException):
|
|
61
52
|
"""A referenced script was not found."""
|
|
62
53
|
|
|
@@ -14,21 +14,23 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
import time
|
|
18
17
|
from abc import ABC, abstractmethod
|
|
19
18
|
from datetime import datetime
|
|
20
19
|
from functools import cached_property
|
|
21
20
|
from pathlib import Path
|
|
22
|
-
from textwrap import dedent
|
|
23
21
|
from typing import Generator, List, Optional
|
|
24
22
|
|
|
25
|
-
from snowflake.cli._plugins.connection.util import make_snowsight_url
|
|
26
23
|
from snowflake.cli._plugins.nativeapp.artifacts import (
|
|
27
24
|
BundleMap,
|
|
28
25
|
)
|
|
29
|
-
from snowflake.cli._plugins.nativeapp.
|
|
30
|
-
|
|
26
|
+
from snowflake.cli._plugins.nativeapp.entities.application import (
|
|
27
|
+
ApplicationEntity,
|
|
28
|
+
ApplicationOwnedObject,
|
|
29
|
+
)
|
|
30
|
+
from snowflake.cli._plugins.nativeapp.entities.application_package import (
|
|
31
|
+
ApplicationPackageEntity,
|
|
31
32
|
)
|
|
33
|
+
from snowflake.cli._plugins.nativeapp.policy import AllowAlwaysPolicy, PolicyBase
|
|
32
34
|
from snowflake.cli._plugins.nativeapp.project_model import (
|
|
33
35
|
NativeAppProjectModel,
|
|
34
36
|
)
|
|
@@ -36,27 +38,13 @@ from snowflake.cli._plugins.stage.diff import (
|
|
|
36
38
|
DiffResult,
|
|
37
39
|
)
|
|
38
40
|
from snowflake.cli.api.console import cli_console as cc
|
|
39
|
-
from snowflake.cli.api.entities.application_entity import (
|
|
40
|
-
ApplicationEntity,
|
|
41
|
-
ApplicationOwnedObject,
|
|
42
|
-
)
|
|
43
|
-
from snowflake.cli.api.entities.application_package_entity import (
|
|
44
|
-
ApplicationPackageEntity,
|
|
45
|
-
)
|
|
46
41
|
from snowflake.cli.api.entities.utils import (
|
|
47
42
|
execute_post_deploy_hooks,
|
|
48
|
-
generic_sql_error_handler,
|
|
49
43
|
sync_deploy_root_with_stage,
|
|
50
44
|
)
|
|
51
45
|
from snowflake.cli.api.project.schemas.entities.common import PostDeployHook
|
|
52
|
-
from snowflake.cli.api.project.schemas.native_app.native_app import NativeApp
|
|
53
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import PathMapping
|
|
54
|
-
from snowflake.cli.api.project.util import (
|
|
55
|
-
identifier_for_url,
|
|
56
|
-
unquote_identifier,
|
|
57
|
-
)
|
|
58
|
-
from snowflake.cli.api.sql_execution import SqlExecutionMixin
|
|
59
|
-
from snowflake.connector import DictCursor, ProgrammingError
|
|
46
|
+
from snowflake.cli.api.project.schemas.v1.native_app.native_app import NativeApp
|
|
47
|
+
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import PathMapping
|
|
60
48
|
|
|
61
49
|
|
|
62
50
|
class NativeAppCommandProcessor(ABC):
|
|
@@ -65,7 +53,7 @@ class NativeAppCommandProcessor(ABC):
|
|
|
65
53
|
pass
|
|
66
54
|
|
|
67
55
|
|
|
68
|
-
class NativeAppManager
|
|
56
|
+
class NativeAppManager:
|
|
69
57
|
"""
|
|
70
58
|
Base class with frequently used functionality already implemented and ready to be used by related subclasses.
|
|
71
59
|
"""
|
|
@@ -134,9 +122,6 @@ class NativeAppManager(SqlExecutionMixin):
|
|
|
134
122
|
def application_warehouse(self) -> Optional[str]:
|
|
135
123
|
return self.na_project.application_warehouse
|
|
136
124
|
|
|
137
|
-
def use_application_warehouse(self):
|
|
138
|
-
return ApplicationEntity.use_application_warehouse(self.application_warehouse)
|
|
139
|
-
|
|
140
125
|
@property
|
|
141
126
|
def project_identifier(self) -> str:
|
|
142
127
|
return self.na_project.project_identifier
|
|
@@ -181,9 +166,7 @@ class NativeAppManager(SqlExecutionMixin):
|
|
|
181
166
|
|
|
182
167
|
@cached_property
|
|
183
168
|
def account_event_table(self) -> str:
|
|
184
|
-
|
|
185
|
-
results = self._execute_query(query, cursor_class=DictCursor)
|
|
186
|
-
return next((r["value"] for r in results if r["key"] == "EVENT_TABLE"), "")
|
|
169
|
+
return ApplicationEntity.get_account_event_table()
|
|
187
170
|
|
|
188
171
|
def verify_project_distribution(
|
|
189
172
|
self, expected_distribution: Optional[str] = None
|
|
@@ -261,9 +244,9 @@ class NativeAppManager(SqlExecutionMixin):
|
|
|
261
244
|
|
|
262
245
|
def get_snowsight_url(self) -> str:
|
|
263
246
|
"""Returns the URL that can be used to visit this app via Snowsight."""
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
247
|
+
return ApplicationEntity.get_snowsight_url(
|
|
248
|
+
self.app_name, self.application_warehouse
|
|
249
|
+
)
|
|
267
250
|
|
|
268
251
|
def create_app_package(self) -> None:
|
|
269
252
|
return ApplicationPackageEntity.create_app_package(
|
|
@@ -306,6 +289,7 @@ class NativeAppManager(SqlExecutionMixin):
|
|
|
306
289
|
bundle_map: BundleMap,
|
|
307
290
|
prune: bool,
|
|
308
291
|
recursive: bool,
|
|
292
|
+
policy: PolicyBase,
|
|
309
293
|
stage_fqn: Optional[str] = None,
|
|
310
294
|
local_paths_to_sync: List[Path] | None = None,
|
|
311
295
|
validate: bool = True,
|
|
@@ -318,6 +302,7 @@ class NativeAppManager(SqlExecutionMixin):
|
|
|
318
302
|
bundle_root=self.bundle_root,
|
|
319
303
|
generated_root=self.generated_root,
|
|
320
304
|
artifacts=self.artifacts,
|
|
305
|
+
bundle_map=bundle_map,
|
|
321
306
|
package_name=self.package_name,
|
|
322
307
|
package_role=self.package_role,
|
|
323
308
|
package_distribution=self.package_distribution,
|
|
@@ -330,42 +315,56 @@ class NativeAppManager(SqlExecutionMixin):
|
|
|
330
315
|
package_warehouse=self.package_warehouse,
|
|
331
316
|
post_deploy_hooks=self.package_post_deploy_hooks,
|
|
332
317
|
package_scripts=self.package_scripts,
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
def deploy_to_scratch_stage_fn(self):
|
|
336
|
-
bundle_map = self.build_bundle()
|
|
337
|
-
self.deploy(
|
|
338
|
-
bundle_map=bundle_map,
|
|
339
|
-
prune=True,
|
|
340
|
-
recursive=True,
|
|
341
|
-
stage_fqn=self.scratch_stage_fqn,
|
|
342
|
-
validate=False,
|
|
343
|
-
print_diff=False,
|
|
318
|
+
policy=policy,
|
|
344
319
|
)
|
|
345
320
|
|
|
346
321
|
def validate(self, use_scratch_stage: bool = False):
|
|
347
322
|
return ApplicationPackageEntity.validate_setup_script(
|
|
348
323
|
console=cc,
|
|
324
|
+
project_root=self.project_root,
|
|
325
|
+
deploy_root=self.deploy_root,
|
|
326
|
+
bundle_root=self.bundle_root,
|
|
327
|
+
generated_root=self.generated_root,
|
|
328
|
+
artifacts=self.artifacts,
|
|
349
329
|
package_name=self.package_name,
|
|
350
330
|
package_role=self.package_role,
|
|
331
|
+
package_distribution=self.package_distribution,
|
|
332
|
+
prune=True,
|
|
333
|
+
recursive=True,
|
|
334
|
+
paths=[],
|
|
351
335
|
stage_fqn=self.stage_fqn,
|
|
336
|
+
package_warehouse=self.package_warehouse,
|
|
337
|
+
post_deploy_hooks=self.package_post_deploy_hooks,
|
|
338
|
+
package_scripts=self.package_scripts,
|
|
339
|
+
policy=AllowAlwaysPolicy(),
|
|
352
340
|
use_scratch_stage=use_scratch_stage,
|
|
353
341
|
scratch_stage_fqn=self.scratch_stage_fqn,
|
|
354
|
-
deploy_to_scratch_stage_fn=self.deploy_to_scratch_stage_fn,
|
|
355
342
|
)
|
|
356
343
|
|
|
357
|
-
def get_validation_result(self, use_scratch_stage: bool):
|
|
344
|
+
def get_validation_result(self, use_scratch_stage: bool = False):
|
|
358
345
|
return ApplicationPackageEntity.get_validation_result(
|
|
359
346
|
console=cc,
|
|
347
|
+
project_root=self.project_root,
|
|
348
|
+
deploy_root=self.deploy_root,
|
|
349
|
+
bundle_root=self.bundle_root,
|
|
350
|
+
generated_root=self.generated_root,
|
|
351
|
+
artifacts=self.artifacts,
|
|
360
352
|
package_name=self.package_name,
|
|
361
353
|
package_role=self.package_role,
|
|
354
|
+
package_distribution=self.package_distribution,
|
|
355
|
+
prune=True,
|
|
356
|
+
recursive=True,
|
|
357
|
+
paths=[],
|
|
362
358
|
stage_fqn=self.stage_fqn,
|
|
359
|
+
package_warehouse=self.package_warehouse,
|
|
360
|
+
post_deploy_hooks=self.package_post_deploy_hooks,
|
|
361
|
+
package_scripts=self.package_scripts,
|
|
362
|
+
policy=AllowAlwaysPolicy(),
|
|
363
363
|
use_scratch_stage=use_scratch_stage,
|
|
364
364
|
scratch_stage_fqn=self.scratch_stage_fqn,
|
|
365
|
-
deploy_to_scratch_stage_fn=self.deploy_to_scratch_stage_fn,
|
|
366
365
|
)
|
|
367
366
|
|
|
368
|
-
def get_events( # type: ignore
|
|
367
|
+
def get_events( # type: ignore
|
|
369
368
|
self,
|
|
370
369
|
since: str | datetime | None = None,
|
|
371
370
|
until: str | datetime | None = None,
|
|
@@ -377,87 +376,19 @@ class NativeAppManager(SqlExecutionMixin):
|
|
|
377
376
|
first: int = -1,
|
|
378
377
|
last: int = -1,
|
|
379
378
|
) -> list[dict]:
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
org_name = unquote_identifier(consumer_org)
|
|
393
|
-
account_name = unquote_identifier(consumer_account)
|
|
394
|
-
|
|
395
|
-
# Filter on record attributes
|
|
396
|
-
if consumer_org and consumer_account:
|
|
397
|
-
# Look for events shared from a consumer account
|
|
398
|
-
app_clause = (
|
|
399
|
-
f"resource_attributes:\"snow.application.package.name\" = '{package_name}' "
|
|
400
|
-
f"and resource_attributes:\"snow.application.consumer.organization\" = '{org_name}' "
|
|
401
|
-
f"and resource_attributes:\"snow.application.consumer.name\" = '{account_name}'"
|
|
402
|
-
)
|
|
403
|
-
if consumer_app_hash:
|
|
404
|
-
# If the user has specified a hash of a specific app installation
|
|
405
|
-
# in the consumer account, filter events to that installation only
|
|
406
|
-
app_clause += f" and resource_attributes:\"snow.database.hash\" = '{consumer_app_hash.lower()}'"
|
|
407
|
-
else:
|
|
408
|
-
# Otherwise look for events from an app installed in the same account as the package
|
|
409
|
-
app_clause = f"resource_attributes:\"snow.database.name\" = '{app_name}'"
|
|
410
|
-
|
|
411
|
-
# Filter on event time
|
|
412
|
-
if isinstance(since, datetime):
|
|
413
|
-
since_clause = f"and timestamp >= '{since}'"
|
|
414
|
-
elif isinstance(since, str) and since:
|
|
415
|
-
since_clause = f"and timestamp >= sysdate() - interval '{since}'"
|
|
416
|
-
else:
|
|
417
|
-
since_clause = ""
|
|
418
|
-
if isinstance(until, datetime):
|
|
419
|
-
until_clause = f"and timestamp <= '{until}'"
|
|
420
|
-
elif isinstance(until, str) and until:
|
|
421
|
-
until_clause = f"and timestamp <= sysdate() - interval '{until}'"
|
|
422
|
-
else:
|
|
423
|
-
until_clause = ""
|
|
424
|
-
|
|
425
|
-
# Filter on event type (log, span, span_event)
|
|
426
|
-
type_in_values = ",".join(f"'{v}'" for v in record_types)
|
|
427
|
-
types_clause = (
|
|
428
|
-
f"and record_type in ({type_in_values})" if type_in_values else ""
|
|
429
|
-
)
|
|
430
|
-
|
|
431
|
-
# Filter on event scope (e.g. the logger name)
|
|
432
|
-
scope_in_values = ",".join(f"'{v}'" for v in scopes)
|
|
433
|
-
scopes_clause = (
|
|
434
|
-
f"and scope:name in ({scope_in_values})" if scope_in_values else ""
|
|
435
|
-
)
|
|
436
|
-
|
|
437
|
-
# Limit event count
|
|
438
|
-
first_clause = f"limit {first}" if first >= 0 else ""
|
|
439
|
-
last_clause = f"limit {last}" if last >= 0 else ""
|
|
440
|
-
|
|
441
|
-
query = dedent(
|
|
442
|
-
f"""\
|
|
443
|
-
select * from (
|
|
444
|
-
select timestamp, value::varchar value
|
|
445
|
-
from {self.account_event_table}
|
|
446
|
-
where ({app_clause})
|
|
447
|
-
{since_clause}
|
|
448
|
-
{until_clause}
|
|
449
|
-
{types_clause}
|
|
450
|
-
{scopes_clause}
|
|
451
|
-
order by timestamp desc
|
|
452
|
-
{last_clause}
|
|
453
|
-
) order by timestamp asc
|
|
454
|
-
{first_clause}
|
|
455
|
-
"""
|
|
379
|
+
return ApplicationEntity.get_events(
|
|
380
|
+
app_name=self.app_name,
|
|
381
|
+
package_name=self.package_name,
|
|
382
|
+
since=since,
|
|
383
|
+
until=until,
|
|
384
|
+
record_types=record_types,
|
|
385
|
+
scopes=scopes,
|
|
386
|
+
consumer_org=consumer_org,
|
|
387
|
+
consumer_account=consumer_account,
|
|
388
|
+
consumer_app_hash=consumer_app_hash,
|
|
389
|
+
first=first,
|
|
390
|
+
last=last,
|
|
456
391
|
)
|
|
457
|
-
try:
|
|
458
|
-
return self._execute_query(query, cursor_class=DictCursor).fetchall()
|
|
459
|
-
except ProgrammingError as err:
|
|
460
|
-
generic_sql_error_handler(err)
|
|
461
392
|
|
|
462
393
|
def stream_events(
|
|
463
394
|
self,
|
|
@@ -470,62 +401,15 @@ class NativeAppManager(SqlExecutionMixin):
|
|
|
470
401
|
consumer_app_hash: str = "",
|
|
471
402
|
last: int = -1,
|
|
472
403
|
) -> Generator[dict, None, None]:
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
while True: # Then infinite poll for new events
|
|
487
|
-
time.sleep(interval_seconds)
|
|
488
|
-
previous_events = events
|
|
489
|
-
events = self.get_events(
|
|
490
|
-
since=last_event_time,
|
|
491
|
-
record_types=record_types,
|
|
492
|
-
scopes=scopes,
|
|
493
|
-
consumer_org=consumer_org,
|
|
494
|
-
consumer_account=consumer_account,
|
|
495
|
-
consumer_app_hash=consumer_app_hash,
|
|
496
|
-
)
|
|
497
|
-
if not events:
|
|
498
|
-
continue
|
|
499
|
-
|
|
500
|
-
yield from _new_events_only(previous_events, events)
|
|
501
|
-
last_event_time = events[-1]["TIMESTAMP"]
|
|
502
|
-
except KeyboardInterrupt:
|
|
503
|
-
return
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
def _new_events_only(previous_events: list[dict], new_events: list[dict]) -> list[dict]:
|
|
507
|
-
# The timestamp that overlaps between both sets of events
|
|
508
|
-
overlap_time = new_events[0]["TIMESTAMP"]
|
|
509
|
-
|
|
510
|
-
# Remove all the events from the new result set
|
|
511
|
-
# if they were already printed. We iterate and remove
|
|
512
|
-
# instead of filtering in order to handle duplicates
|
|
513
|
-
# (i.e. if an event is present 3 times in new_events
|
|
514
|
-
# but only once in previous_events, it should still
|
|
515
|
-
# appear twice in new_events at the end
|
|
516
|
-
new_events = new_events.copy()
|
|
517
|
-
for event in reversed(previous_events):
|
|
518
|
-
if event["TIMESTAMP"] < overlap_time:
|
|
519
|
-
break
|
|
520
|
-
# No need to handle ValueError here since we know
|
|
521
|
-
# that events that pass the above if check will
|
|
522
|
-
# either be in both lists or in new_events only
|
|
523
|
-
new_events.remove(event)
|
|
524
|
-
return new_events
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
def _validation_item_to_str(item: dict[str, str | int]):
|
|
528
|
-
s = item["message"]
|
|
529
|
-
if item["errorCode"]:
|
|
530
|
-
s = f"{s} (error code {item['errorCode']})"
|
|
531
|
-
return s
|
|
404
|
+
return ApplicationEntity.stream_events(
|
|
405
|
+
app_name=self.app_name,
|
|
406
|
+
package_name=self.package_name,
|
|
407
|
+
interval_seconds=interval_seconds,
|
|
408
|
+
since=since,
|
|
409
|
+
record_types=record_types,
|
|
410
|
+
scopes=scopes,
|
|
411
|
+
consumer_org=consumer_org,
|
|
412
|
+
consumer_account=consumer_account,
|
|
413
|
+
consumer_app_hash=consumer_app_hash,
|
|
414
|
+
last=last,
|
|
415
|
+
)
|
|
@@ -27,6 +27,9 @@ class PolicyBase(ABC):
|
|
|
27
27
|
def should_proceed(self, user_prompt: Optional[str]) -> bool:
|
|
28
28
|
pass
|
|
29
29
|
|
|
30
|
+
def __eq__(self, value: object) -> bool:
|
|
31
|
+
return self.__class__ == value.__class__
|
|
32
|
+
|
|
30
33
|
|
|
31
34
|
class AllowAlwaysPolicy(PolicyBase):
|
|
32
35
|
"""Always allow a Snowflake CLI command to continue execution."""
|
|
@@ -28,8 +28,8 @@ from snowflake.cli.api.project.definition import (
|
|
|
28
28
|
default_role,
|
|
29
29
|
)
|
|
30
30
|
from snowflake.cli.api.project.schemas.entities.common import PostDeployHook
|
|
31
|
-
from snowflake.cli.api.project.schemas.native_app.native_app import NativeApp
|
|
32
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import PathMapping
|
|
31
|
+
from snowflake.cli.api.project.schemas.v1.native_app.native_app import NativeApp
|
|
32
|
+
from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import PathMapping
|
|
33
33
|
from snowflake.cli.api.project.util import (
|
|
34
34
|
append_test_resource_suffix,
|
|
35
35
|
extract_schema,
|
|
@@ -19,6 +19,10 @@ from typing import Optional
|
|
|
19
19
|
|
|
20
20
|
import typer
|
|
21
21
|
from snowflake.cli._plugins.nativeapp.artifacts import BundleMap
|
|
22
|
+
from snowflake.cli._plugins.nativeapp.entities.application import ApplicationEntity
|
|
23
|
+
from snowflake.cli._plugins.nativeapp.entities.application_package import (
|
|
24
|
+
ApplicationPackageEntity,
|
|
25
|
+
)
|
|
22
26
|
from snowflake.cli._plugins.nativeapp.manager import (
|
|
23
27
|
NativeAppCommandProcessor,
|
|
24
28
|
NativeAppManager,
|
|
@@ -28,9 +32,7 @@ from snowflake.cli._plugins.nativeapp.same_account_install_method import (
|
|
|
28
32
|
SameAccountInstallMethod,
|
|
29
33
|
)
|
|
30
34
|
from snowflake.cli.api.console import cli_console as cc
|
|
31
|
-
from snowflake.cli.api.entities.
|
|
32
|
-
ApplicationEntity,
|
|
33
|
-
)
|
|
35
|
+
from snowflake.cli.api.entities.common import get_sql_executor
|
|
34
36
|
from snowflake.cli.api.entities.utils import (
|
|
35
37
|
generic_sql_error_handler,
|
|
36
38
|
)
|
|
@@ -38,8 +40,7 @@ from snowflake.cli.api.errno import (
|
|
|
38
40
|
APPLICATION_NO_LONGER_AVAILABLE,
|
|
39
41
|
APPLICATION_OWNS_EXTERNAL_OBJECTS,
|
|
40
42
|
)
|
|
41
|
-
from snowflake.cli.api.
|
|
42
|
-
from snowflake.cli.api.project.schemas.native_app.native_app import NativeApp
|
|
43
|
+
from snowflake.cli.api.project.schemas.v1.native_app.native_app import NativeApp
|
|
43
44
|
from snowflake.connector import ProgrammingError
|
|
44
45
|
from snowflake.connector.cursor import SnowflakeCursor
|
|
45
46
|
|
|
@@ -49,21 +50,12 @@ class NativeAppRunProcessor(NativeAppManager, NativeAppCommandProcessor):
|
|
|
49
50
|
super().__init__(project_definition, project_root)
|
|
50
51
|
|
|
51
52
|
def get_all_existing_versions(self) -> SnowflakeCursor:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"""
|
|
56
|
-
with self.use_role(self.package_role):
|
|
57
|
-
show_obj_query = f"show versions in application package {self.package_name}"
|
|
58
|
-
show_obj_cursor = self._execute_query(show_obj_query)
|
|
59
|
-
|
|
60
|
-
if show_obj_cursor.rowcount is None:
|
|
61
|
-
raise SnowflakeSQLExecutionError(show_obj_query)
|
|
62
|
-
|
|
63
|
-
return show_obj_cursor
|
|
53
|
+
return ApplicationPackageEntity.version_list(
|
|
54
|
+
self.package_name, self.package_role
|
|
55
|
+
)
|
|
64
56
|
|
|
65
57
|
def get_existing_version_info(self, version: str) -> Optional[dict]:
|
|
66
|
-
return
|
|
58
|
+
return ApplicationPackageEntity.get_existing_version_info(
|
|
67
59
|
version=version,
|
|
68
60
|
package_name=self.package_name,
|
|
69
61
|
package_role=self.package_role,
|
|
@@ -107,7 +99,8 @@ class NativeAppRunProcessor(NativeAppManager, NativeAppCommandProcessor):
|
|
|
107
99
|
cascade_msg = " (cascade)" if cascade else ""
|
|
108
100
|
cc.step(f"Dropping application object {self.app_name}{cascade_msg}.")
|
|
109
101
|
cascade_sql = " cascade" if cascade else ""
|
|
110
|
-
|
|
102
|
+
sql_executor = get_sql_executor()
|
|
103
|
+
sql_executor.execute_query(f"drop application {self.app_name}{cascade_sql}")
|
|
111
104
|
except ProgrammingError as err:
|
|
112
105
|
if err.errno == APPLICATION_OWNS_EXTERNAL_OBJECTS and not cascade:
|
|
113
106
|
# We need to cascade the deletion, let's try again (only if we didn't try with cascade already)
|
|
@@ -158,7 +151,11 @@ class NativeAppRunProcessor(NativeAppManager, NativeAppCommandProcessor):
|
|
|
158
151
|
):
|
|
159
152
|
def deploy_package():
|
|
160
153
|
self.deploy(
|
|
161
|
-
bundle_map=bundle_map,
|
|
154
|
+
bundle_map=bundle_map,
|
|
155
|
+
prune=True,
|
|
156
|
+
recursive=True,
|
|
157
|
+
validate=validate,
|
|
158
|
+
policy=policy,
|
|
162
159
|
)
|
|
163
160
|
|
|
164
161
|
def drop_app():
|
|
@@ -10,7 +10,6 @@ from snowflake.cli._plugins.nativeapp.exceptions import (
|
|
|
10
10
|
|
|
11
11
|
# from snowflake.cli._plugins.nativeapp.project_model import NativeAppProjectModel
|
|
12
12
|
from snowflake.cli._plugins.stage.manager import StageManager
|
|
13
|
-
from snowflake.cli.api.entities.utils import ensure_correct_owner
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
class SameAccountInstallMethod:
|
|
@@ -69,6 +68,3 @@ class SameAccountInstallMethod:
|
|
|
69
68
|
if show_app_row[COMMENT_COL] not in ALLOWED_SPECIAL_COMMENTS:
|
|
70
69
|
# this application object was not created by this tooling
|
|
71
70
|
raise ApplicationCreatedExternallyError(app_name)
|
|
72
|
-
|
|
73
|
-
# expected owner
|
|
74
|
-
ensure_correct_owner(row=show_app_row, role=app_role, obj_name=app_name)
|
|
@@ -17,17 +17,15 @@ from __future__ import annotations
|
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
from typing import Dict, Optional
|
|
19
19
|
|
|
20
|
+
from snowflake.cli._plugins.nativeapp.entities.application import ApplicationEntity
|
|
21
|
+
from snowflake.cli._plugins.nativeapp.entities.application_package import (
|
|
22
|
+
ApplicationPackageEntity,
|
|
23
|
+
)
|
|
20
24
|
from snowflake.cli._plugins.nativeapp.manager import (
|
|
21
25
|
NativeAppCommandProcessor,
|
|
22
26
|
NativeAppManager,
|
|
23
27
|
)
|
|
24
28
|
from snowflake.cli.api.console import cli_console as cc
|
|
25
|
-
from snowflake.cli.api.entities.application_entity import (
|
|
26
|
-
ApplicationEntity,
|
|
27
|
-
)
|
|
28
|
-
from snowflake.cli.api.entities.application_package_entity import (
|
|
29
|
-
ApplicationPackageEntity,
|
|
30
|
-
)
|
|
31
29
|
|
|
32
30
|
|
|
33
31
|
class NativeAppTeardownProcessor(NativeAppManager, NativeAppCommandProcessor):
|