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.
Files changed (88) hide show
  1. snowflake/cli/__about__.py +1 -1
  2. snowflake/cli/_app/commands_registration/builtin_plugins.py +2 -0
  3. snowflake/cli/_app/secret.py +9 -0
  4. snowflake/cli/_app/snow_connector.py +39 -27
  5. snowflake/cli/_app/telemetry.py +28 -0
  6. snowflake/cli/_plugins/connection/commands.py +9 -4
  7. snowflake/cli/_plugins/git/manager.py +53 -7
  8. snowflake/cli/_plugins/helpers/commands.py +61 -0
  9. snowflake/cli/{api/project/schemas/snowpark/__init__.py → _plugins/helpers/plugin_spec.py} +17 -0
  10. snowflake/cli/_plugins/nativeapp/artifacts.py +10 -9
  11. snowflake/cli/_plugins/nativeapp/bundle_context.py +1 -1
  12. snowflake/cli/_plugins/nativeapp/codegen/artifact_processor.py +1 -1
  13. snowflake/cli/_plugins/nativeapp/codegen/compiler.py +6 -1
  14. snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +1 -1
  15. snowflake/cli/_plugins/nativeapp/codegen/snowpark/extension_function_utils.py +1 -1
  16. snowflake/cli/_plugins/nativeapp/codegen/snowpark/models.py +1 -1
  17. snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +5 -1
  18. snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +4 -1
  19. snowflake/cli/_plugins/nativeapp/commands.py +87 -96
  20. snowflake/cli/_plugins/nativeapp/entities/__init__.py +0 -0
  21. snowflake/cli/{api/entities/application_entity.py → _plugins/nativeapp/entities/application.py} +264 -83
  22. snowflake/cli/_plugins/nativeapp/entities/application_package.py +1392 -0
  23. snowflake/cli/_plugins/nativeapp/exceptions.py +0 -9
  24. snowflake/cli/_plugins/nativeapp/manager.py +69 -185
  25. snowflake/cli/_plugins/nativeapp/policy.py +3 -0
  26. snowflake/cli/_plugins/nativeapp/project_model.py +2 -2
  27. snowflake/cli/_plugins/nativeapp/run_processor.py +17 -20
  28. snowflake/cli/_plugins/nativeapp/same_account_install_method.py +0 -4
  29. snowflake/cli/_plugins/nativeapp/teardown_processor.py +4 -6
  30. snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +122 -88
  31. snowflake/cli/_plugins/nativeapp/version/commands.py +7 -39
  32. snowflake/cli/_plugins/nativeapp/version/version_processor.py +46 -312
  33. snowflake/cli/_plugins/object/manager.py +36 -15
  34. snowflake/cli/_plugins/snowpark/commands.py +4 -4
  35. snowflake/cli/_plugins/snowpark/common.py +4 -4
  36. snowflake/cli/{api/entities → _plugins/snowpark}/snowpark_entity.py +2 -2
  37. snowflake/cli/{api/project/schemas/entities/snowpark_entity.py → _plugins/snowpark/snowpark_entity_model.py} +3 -6
  38. snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +1 -1
  39. snowflake/cli/_plugins/stage/manager.py +9 -4
  40. snowflake/cli/_plugins/streamlit/commands.py +15 -3
  41. snowflake/cli/_plugins/streamlit/manager.py +12 -4
  42. snowflake/cli/{api/entities → _plugins/streamlit}/streamlit_entity.py +2 -2
  43. snowflake/cli/{api/project/schemas/entities → _plugins/streamlit}/streamlit_entity_model.py +5 -12
  44. snowflake/cli/_plugins/workspace/commands.py +116 -36
  45. snowflake/cli/_plugins/workspace/plugin_spec.py +1 -1
  46. snowflake/cli/api/cli_global_context.py +7 -0
  47. snowflake/cli/api/commands/decorators.py +14 -0
  48. snowflake/cli/api/commands/flags.py +18 -0
  49. snowflake/cli/api/commands/snow_typer.py +1 -1
  50. snowflake/cli/api/config.py +25 -6
  51. snowflake/cli/api/connections.py +3 -1
  52. snowflake/cli/api/entities/common.py +4 -0
  53. snowflake/cli/api/entities/utils.py +3 -14
  54. snowflake/cli/api/errno.py +1 -0
  55. snowflake/cli/api/identifiers.py +4 -3
  56. snowflake/cli/api/metrics.py +92 -0
  57. snowflake/cli/api/project/definition_conversion.py +61 -18
  58. snowflake/cli/api/project/schemas/entities/common.py +17 -4
  59. snowflake/cli/api/project/schemas/entities/entities.py +11 -10
  60. snowflake/cli/api/project/schemas/project_definition.py +5 -7
  61. snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
  62. snowflake/cli/api/project/schemas/{identifier_model.py → v1/identifier_model.py} +0 -7
  63. snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
  64. snowflake/cli/api/project/schemas/{native_app → v1/native_app}/native_app.py +4 -4
  65. snowflake/cli/api/project/schemas/v1/snowpark/__init__.py +0 -0
  66. snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/callable.py +2 -2
  67. snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/snowpark.py +2 -2
  68. snowflake/cli/api/project/schemas/v1/streamlit/__init__.py +0 -0
  69. snowflake/cli/api/project/schemas/{streamlit → v1/streamlit}/streamlit.py +2 -1
  70. snowflake/cli/api/rendering/sql_templates.py +6 -0
  71. snowflake/cli/api/rest_api.py +11 -5
  72. snowflake/cli/api/sql_execution.py +6 -15
  73. snowflake/cli/api/utils/definition_rendering.py +24 -4
  74. {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/METADATA +9 -7
  75. {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/RECORD +83 -79
  76. snowflake/cli/_plugins/nativeapp/init.py +0 -345
  77. snowflake/cli/api/entities/application_package_entity.py +0 -658
  78. snowflake/cli/api/project/schemas/entities/application_entity_model.py +0 -56
  79. snowflake/cli/api/project/schemas/entities/application_package_entity_model.py +0 -94
  80. snowflake/cli/api/project/schemas/streamlit/__init__.py +0 -13
  81. /snowflake/cli/{api/project/schemas/native_app → _plugins/helpers}/__init__.py +0 -0
  82. /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/application.py +0 -0
  83. /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/package.py +0 -0
  84. /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/path_mapping.py +0 -0
  85. /snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/argument.py +0 -0
  86. {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/WHEEL +0 -0
  87. {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/entry_points.txt +0 -0
  88. {snowflake_cli_labs-3.0.0rc2.dist-info → snowflake_cli_labs-3.0.0rc4.dist-info}/licenses/LICENSE +0 -0
@@ -16,26 +16,25 @@ from __future__ import annotations
16
16
 
17
17
  import inspect
18
18
  from functools import wraps
19
- from typing import Any, Dict, Optional, Union
19
+ from typing import Any, Dict, Optional, Type, TypeVar, Union
20
20
 
21
21
  import typer
22
22
  from click import ClickException
23
+ from snowflake.cli._plugins.nativeapp.entities.application import ApplicationEntityModel
24
+ from snowflake.cli._plugins.nativeapp.entities.application_package import (
25
+ ApplicationPackageEntityModel,
26
+ )
23
27
  from snowflake.cli.api.cli_global_context import (
24
28
  get_cli_context,
25
29
  get_cli_context_manager,
26
30
  )
27
31
  from snowflake.cli.api.commands.decorators import _options_decorator_factory
28
- from snowflake.cli.api.project.schemas.entities.application_entity_model import (
29
- ApplicationEntityModel,
30
- )
31
- from snowflake.cli.api.project.schemas.entities.application_package_entity_model import (
32
- ApplicationPackageEntityModel,
33
- )
34
- from snowflake.cli.api.project.schemas.native_app.path_mapping import PathMapping
32
+ from snowflake.cli.api.project.schemas.entities.common import EntityModelBase
35
33
  from snowflake.cli.api.project.schemas.project_definition import (
36
34
  DefinitionV11,
37
35
  DefinitionV20,
38
36
  )
37
+ from snowflake.cli.api.project.schemas.v1.native_app.path_mapping import PathMapping
39
38
  from snowflake.cli.api.utils.definition_rendering import render_definition_template
40
39
 
41
40
 
@@ -55,33 +54,18 @@ def _pdf_v2_to_v1(
55
54
  v2_definition: DefinitionV20,
56
55
  package_entity_id: str = "",
57
56
  app_entity_id: str = "",
57
+ app_required: bool = False,
58
58
  ) -> DefinitionV11:
59
59
  pdfv1: Dict[str, Any] = {"definition_version": "1.1", "native_app": {}}
60
60
 
61
- app_package_definition: Optional[ApplicationPackageEntityModel] = None
62
- app_definition: Optional[ApplicationEntityModel] = None
63
-
64
- # Enumerate all application package and application entities in the project definition
65
- packages: dict[
66
- str, ApplicationPackageEntityModel
67
- ] = v2_definition.get_entities_by_type(ApplicationPackageEntityModel.get_type())
68
- apps: dict[str, ApplicationEntityModel] = v2_definition.get_entities_by_type(
69
- ApplicationEntityModel.get_type()
70
- )
71
-
72
61
  # Determine the application entity to convert, there can be zero or one
73
- if app_entity_id:
74
- # If the user specified an app entity ID, use that one directly
75
- app_definition = apps.get(app_entity_id)
76
- elif len(apps) == 1:
77
- # Otherwise, if there is only one app entity, fall back to that one
78
- app_definition = next(iter(apps.values()))
79
- elif len(apps) > 1:
80
- # If there are multiple app entities, the user must specify which one to use
81
- raise ClickException(
82
- "More than one application entity exists in the project definition file, "
83
- "specify --app-entity-id to choose which one to operate on."
84
- )
62
+ app_definition = find_entity(
63
+ v2_definition,
64
+ ApplicationEntityModel,
65
+ app_entity_id,
66
+ disambiguation_option="--app-entity-id",
67
+ required=app_required,
68
+ )
85
69
 
86
70
  # Infer or verify the package if we have an app entity to convert
87
71
  if app_definition:
@@ -89,7 +73,8 @@ def _pdf_v2_to_v1(
89
73
  if package_entity_id:
90
74
  # If the user specified a package entity ID,
91
75
  # check that the app entity targets the user-specified package entity
92
- if target_package != package_entity_id:
76
+ # if the app entity is used by the command being run
77
+ if target_package != package_entity_id and app_required:
93
78
  raise ClickException(
94
79
  f"The application entity {app_definition.entity_id} does not "
95
80
  f"target the application package entity {package_entity_id}. Either"
@@ -97,30 +82,21 @@ def _pdf_v2_to_v1(
97
82
  f"or omit the --package-entity-id flag to automatically use the package entity "
98
83
  f"that the application entity targets."
99
84
  )
100
- elif target_package in packages:
85
+ elif target_package in v2_definition.get_entities_by_type(
86
+ ApplicationPackageEntityModel.get_type()
87
+ ):
101
88
  # If the user didn't target a specific package entity, use the one the app entity targets
102
89
  package_entity_id = target_package
103
90
 
104
91
  # Determine the package entity to convert, there must be one
105
- if package_entity_id:
106
- # If the user specified a package entity ID (or we inferred one from the app entity), use that one directly
107
- app_package_definition = packages.get(package_entity_id)
108
- elif len(packages) == 1:
109
- # Otherwise, if there is only one package entity, fall back to that one
110
- app_package_definition = next(iter(packages.values()))
111
- elif len(packages) > 1:
112
- # If there are multiple package entities, the user must specify which one to use
113
- raise ClickException(
114
- "More than one application package entity exists in the project definition file, "
115
- "specify --package-entity-id to choose which one to operate on."
116
- )
117
-
118
- # If we don't have a package entity to convert, error out since it's not optional
119
- if not app_package_definition:
120
- with_id = f'with ID "{package_entity_id}" ' if package_entity_id else ""
121
- raise ClickException(
122
- f"Could not find an application package entity {with_id}in the project definition file."
123
- )
92
+ app_package_definition = find_entity(
93
+ v2_definition,
94
+ ApplicationPackageEntityModel,
95
+ package_entity_id,
96
+ disambiguation_option="--package-entity-id",
97
+ required=True,
98
+ )
99
+ assert app_package_definition is not None # satisfy mypy
124
100
 
125
101
  # NativeApp
126
102
  if app_definition and app_definition.fqn.identifier:
@@ -180,7 +156,60 @@ def _pdf_v2_to_v1(
180
156
  return result.project_definition
181
157
 
182
158
 
183
- def nativeapp_definition_v2_to_v1(func):
159
+ T = TypeVar("T", bound=EntityModelBase)
160
+
161
+
162
+ def find_entity(
163
+ project_definition: DefinitionV20,
164
+ entity_class: Type[T],
165
+ entity_id: str,
166
+ disambiguation_option: str,
167
+ required: bool,
168
+ ) -> T | None:
169
+ """
170
+ Find an entity of the specified type in the project definition file.
171
+
172
+ If an ID is passed, only that entity will be considered,
173
+ otherwise look for a single entity of the specified type.
174
+
175
+ If there are multiple entities of the specified type,
176
+ the user must specify which one to use using the CLI option
177
+ named in the disambiguation_option parameter.
178
+
179
+ If no entity is found, an error is raised if required is True,
180
+ otherwise None is returned.
181
+ """
182
+
183
+ entity_type = entity_class.get_type()
184
+ entities = project_definition.get_entities_by_type(entity_type)
185
+
186
+ entity: Optional[T] = None
187
+
188
+ if entity_id:
189
+ # If we're looking for a specific entity, use that one directly
190
+ entity = entities.get(entity_id)
191
+ elif len(entities) == 1:
192
+ # Otherwise, if there is only one entity, fall back to that one
193
+ entity = next(iter(entities.values()))
194
+ elif len(entities) > 1 and required:
195
+ # If there are multiple entities and it's required,
196
+ # the user must specify which one to use
197
+ raise ClickException(
198
+ f"More than one {entity_type} entity exists in the project definition file, "
199
+ f"specify {disambiguation_option} to choose which one to operate on."
200
+ )
201
+
202
+ # If we don't have a package entity to convert, error out if it's required
203
+ if not entity and required:
204
+ with_id = f'with ID "{entity_id}" ' if entity_id else ""
205
+ raise ClickException(
206
+ f"Could not find an {entity_type} entity {with_id}in the project definition file."
207
+ )
208
+
209
+ return entity
210
+
211
+
212
+ def nativeapp_definition_v2_to_v1(*, app_required: bool = False):
184
213
  """
185
214
  A command decorator that attempts to automatically convert a native app project from
186
215
  definition v2 to v1.1. Assumes with_project_definition() has already been called.
@@ -189,40 +218,45 @@ def nativeapp_definition_v2_to_v1(func):
189
218
  entity type is expected.
190
219
  """
191
220
 
192
- @wraps(func)
193
- def wrapper(*args, **kwargs):
194
- original_pdf: Optional[DefinitionV20] = get_cli_context().project_definition
195
- if not original_pdf:
196
- raise ValueError(
197
- "Project definition could not be found. The nativeapp_definition_v2_to_v1 command decorator assumes with_project_definition() was called before it."
198
- )
199
- if original_pdf.definition_version == "2":
200
- package_entity_id = kwargs.get("package_entity_id", "")
201
- app_entity_id = kwargs.get("app_entity_id", "")
202
- pdfv1 = _pdf_v2_to_v1(original_pdf, package_entity_id, app_entity_id)
203
- get_cli_context_manager().override_project_definition = pdfv1
204
- return func(*args, **kwargs)
205
-
206
- return _options_decorator_factory(
207
- wrapper,
208
- additional_options=[
209
- inspect.Parameter(
210
- "package_entity_id",
211
- inspect.Parameter.KEYWORD_ONLY,
212
- annotation=Optional[str],
213
- default=typer.Option(
214
- default="",
215
- help="The ID of the package entity on which to operate when definition_version is 2 or higher.",
221
+ def decorator(func):
222
+ @wraps(func)
223
+ def wrapper(*args, **kwargs):
224
+ original_pdf: Optional[DefinitionV20] = get_cli_context().project_definition
225
+ if not original_pdf:
226
+ raise ValueError(
227
+ "Project definition could not be found. The nativeapp_definition_v2_to_v1 command decorator assumes with_project_definition() was called before it."
228
+ )
229
+ if original_pdf.definition_version == "2":
230
+ package_entity_id = kwargs.get("package_entity_id", "")
231
+ app_entity_id = kwargs.get("app_entity_id", "")
232
+ pdfv1 = _pdf_v2_to_v1(
233
+ original_pdf, package_entity_id, app_entity_id, app_required
234
+ )
235
+ get_cli_context_manager().override_project_definition = pdfv1
236
+ return func(*args, **kwargs)
237
+
238
+ return _options_decorator_factory(
239
+ wrapper,
240
+ additional_options=[
241
+ inspect.Parameter(
242
+ "package_entity_id",
243
+ inspect.Parameter.KEYWORD_ONLY,
244
+ annotation=Optional[str],
245
+ default=typer.Option(
246
+ default="",
247
+ help="The ID of the package entity on which to operate when definition_version is 2 or higher.",
248
+ ),
216
249
  ),
217
- ),
218
- inspect.Parameter(
219
- "app_entity_id",
220
- inspect.Parameter.KEYWORD_ONLY,
221
- annotation=Optional[str],
222
- default=typer.Option(
223
- default="",
224
- help="The ID of the application entity on which to operate when definition_version is 2 or higher.",
250
+ inspect.Parameter(
251
+ "app_entity_id",
252
+ inspect.Parameter.KEYWORD_ONLY,
253
+ annotation=Optional[str],
254
+ default=typer.Option(
255
+ default="",
256
+ help="The ID of the application entity on which to operate when definition_version is 2 or higher.",
257
+ ),
225
258
  ),
226
- ),
227
- ],
228
- )
259
+ ],
260
+ )
261
+
262
+ return decorator
@@ -20,11 +20,6 @@ from typing import Optional
20
20
  import typer
21
21
  from click import MissingParameter
22
22
  from snowflake.cli._plugins.nativeapp.common_flags import ForceOption, InteractiveOption
23
- from snowflake.cli._plugins.nativeapp.policy import (
24
- AllowAlwaysPolicy,
25
- AskAlwaysPolicy,
26
- DenyAlwaysPolicy,
27
- )
28
23
  from snowflake.cli._plugins.nativeapp.run_processor import NativeAppRunProcessor
29
24
  from snowflake.cli._plugins.nativeapp.v2_conversions.v2_to_v1_decorator import (
30
25
  nativeapp_definition_v2_to_v1,
@@ -51,7 +46,7 @@ log = logging.getLogger(__name__)
51
46
 
52
47
  @app.command(requires_connection=True)
53
48
  @with_project_definition()
54
- @nativeapp_definition_v2_to_v1
49
+ @nativeapp_definition_v2_to_v1()
55
50
  def create(
56
51
  version: Optional[str] = typer.Argument(
57
52
  None,
@@ -82,42 +77,24 @@ def create(
82
77
  if version is None and patch is not None:
83
78
  raise MissingParameter("Cannot provide a patch without version!")
84
79
 
85
- is_interactive = False
86
- if force:
87
- policy = AllowAlwaysPolicy()
88
- elif interactive:
89
- is_interactive = True
90
- policy = AskAlwaysPolicy()
91
- else:
92
- policy = DenyAlwaysPolicy()
93
-
94
- if skip_git_check:
95
- git_policy = DenyAlwaysPolicy()
96
- else:
97
- git_policy = AllowAlwaysPolicy()
98
-
99
80
  cli_context = get_cli_context()
100
81
  processor = NativeAppVersionCreateProcessor(
101
82
  project_definition=cli_context.project_definition.native_app,
102
83
  project_root=cli_context.project_root,
103
84
  )
104
-
105
- # We need build_bundle() to (optionally) find version in manifest.yml and create an application package
106
- bundle_map = processor.build_bundle()
107
85
  processor.process(
108
- bundle_map=bundle_map,
109
86
  version=version,
110
87
  patch=patch,
111
- policy=policy,
112
- git_policy=git_policy,
113
- is_interactive=is_interactive,
88
+ force=force,
89
+ interactive=interactive,
90
+ skip_git_check=skip_git_check,
114
91
  )
115
92
  return MessageResult(f"Version create is now complete.")
116
93
 
117
94
 
118
95
  @app.command("list", requires_connection=True)
119
96
  @with_project_definition()
120
- @nativeapp_definition_v2_to_v1
97
+ @nativeapp_definition_v2_to_v1()
121
98
  def version_list(
122
99
  **options,
123
100
  ) -> CommandResult:
@@ -138,7 +115,7 @@ def version_list(
138
115
 
139
116
  @app.command(requires_connection=True)
140
117
  @with_project_definition()
141
- @nativeapp_definition_v2_to_v1
118
+ @nativeapp_definition_v2_to_v1()
142
119
  def drop(
143
120
  version: Optional[str] = typer.Argument(
144
121
  None,
@@ -155,19 +132,10 @@ def drop(
155
132
 
156
133
  assert_project_type("native_app")
157
134
 
158
- is_interactive = False
159
- if force:
160
- policy = AllowAlwaysPolicy()
161
- elif interactive:
162
- is_interactive = True
163
- policy = AskAlwaysPolicy()
164
- else:
165
- policy = DenyAlwaysPolicy()
166
-
167
135
  cli_context = get_cli_context()
168
136
  processor = NativeAppVersionDropProcessor(
169
137
  project_definition=cli_context.project_definition.native_app,
170
138
  project_root=cli_context.project_root,
171
139
  )
172
- processor.process(version, policy, is_interactive)
140
+ processor.process(version, force, interactive)
173
141
  return MessageResult(f"Version drop is now complete.")