snowflake-cli 3.0.2__py3-none-any.whl → 3.2.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.
- snowflake/cli/__about__.py +1 -1
- snowflake/cli/_app/cli_app.py +3 -0
- snowflake/cli/_app/dev/docs/templates/overview.rst.jinja2 +1 -1
- snowflake/cli/_app/dev/docs/templates/usage.rst.jinja2 +2 -2
- snowflake/cli/_app/telemetry.py +69 -4
- snowflake/cli/_plugins/connection/commands.py +152 -99
- snowflake/cli/_plugins/connection/util.py +54 -9
- snowflake/cli/_plugins/cortex/manager.py +1 -1
- snowflake/cli/_plugins/git/commands.py +6 -3
- snowflake/cli/_plugins/git/manager.py +9 -4
- snowflake/cli/_plugins/nativeapp/artifacts.py +77 -13
- snowflake/cli/_plugins/nativeapp/codegen/artifact_processor.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/compiler.py +7 -0
- snowflake/cli/_plugins/nativeapp/codegen/sandbox.py +10 -10
- snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +2 -2
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/extension_function_utils.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +8 -8
- snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +5 -3
- snowflake/cli/_plugins/nativeapp/commands.py +144 -188
- snowflake/cli/_plugins/nativeapp/constants.py +1 -0
- snowflake/cli/_plugins/nativeapp/entities/application.py +564 -351
- snowflake/cli/_plugins/nativeapp/entities/application_package.py +583 -929
- snowflake/cli/_plugins/nativeapp/entities/models/event_sharing_telemetry.py +58 -0
- snowflake/cli/_plugins/nativeapp/exceptions.py +12 -0
- snowflake/cli/_plugins/nativeapp/same_account_install_method.py +0 -2
- snowflake/cli/_plugins/nativeapp/sf_facade.py +30 -0
- snowflake/cli/_plugins/nativeapp/sf_facade_constants.py +25 -0
- snowflake/cli/_plugins/nativeapp/sf_facade_exceptions.py +117 -0
- snowflake/cli/_plugins/nativeapp/sf_sql_facade.py +525 -0
- snowflake/cli/_plugins/nativeapp/v2_conversions/{v2_to_v1_decorator.py → compat.py} +88 -117
- snowflake/cli/_plugins/nativeapp/version/commands.py +36 -32
- snowflake/cli/_plugins/notebook/manager.py +2 -2
- snowflake/cli/_plugins/object/commands.py +10 -1
- snowflake/cli/_plugins/object/manager.py +13 -5
- snowflake/cli/_plugins/snowpark/common.py +63 -21
- snowflake/cli/_plugins/snowpark/package/anaconda_packages.py +3 -3
- snowflake/cli/_plugins/spcs/common.py +29 -0
- snowflake/cli/_plugins/spcs/compute_pool/manager.py +7 -9
- snowflake/cli/_plugins/spcs/image_registry/manager.py +2 -2
- snowflake/cli/_plugins/spcs/image_repository/commands.py +4 -37
- snowflake/cli/_plugins/spcs/image_repository/manager.py +4 -1
- snowflake/cli/_plugins/spcs/services/commands.py +100 -17
- snowflake/cli/_plugins/spcs/services/manager.py +108 -16
- snowflake/cli/_plugins/sql/commands.py +9 -1
- snowflake/cli/_plugins/sql/manager.py +9 -4
- snowflake/cli/_plugins/stage/commands.py +28 -19
- snowflake/cli/_plugins/stage/diff.py +17 -17
- snowflake/cli/_plugins/stage/manager.py +304 -84
- snowflake/cli/_plugins/stage/md5.py +1 -1
- snowflake/cli/_plugins/streamlit/manager.py +5 -5
- snowflake/cli/_plugins/workspace/commands.py +27 -4
- snowflake/cli/_plugins/workspace/context.py +38 -0
- snowflake/cli/_plugins/workspace/manager.py +23 -13
- snowflake/cli/api/cli_global_context.py +4 -3
- snowflake/cli/api/commands/flags.py +23 -7
- snowflake/cli/api/config.py +30 -9
- snowflake/cli/api/connections.py +12 -1
- snowflake/cli/api/console/console.py +4 -19
- snowflake/cli/api/entities/common.py +4 -2
- snowflake/cli/api/entities/utils.py +36 -69
- snowflake/cli/api/errno.py +2 -0
- snowflake/cli/api/exceptions.py +41 -0
- snowflake/cli/api/identifiers.py +8 -0
- snowflake/cli/api/metrics.py +223 -7
- snowflake/cli/api/output/types.py +1 -1
- snowflake/cli/api/project/definition_conversion.py +293 -77
- snowflake/cli/api/project/schemas/entities/common.py +11 -0
- snowflake/cli/api/project/schemas/project_definition.py +30 -25
- snowflake/cli/api/rest_api.py +26 -4
- snowflake/cli/api/secure_utils.py +1 -1
- snowflake/cli/api/sql_execution.py +40 -29
- snowflake/cli/api/stage_path.py +244 -0
- snowflake/cli/api/utils/definition_rendering.py +3 -5
- {snowflake_cli-3.0.2.dist-info → snowflake_cli-3.2.0.dist-info}/METADATA +14 -15
- {snowflake_cli-3.0.2.dist-info → snowflake_cli-3.2.0.dist-info}/RECORD +78 -77
- {snowflake_cli-3.0.2.dist-info → snowflake_cli-3.2.0.dist-info}/WHEEL +1 -1
- snowflake/cli/_plugins/nativeapp/manager.py +0 -415
- snowflake/cli/_plugins/nativeapp/project_model.py +0 -211
- snowflake/cli/_plugins/nativeapp/run_processor.py +0 -184
- snowflake/cli/_plugins/nativeapp/teardown_processor.py +0 -70
- snowflake/cli/_plugins/nativeapp/version/version_processor.py +0 -98
- snowflake/cli/_plugins/workspace/action_context.py +0 -18
- {snowflake_cli-3.0.2.dist-info → snowflake_cli-3.2.0.dist-info}/entry_points.txt +0 -0
- {snowflake_cli-3.0.2.dist-info → snowflake_cli-3.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -22,7 +22,6 @@ from textwrap import dedent
|
|
|
22
22
|
from typing import Generator, Iterable, List, Optional, cast
|
|
23
23
|
|
|
24
24
|
import typer
|
|
25
|
-
from click.exceptions import ClickException
|
|
26
25
|
from snowflake.cli._plugins.nativeapp.common_flags import (
|
|
27
26
|
ForceOption,
|
|
28
27
|
InteractiveOption,
|
|
@@ -32,19 +31,9 @@ from snowflake.cli._plugins.nativeapp.entities.application import ApplicationEnt
|
|
|
32
31
|
from snowflake.cli._plugins.nativeapp.entities.application_package import (
|
|
33
32
|
ApplicationPackageEntityModel,
|
|
34
33
|
)
|
|
35
|
-
from snowflake.cli._plugins.nativeapp.
|
|
36
|
-
from snowflake.cli._plugins.nativeapp.policy import (
|
|
37
|
-
AllowAlwaysPolicy,
|
|
38
|
-
AskAlwaysPolicy,
|
|
39
|
-
DenyAlwaysPolicy,
|
|
40
|
-
)
|
|
41
|
-
from snowflake.cli._plugins.nativeapp.run_processor import NativeAppRunProcessor
|
|
42
|
-
from snowflake.cli._plugins.nativeapp.teardown_processor import (
|
|
43
|
-
NativeAppTeardownProcessor,
|
|
44
|
-
)
|
|
45
|
-
from snowflake.cli._plugins.nativeapp.v2_conversions.v2_to_v1_decorator import (
|
|
34
|
+
from snowflake.cli._plugins.nativeapp.v2_conversions.compat import (
|
|
46
35
|
find_entity,
|
|
47
|
-
|
|
36
|
+
force_project_definition_v2,
|
|
48
37
|
)
|
|
49
38
|
from snowflake.cli._plugins.nativeapp.version.commands import app as versions_app
|
|
50
39
|
from snowflake.cli._plugins.stage.diff import (
|
|
@@ -59,7 +48,10 @@ from snowflake.cli.api.commands.decorators import (
|
|
|
59
48
|
)
|
|
60
49
|
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
61
50
|
from snowflake.cli.api.entities.common import EntityActions
|
|
62
|
-
from snowflake.cli.api.exceptions import
|
|
51
|
+
from snowflake.cli.api.exceptions import (
|
|
52
|
+
IncompatibleParametersError,
|
|
53
|
+
UnmetParametersError,
|
|
54
|
+
)
|
|
63
55
|
from snowflake.cli.api.output.formats import OutputFormat
|
|
64
56
|
from snowflake.cli.api.output.types import (
|
|
65
57
|
CommandResult,
|
|
@@ -67,8 +59,6 @@ from snowflake.cli.api.output.types import (
|
|
|
67
59
|
ObjectResult,
|
|
68
60
|
StreamResult,
|
|
69
61
|
)
|
|
70
|
-
from snowflake.cli.api.project.project_verification import assert_project_type
|
|
71
|
-
from snowflake.cli.api.project.schemas.project_definition import ProjectDefinitionV1
|
|
72
62
|
from typing_extensions import Annotated
|
|
73
63
|
|
|
74
64
|
app = SnowTyperFactory(
|
|
@@ -80,57 +70,52 @@ app.add_typer(versions_app)
|
|
|
80
70
|
log = logging.getLogger(__name__)
|
|
81
71
|
|
|
82
72
|
|
|
83
|
-
@app.command("init", hidden=True)
|
|
84
|
-
def app_init(**options):
|
|
85
|
-
"""
|
|
86
|
-
*** Deprecated. Use snow init instead ***
|
|
87
|
-
|
|
88
|
-
Initializes a Snowflake Native App project.
|
|
89
|
-
"""
|
|
90
|
-
|
|
91
|
-
raise ClickException("This command has been removed. Use `snow init` instead.")
|
|
92
|
-
|
|
93
|
-
|
|
94
73
|
@app.command("bundle")
|
|
95
74
|
@with_project_definition()
|
|
96
|
-
@
|
|
75
|
+
@force_project_definition_v2()
|
|
97
76
|
def app_bundle(
|
|
98
77
|
**options,
|
|
99
78
|
) -> CommandResult:
|
|
100
79
|
"""
|
|
101
80
|
Prepares a local folder with configured app artifacts.
|
|
102
81
|
"""
|
|
103
|
-
|
|
104
|
-
assert_project_type("native_app")
|
|
105
|
-
|
|
106
82
|
cli_context = get_cli_context()
|
|
107
|
-
|
|
108
|
-
project_definition=cli_context.project_definition
|
|
83
|
+
ws = WorkspaceManager(
|
|
84
|
+
project_definition=cli_context.project_definition,
|
|
109
85
|
project_root=cli_context.project_root,
|
|
110
86
|
)
|
|
111
|
-
|
|
112
|
-
|
|
87
|
+
package_id = options["package_entity_id"]
|
|
88
|
+
package = cli_context.project_definition.entities[package_id]
|
|
89
|
+
ws.perform_action(
|
|
90
|
+
package_id,
|
|
91
|
+
EntityActions.BUNDLE,
|
|
92
|
+
)
|
|
93
|
+
return MessageResult(f"Bundle generated at {ws.project_root / package.deploy_root}")
|
|
113
94
|
|
|
114
95
|
|
|
115
96
|
@app.command("diff", requires_connection=True, hidden=True)
|
|
116
97
|
@with_project_definition()
|
|
117
|
-
@
|
|
98
|
+
@force_project_definition_v2()
|
|
118
99
|
def app_diff(
|
|
119
100
|
**options,
|
|
120
|
-
) -> CommandResult:
|
|
101
|
+
) -> CommandResult | None:
|
|
121
102
|
"""
|
|
122
103
|
Performs a diff between the app's source stage and the local deploy root.
|
|
123
104
|
"""
|
|
124
|
-
assert_project_type("native_app")
|
|
125
|
-
|
|
126
105
|
cli_context = get_cli_context()
|
|
127
|
-
|
|
128
|
-
project_definition=cli_context.project_definition
|
|
106
|
+
ws = WorkspaceManager(
|
|
107
|
+
project_definition=cli_context.project_definition,
|
|
129
108
|
project_root=cli_context.project_root,
|
|
130
109
|
)
|
|
131
|
-
|
|
110
|
+
package_id = options["package_entity_id"]
|
|
111
|
+
package = cli_context.project_definition.entities[package_id]
|
|
112
|
+
bundle_map = ws.perform_action(
|
|
113
|
+
package_id,
|
|
114
|
+
EntityActions.BUNDLE,
|
|
115
|
+
)
|
|
116
|
+
stage_fqn = f"{package.fqn.name}.{package.stage}"
|
|
132
117
|
diff: DiffResult = compute_stage_diff(
|
|
133
|
-
local_root=Path(
|
|
118
|
+
local_root=Path(package.deploy_root), stage_fqn=stage_fqn
|
|
134
119
|
)
|
|
135
120
|
if cli_context.output_format == OutputFormat.JSON:
|
|
136
121
|
return ObjectResult(diff.to_dict())
|
|
@@ -141,7 +126,7 @@ def app_diff(
|
|
|
141
126
|
|
|
142
127
|
@app.command("run", requires_connection=True)
|
|
143
128
|
@with_project_definition()
|
|
144
|
-
@
|
|
129
|
+
@force_project_definition_v2(app_required=True)
|
|
145
130
|
def app_run(
|
|
146
131
|
version: Optional[str] = typer.Option(
|
|
147
132
|
None,
|
|
@@ -170,42 +155,35 @@ def app_run(
|
|
|
170
155
|
Creates an application package in your Snowflake account, uploads code files to its stage,
|
|
171
156
|
then creates or upgrades an application object from the application package.
|
|
172
157
|
"""
|
|
173
|
-
|
|
174
|
-
assert_project_type("native_app")
|
|
175
|
-
|
|
176
|
-
is_interactive = False
|
|
177
|
-
if force:
|
|
178
|
-
policy = AllowAlwaysPolicy()
|
|
179
|
-
elif interactive:
|
|
180
|
-
is_interactive = True
|
|
181
|
-
policy = AskAlwaysPolicy()
|
|
182
|
-
else:
|
|
183
|
-
policy = DenyAlwaysPolicy()
|
|
184
|
-
|
|
185
158
|
cli_context = get_cli_context()
|
|
186
|
-
|
|
187
|
-
project_definition=cli_context.project_definition
|
|
159
|
+
ws = WorkspaceManager(
|
|
160
|
+
project_definition=cli_context.project_definition,
|
|
188
161
|
project_root=cli_context.project_root,
|
|
189
162
|
)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
163
|
+
app_id = options["app_entity_id"]
|
|
164
|
+
app_model = cli_context.project_definition.entities[app_id]
|
|
165
|
+
ws.perform_action(
|
|
166
|
+
app_id,
|
|
167
|
+
EntityActions.DEPLOY,
|
|
168
|
+
validate=validate,
|
|
194
169
|
version=version,
|
|
195
170
|
patch=patch,
|
|
196
171
|
from_release_directive=from_release_directive,
|
|
197
|
-
|
|
198
|
-
|
|
172
|
+
prune=True,
|
|
173
|
+
recursive=True,
|
|
174
|
+
paths=[],
|
|
175
|
+
interactive=interactive,
|
|
176
|
+
force=force,
|
|
199
177
|
)
|
|
178
|
+
app = ws.get_entity(app_id)
|
|
200
179
|
return MessageResult(
|
|
201
|
-
f"Your application object ({
|
|
202
|
-
+ processor.get_snowsight_url()
|
|
180
|
+
f"Your application object ({app_model.fqn.name}) is now available:\n{app.get_snowsight_url()}"
|
|
203
181
|
)
|
|
204
182
|
|
|
205
183
|
|
|
206
184
|
@app.command("open", requires_connection=True)
|
|
207
185
|
@with_project_definition()
|
|
208
|
-
@
|
|
186
|
+
@force_project_definition_v2(app_required=True)
|
|
209
187
|
def app_open(
|
|
210
188
|
**options,
|
|
211
189
|
) -> CommandResult:
|
|
@@ -213,16 +191,15 @@ def app_open(
|
|
|
213
191
|
Opens the Snowflake Native App inside of your browser,
|
|
214
192
|
once it has been installed in your account.
|
|
215
193
|
"""
|
|
216
|
-
|
|
217
|
-
assert_project_type("native_app")
|
|
218
|
-
|
|
219
194
|
cli_context = get_cli_context()
|
|
220
|
-
|
|
221
|
-
project_definition=cli_context.project_definition
|
|
195
|
+
ws = WorkspaceManager(
|
|
196
|
+
project_definition=cli_context.project_definition,
|
|
222
197
|
project_root=cli_context.project_root,
|
|
223
198
|
)
|
|
224
|
-
|
|
225
|
-
|
|
199
|
+
app_id = options["app_entity_id"]
|
|
200
|
+
app = ws.get_entity(app_id)
|
|
201
|
+
if app.get_existing_app_info():
|
|
202
|
+
typer.launch(app.get_snowsight_url())
|
|
226
203
|
return MessageResult(f"Snowflake Native App opened in browser.")
|
|
227
204
|
else:
|
|
228
205
|
return MessageResult(
|
|
@@ -232,9 +209,7 @@ def app_open(
|
|
|
232
209
|
|
|
233
210
|
@app.command("teardown", requires_connection=True)
|
|
234
211
|
@with_project_definition()
|
|
235
|
-
|
|
236
|
-
# be aware of PDFv2 definitions that have multiple apps created from the same package,
|
|
237
|
-
# which all need to be torn down.
|
|
212
|
+
@force_project_definition_v2(single_app_and_package=False)
|
|
238
213
|
def app_teardown(
|
|
239
214
|
force: Optional[bool] = ForceOption,
|
|
240
215
|
cascade: Optional[bool] = typer.Option(
|
|
@@ -243,7 +218,7 @@ def app_teardown(
|
|
|
243
218
|
show_default=False,
|
|
244
219
|
),
|
|
245
220
|
interactive: bool = InteractiveOption,
|
|
246
|
-
# Same as the param auto-added by @
|
|
221
|
+
# Same as the param auto-added by @force_project_definition_v2 if single_app_and_package were true
|
|
247
222
|
package_entity_id: Optional[str] = typer.Option(
|
|
248
223
|
default="",
|
|
249
224
|
help="The ID of the package entity on which to operate when definition_version is 2 or higher.",
|
|
@@ -255,58 +230,49 @@ def app_teardown(
|
|
|
255
230
|
"""
|
|
256
231
|
cli_context = get_cli_context()
|
|
257
232
|
project = cli_context.project_definition
|
|
258
|
-
if isinstance(project, ProjectDefinitionV1):
|
|
259
|
-
# Old behaviour, not multi-app aware so we can use the old processor
|
|
260
|
-
processor = NativeAppTeardownProcessor(
|
|
261
|
-
project_definition=cli_context.project_definition.native_app,
|
|
262
|
-
project_root=cli_context.project_root,
|
|
263
|
-
)
|
|
264
|
-
processor.process(interactive, force, cascade)
|
|
265
|
-
else:
|
|
266
|
-
# New behaviour, multi-app aware so teardown all the apps created from the package
|
|
267
|
-
|
|
268
|
-
# Determine the package entity to drop, there must be one
|
|
269
|
-
app_package_entity = find_entity(
|
|
270
|
-
project,
|
|
271
|
-
ApplicationPackageEntityModel,
|
|
272
|
-
package_entity_id,
|
|
273
|
-
disambiguation_option="--package-entity-id",
|
|
274
|
-
required=True,
|
|
275
|
-
)
|
|
276
|
-
assert app_package_entity is not None # satisfy mypy
|
|
277
233
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
234
|
+
# Determine the package entity to drop, there must be one
|
|
235
|
+
app_package_entity = find_entity(
|
|
236
|
+
project,
|
|
237
|
+
ApplicationPackageEntityModel,
|
|
238
|
+
package_entity_id,
|
|
239
|
+
disambiguation_option="--package-entity-id",
|
|
240
|
+
required=True,
|
|
241
|
+
)
|
|
242
|
+
assert app_package_entity is not None # satisfy mypy
|
|
243
|
+
|
|
244
|
+
# Same implementation as `snow ws drop`
|
|
245
|
+
ws = WorkspaceManager(
|
|
246
|
+
project_definition=cli_context.project_definition,
|
|
247
|
+
project_root=cli_context.project_root,
|
|
248
|
+
)
|
|
249
|
+
for app_entity in project.get_entities_by_type(
|
|
250
|
+
ApplicationEntityModel.get_type()
|
|
251
|
+
).values():
|
|
252
|
+
# Drop each app
|
|
253
|
+
if app_entity.from_.target == app_package_entity.entity_id:
|
|
254
|
+
ws.perform_action(
|
|
255
|
+
app_entity.entity_id,
|
|
256
|
+
EntityActions.DROP,
|
|
257
|
+
force_drop=force,
|
|
258
|
+
interactive=interactive,
|
|
259
|
+
cascade=cascade,
|
|
260
|
+
)
|
|
261
|
+
# Then drop the package
|
|
262
|
+
ws.perform_action(
|
|
263
|
+
app_package_entity.entity_id,
|
|
264
|
+
EntityActions.DROP,
|
|
265
|
+
force_drop=force,
|
|
266
|
+
interactive=interactive,
|
|
267
|
+
cascade=cascade,
|
|
268
|
+
)
|
|
303
269
|
|
|
304
270
|
return MessageResult(f"Teardown is now complete.")
|
|
305
271
|
|
|
306
272
|
|
|
307
273
|
@app.command("deploy", requires_connection=True)
|
|
308
274
|
@with_project_definition()
|
|
309
|
-
@
|
|
275
|
+
@force_project_definition_v2()
|
|
310
276
|
def app_deploy(
|
|
311
277
|
prune: Optional[bool] = typer.Option(
|
|
312
278
|
default=None,
|
|
@@ -338,16 +304,6 @@ def app_deploy(
|
|
|
338
304
|
Creates an application package in your Snowflake account and syncs the local changes to the stage without creating or updating the application.
|
|
339
305
|
Running this command with no arguments at all, as in `snow app deploy`, is a shorthand for `snow app deploy --prune --recursive`.
|
|
340
306
|
"""
|
|
341
|
-
|
|
342
|
-
assert_project_type("native_app")
|
|
343
|
-
|
|
344
|
-
if force:
|
|
345
|
-
policy = AllowAlwaysPolicy()
|
|
346
|
-
elif interactive:
|
|
347
|
-
policy = AskAlwaysPolicy()
|
|
348
|
-
else:
|
|
349
|
-
policy = DenyAlwaysPolicy()
|
|
350
|
-
|
|
351
307
|
has_paths = paths is not None and len(paths) > 0
|
|
352
308
|
if prune is None and recursive is None and not has_paths:
|
|
353
309
|
prune = True
|
|
@@ -357,24 +313,24 @@ def app_deploy(
|
|
|
357
313
|
prune = False
|
|
358
314
|
if recursive is None:
|
|
359
315
|
recursive = False
|
|
360
|
-
|
|
361
316
|
if has_paths and prune:
|
|
362
317
|
raise IncompatibleParametersError(["paths", "--prune"])
|
|
363
318
|
|
|
364
319
|
cli_context = get_cli_context()
|
|
365
|
-
|
|
366
|
-
project_definition=cli_context.project_definition
|
|
320
|
+
ws = WorkspaceManager(
|
|
321
|
+
project_definition=cli_context.project_definition,
|
|
367
322
|
project_root=cli_context.project_root,
|
|
368
323
|
)
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
324
|
+
package_id = options["package_entity_id"]
|
|
325
|
+
ws.perform_action(
|
|
326
|
+
package_id,
|
|
327
|
+
EntityActions.DEPLOY,
|
|
373
328
|
prune=prune,
|
|
374
329
|
recursive=recursive,
|
|
375
|
-
|
|
330
|
+
paths=paths,
|
|
376
331
|
validate=validate,
|
|
377
|
-
|
|
332
|
+
interactive=interactive,
|
|
333
|
+
force=force,
|
|
378
334
|
)
|
|
379
335
|
|
|
380
336
|
return MessageResult(
|
|
@@ -384,25 +340,33 @@ def app_deploy(
|
|
|
384
340
|
|
|
385
341
|
@app.command("validate", requires_connection=True)
|
|
386
342
|
@with_project_definition()
|
|
387
|
-
@
|
|
343
|
+
@force_project_definition_v2()
|
|
388
344
|
def app_validate(
|
|
389
345
|
**options,
|
|
390
346
|
):
|
|
391
347
|
"""
|
|
392
348
|
Validates a deployed Snowflake Native App's setup script.
|
|
393
349
|
"""
|
|
394
|
-
|
|
395
|
-
assert_project_type("native_app")
|
|
396
|
-
|
|
397
350
|
cli_context = get_cli_context()
|
|
398
|
-
|
|
399
|
-
project_definition=cli_context.project_definition
|
|
351
|
+
ws = WorkspaceManager(
|
|
352
|
+
project_definition=cli_context.project_definition,
|
|
400
353
|
project_root=cli_context.project_root,
|
|
401
354
|
)
|
|
355
|
+
package_id = options["package_entity_id"]
|
|
356
|
+
package = ws.get_entity(package_id)
|
|
402
357
|
if cli_context.output_format == OutputFormat.JSON:
|
|
403
|
-
return ObjectResult(
|
|
358
|
+
return ObjectResult(
|
|
359
|
+
package.get_validation_result(
|
|
360
|
+
use_scratch_stage=True, interactive=False, force=True
|
|
361
|
+
)
|
|
362
|
+
)
|
|
404
363
|
|
|
405
|
-
|
|
364
|
+
ws.perform_action(
|
|
365
|
+
package_id,
|
|
366
|
+
EntityActions.VALIDATE,
|
|
367
|
+
interactive=False,
|
|
368
|
+
force=True,
|
|
369
|
+
)
|
|
406
370
|
return MessageResult("Snowflake Native App validation succeeded.")
|
|
407
371
|
|
|
408
372
|
|
|
@@ -419,7 +383,7 @@ DEFAULT_EVENT_FOLLOW_LAST = 20
|
|
|
419
383
|
|
|
420
384
|
@app.command("events", requires_connection=True)
|
|
421
385
|
@with_project_definition()
|
|
422
|
-
@
|
|
386
|
+
@force_project_definition_v2(app_required=True)
|
|
423
387
|
def app_events(
|
|
424
388
|
since: str = typer.Option(
|
|
425
389
|
default="",
|
|
@@ -491,7 +455,7 @@ def app_events(
|
|
|
491
455
|
if (consumer_org and not consumer_account) or (
|
|
492
456
|
consumer_account and not consumer_org
|
|
493
457
|
):
|
|
494
|
-
raise
|
|
458
|
+
raise UnmetParametersError(["--consumer-org", "--consumer-account"])
|
|
495
459
|
|
|
496
460
|
if follow:
|
|
497
461
|
if until:
|
|
@@ -499,48 +463,40 @@ def app_events(
|
|
|
499
463
|
if first >= 0:
|
|
500
464
|
raise IncompatibleParametersError(["--follow", "--first"])
|
|
501
465
|
|
|
502
|
-
|
|
466
|
+
cli_context = get_cli_context()
|
|
467
|
+
ws = WorkspaceManager(
|
|
468
|
+
project_definition=cli_context.project_definition,
|
|
469
|
+
project_root=cli_context.project_root,
|
|
470
|
+
)
|
|
471
|
+
app_id = options["app_entity_id"]
|
|
503
472
|
|
|
504
473
|
record_type_names = [r.name for r in record_types]
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
474
|
+
|
|
475
|
+
if follow and last == -1 and not since:
|
|
476
|
+
# If we don't have a value for --last or --since, assume a value
|
|
477
|
+
# for --last so we at least print something before starting the stream
|
|
478
|
+
last = DEFAULT_EVENT_FOLLOW_LAST
|
|
479
|
+
stream: Iterable[CommandResult] = (
|
|
480
|
+
EventResult(event)
|
|
481
|
+
for event in ws.perform_action(
|
|
482
|
+
app_id,
|
|
483
|
+
EntityActions.EVENTS,
|
|
484
|
+
since=since,
|
|
485
|
+
until=until,
|
|
486
|
+
record_types=record_type_names,
|
|
487
|
+
scopes=scopes,
|
|
488
|
+
consumer_org=consumer_org,
|
|
489
|
+
consumer_account=consumer_account,
|
|
490
|
+
consumer_app_hash=consumer_app_hash,
|
|
491
|
+
first=first,
|
|
492
|
+
last=last,
|
|
493
|
+
follow=follow,
|
|
494
|
+
interval_seconds=follow_interval,
|
|
495
|
+
)
|
|
508
496
|
)
|
|
509
497
|
if follow:
|
|
510
|
-
if last == -1 and not since:
|
|
511
|
-
# If we don't have a value for --last or --since, assume a value
|
|
512
|
-
# for --last so we at least print something before starting the stream
|
|
513
|
-
last = DEFAULT_EVENT_FOLLOW_LAST
|
|
514
|
-
stream: Iterable[CommandResult] = (
|
|
515
|
-
EventResult(event)
|
|
516
|
-
for event in manager.stream_events(
|
|
517
|
-
since=since,
|
|
518
|
-
last=last,
|
|
519
|
-
interval_seconds=follow_interval,
|
|
520
|
-
record_types=record_type_names,
|
|
521
|
-
scopes=scopes,
|
|
522
|
-
consumer_org=consumer_org,
|
|
523
|
-
consumer_account=consumer_account,
|
|
524
|
-
consumer_app_hash=consumer_app_hash,
|
|
525
|
-
)
|
|
526
|
-
)
|
|
527
498
|
# Append a newline at the end to make the CLI output clean when we hit Ctrl-C
|
|
528
499
|
stream = itertools.chain(stream, [MessageResult("")])
|
|
529
|
-
else:
|
|
530
|
-
stream = (
|
|
531
|
-
EventResult(event)
|
|
532
|
-
for event in manager.get_events(
|
|
533
|
-
since=since,
|
|
534
|
-
until=until,
|
|
535
|
-
record_types=record_type_names,
|
|
536
|
-
scopes=scopes,
|
|
537
|
-
first=first,
|
|
538
|
-
last=last,
|
|
539
|
-
consumer_org=consumer_org,
|
|
540
|
-
consumer_account=consumer_account,
|
|
541
|
-
consumer_app_hash=consumer_app_hash,
|
|
542
|
-
)
|
|
543
|
-
)
|
|
544
500
|
|
|
545
501
|
# Cast the stream to a Generator since that's what StreamResult wants
|
|
546
502
|
return StreamResult(cast(Generator[CommandResult, None, None], stream))
|