snowflake-cli-labs 2.8.0rc1__py3-none-any.whl → 2.8.2__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 (242) hide show
  1. README.md +21 -0
  2. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-2.8.2.dist-info}/METADATA +7 -95
  3. snowflake_cli_labs-2.8.2.dist-info/RECORD +5 -0
  4. snowflake/cli/__about__.py +0 -17
  5. snowflake/cli/__init__.py +0 -13
  6. snowflake/cli/api/__init__.py +0 -48
  7. snowflake/cli/api/cli_global_context.py +0 -390
  8. snowflake/cli/api/commands/__init__.py +0 -13
  9. snowflake/cli/api/commands/alias.py +0 -23
  10. snowflake/cli/api/commands/decorators.py +0 -354
  11. snowflake/cli/api/commands/execution_metadata.py +0 -40
  12. snowflake/cli/api/commands/experimental_behaviour.py +0 -19
  13. snowflake/cli/api/commands/flags.py +0 -640
  14. snowflake/cli/api/commands/project_initialisation.py +0 -65
  15. snowflake/cli/api/commands/snow_typer.py +0 -237
  16. snowflake/cli/api/commands/typer_pre_execute.py +0 -26
  17. snowflake/cli/api/config.py +0 -348
  18. snowflake/cli/api/console/__init__.py +0 -17
  19. snowflake/cli/api/console/abc.py +0 -89
  20. snowflake/cli/api/console/console.py +0 -134
  21. snowflake/cli/api/console/enum.py +0 -17
  22. snowflake/cli/api/constants.py +0 -79
  23. snowflake/cli/api/errno.py +0 -27
  24. snowflake/cli/api/exceptions.py +0 -164
  25. snowflake/cli/api/feature_flags.py +0 -55
  26. snowflake/cli/api/identifiers.py +0 -154
  27. snowflake/cli/api/output/__init__.py +0 -13
  28. snowflake/cli/api/output/formats.py +0 -20
  29. snowflake/cli/api/output/types.py +0 -118
  30. snowflake/cli/api/plugins/__init__.py +0 -13
  31. snowflake/cli/api/plugins/command/__init__.py +0 -72
  32. snowflake/cli/api/plugins/command/plugin_hook_specs.py +0 -21
  33. snowflake/cli/api/plugins/plugin_config.py +0 -32
  34. snowflake/cli/api/project/__init__.py +0 -13
  35. snowflake/cli/api/project/definition.py +0 -84
  36. snowflake/cli/api/project/definition_manager.py +0 -134
  37. snowflake/cli/api/project/errors.py +0 -56
  38. snowflake/cli/api/project/project_verification.py +0 -23
  39. snowflake/cli/api/project/schemas/__init__.py +0 -13
  40. snowflake/cli/api/project/schemas/entities/application_entity.py +0 -44
  41. snowflake/cli/api/project/schemas/entities/application_package_entity.py +0 -66
  42. snowflake/cli/api/project/schemas/entities/common.py +0 -78
  43. snowflake/cli/api/project/schemas/entities/entities.py +0 -30
  44. snowflake/cli/api/project/schemas/identifier_model.py +0 -49
  45. snowflake/cli/api/project/schemas/native_app/__init__.py +0 -13
  46. snowflake/cli/api/project/schemas/native_app/application.py +0 -62
  47. snowflake/cli/api/project/schemas/native_app/native_app.py +0 -93
  48. snowflake/cli/api/project/schemas/native_app/package.py +0 -78
  49. snowflake/cli/api/project/schemas/native_app/path_mapping.py +0 -65
  50. snowflake/cli/api/project/schemas/project_definition.py +0 -199
  51. snowflake/cli/api/project/schemas/snowpark/__init__.py +0 -13
  52. snowflake/cli/api/project/schemas/snowpark/argument.py +0 -28
  53. snowflake/cli/api/project/schemas/snowpark/callable.py +0 -69
  54. snowflake/cli/api/project/schemas/snowpark/snowpark.py +0 -36
  55. snowflake/cli/api/project/schemas/streamlit/__init__.py +0 -13
  56. snowflake/cli/api/project/schemas/streamlit/streamlit.py +0 -46
  57. snowflake/cli/api/project/schemas/template.py +0 -77
  58. snowflake/cli/api/project/schemas/updatable_model.py +0 -194
  59. snowflake/cli/api/project/util.py +0 -261
  60. snowflake/cli/api/rendering/__init__.py +0 -13
  61. snowflake/cli/api/rendering/jinja.py +0 -112
  62. snowflake/cli/api/rendering/project_definition_templates.py +0 -39
  63. snowflake/cli/api/rendering/project_templates.py +0 -98
  64. snowflake/cli/api/rendering/sql_templates.py +0 -60
  65. snowflake/cli/api/rest_api.py +0 -172
  66. snowflake/cli/api/sanitizers.py +0 -43
  67. snowflake/cli/api/secure_path.py +0 -362
  68. snowflake/cli/api/secure_utils.py +0 -29
  69. snowflake/cli/api/sql_execution.py +0 -260
  70. snowflake/cli/api/utils/__init__.py +0 -13
  71. snowflake/cli/api/utils/cursor.py +0 -34
  72. snowflake/cli/api/utils/definition_rendering.py +0 -383
  73. snowflake/cli/api/utils/dict_utils.py +0 -73
  74. snowflake/cli/api/utils/error_handling.py +0 -23
  75. snowflake/cli/api/utils/graph.py +0 -97
  76. snowflake/cli/api/utils/models.py +0 -63
  77. snowflake/cli/api/utils/naming_utils.py +0 -13
  78. snowflake/cli/api/utils/path_utils.py +0 -36
  79. snowflake/cli/api/utils/templating_functions.py +0 -144
  80. snowflake/cli/api/utils/types.py +0 -35
  81. snowflake/cli/app/__init__.py +0 -22
  82. snowflake/cli/app/__main__.py +0 -31
  83. snowflake/cli/app/api_impl/__init__.py +0 -13
  84. snowflake/cli/app/api_impl/plugin/__init__.py +0 -13
  85. snowflake/cli/app/api_impl/plugin/plugin_config_provider_impl.py +0 -66
  86. snowflake/cli/app/build_and_push.sh +0 -8
  87. snowflake/cli/app/cli_app.py +0 -243
  88. snowflake/cli/app/commands_registration/__init__.py +0 -33
  89. snowflake/cli/app/commands_registration/builtin_plugins.py +0 -54
  90. snowflake/cli/app/commands_registration/command_plugins_loader.py +0 -169
  91. snowflake/cli/app/commands_registration/commands_registration_with_callbacks.py +0 -105
  92. snowflake/cli/app/commands_registration/exception_logging.py +0 -26
  93. snowflake/cli/app/commands_registration/threadsafe.py +0 -48
  94. snowflake/cli/app/commands_registration/typer_registration.py +0 -153
  95. snowflake/cli/app/constants.py +0 -19
  96. snowflake/cli/app/dev/__init__.py +0 -13
  97. snowflake/cli/app/dev/commands_structure.py +0 -48
  98. snowflake/cli/app/dev/docs/__init__.py +0 -13
  99. snowflake/cli/app/dev/docs/commands_docs_generator.py +0 -100
  100. snowflake/cli/app/dev/docs/generator.py +0 -35
  101. snowflake/cli/app/dev/docs/project_definition_docs_generator.py +0 -58
  102. snowflake/cli/app/dev/docs/project_definition_generate_json_schema.py +0 -227
  103. snowflake/cli/app/dev/docs/template_utils.py +0 -23
  104. snowflake/cli/app/dev/docs/templates/definition_description.rst.jinja2 +0 -38
  105. snowflake/cli/app/dev/docs/templates/overview.rst.jinja2 +0 -9
  106. snowflake/cli/app/dev/docs/templates/usage.rst.jinja2 +0 -57
  107. snowflake/cli/app/dev/pycharm_remote_debug.py +0 -46
  108. snowflake/cli/app/loggers.py +0 -199
  109. snowflake/cli/app/main_typer.py +0 -62
  110. snowflake/cli/app/printing.py +0 -181
  111. snowflake/cli/app/snow_connector.py +0 -243
  112. snowflake/cli/app/telemetry.py +0 -189
  113. snowflake/cli/plugins/__init__.py +0 -13
  114. snowflake/cli/plugins/connection/__init__.py +0 -13
  115. snowflake/cli/plugins/connection/commands.py +0 -330
  116. snowflake/cli/plugins/connection/plugin_spec.py +0 -30
  117. snowflake/cli/plugins/connection/util.py +0 -179
  118. snowflake/cli/plugins/cortex/__init__.py +0 -13
  119. snowflake/cli/plugins/cortex/commands.py +0 -327
  120. snowflake/cli/plugins/cortex/constants.py +0 -17
  121. snowflake/cli/plugins/cortex/manager.py +0 -189
  122. snowflake/cli/plugins/cortex/plugin_spec.py +0 -30
  123. snowflake/cli/plugins/cortex/types.py +0 -22
  124. snowflake/cli/plugins/git/__init__.py +0 -13
  125. snowflake/cli/plugins/git/commands.py +0 -305
  126. snowflake/cli/plugins/git/manager.py +0 -96
  127. snowflake/cli/plugins/git/plugin_spec.py +0 -30
  128. snowflake/cli/plugins/init/__init__.py +0 -13
  129. snowflake/cli/plugins/init/commands.py +0 -244
  130. snowflake/cli/plugins/init/plugin_spec.py +0 -30
  131. snowflake/cli/plugins/nativeapp/__init__.py +0 -13
  132. snowflake/cli/plugins/nativeapp/artifacts.py +0 -742
  133. snowflake/cli/plugins/nativeapp/codegen/__init__.py +0 -13
  134. snowflake/cli/plugins/nativeapp/codegen/artifact_processor.py +0 -91
  135. snowflake/cli/plugins/nativeapp/codegen/compiler.py +0 -130
  136. snowflake/cli/plugins/nativeapp/codegen/sandbox.py +0 -306
  137. snowflake/cli/plugins/nativeapp/codegen/setup/native_app_setup_processor.py +0 -172
  138. snowflake/cli/plugins/nativeapp/codegen/setup/setup_driver.py.source +0 -56
  139. snowflake/cli/plugins/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -181
  140. snowflake/cli/plugins/nativeapp/codegen/snowpark/extension_function_utils.py +0 -217
  141. snowflake/cli/plugins/nativeapp/codegen/snowpark/models.py +0 -61
  142. snowflake/cli/plugins/nativeapp/codegen/snowpark/python_processor.py +0 -528
  143. snowflake/cli/plugins/nativeapp/commands.py +0 -439
  144. snowflake/cli/plugins/nativeapp/common_flags.py +0 -44
  145. snowflake/cli/plugins/nativeapp/constants.py +0 -27
  146. snowflake/cli/plugins/nativeapp/exceptions.py +0 -122
  147. snowflake/cli/plugins/nativeapp/feature_flags.py +0 -24
  148. snowflake/cli/plugins/nativeapp/init.py +0 -345
  149. snowflake/cli/plugins/nativeapp/manager.py +0 -823
  150. snowflake/cli/plugins/nativeapp/plugin_spec.py +0 -30
  151. snowflake/cli/plugins/nativeapp/policy.py +0 -50
  152. snowflake/cli/plugins/nativeapp/project_model.py +0 -195
  153. snowflake/cli/plugins/nativeapp/run_processor.py +0 -389
  154. snowflake/cli/plugins/nativeapp/teardown_processor.py +0 -301
  155. snowflake/cli/plugins/nativeapp/utils.py +0 -98
  156. snowflake/cli/plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +0 -135
  157. snowflake/cli/plugins/nativeapp/version/__init__.py +0 -13
  158. snowflake/cli/plugins/nativeapp/version/commands.py +0 -170
  159. snowflake/cli/plugins/nativeapp/version/version_processor.py +0 -362
  160. snowflake/cli/plugins/notebook/__init__.py +0 -13
  161. snowflake/cli/plugins/notebook/commands.py +0 -84
  162. snowflake/cli/plugins/notebook/exceptions.py +0 -20
  163. snowflake/cli/plugins/notebook/manager.py +0 -71
  164. snowflake/cli/plugins/notebook/plugin_spec.py +0 -30
  165. snowflake/cli/plugins/notebook/types.py +0 -16
  166. snowflake/cli/plugins/object/__init__.py +0 -13
  167. snowflake/cli/plugins/object/command_aliases.py +0 -94
  168. snowflake/cli/plugins/object/commands.py +0 -174
  169. snowflake/cli/plugins/object/common.py +0 -85
  170. snowflake/cli/plugins/object/manager.py +0 -96
  171. snowflake/cli/plugins/object/plugin_spec.py +0 -30
  172. snowflake/cli/plugins/object_stage_deprecated/__init__.py +0 -15
  173. snowflake/cli/plugins/object_stage_deprecated/commands.py +0 -122
  174. snowflake/cli/plugins/object_stage_deprecated/plugin_spec.py +0 -32
  175. snowflake/cli/plugins/snowpark/__init__.py +0 -13
  176. snowflake/cli/plugins/snowpark/commands.py +0 -548
  177. snowflake/cli/plugins/snowpark/common.py +0 -307
  178. snowflake/cli/plugins/snowpark/manager.py +0 -109
  179. snowflake/cli/plugins/snowpark/models.py +0 -156
  180. snowflake/cli/plugins/snowpark/package/__init__.py +0 -13
  181. snowflake/cli/plugins/snowpark/package/anaconda_packages.py +0 -233
  182. snowflake/cli/plugins/snowpark/package/commands.py +0 -256
  183. snowflake/cli/plugins/snowpark/package/manager.py +0 -43
  184. snowflake/cli/plugins/snowpark/package/utils.py +0 -26
  185. snowflake/cli/plugins/snowpark/package_utils.py +0 -354
  186. snowflake/cli/plugins/snowpark/plugin_spec.py +0 -30
  187. snowflake/cli/plugins/snowpark/snowpark_package_paths.py +0 -65
  188. snowflake/cli/plugins/snowpark/snowpark_shared.py +0 -95
  189. snowflake/cli/plugins/snowpark/zipper.py +0 -81
  190. snowflake/cli/plugins/spcs/__init__.py +0 -35
  191. snowflake/cli/plugins/spcs/common.py +0 -99
  192. snowflake/cli/plugins/spcs/compute_pool/__init__.py +0 -13
  193. snowflake/cli/plugins/spcs/compute_pool/commands.py +0 -240
  194. snowflake/cli/plugins/spcs/compute_pool/manager.py +0 -121
  195. snowflake/cli/plugins/spcs/image_registry/__init__.py +0 -13
  196. snowflake/cli/plugins/spcs/image_registry/commands.py +0 -65
  197. snowflake/cli/plugins/spcs/image_registry/manager.py +0 -105
  198. snowflake/cli/plugins/spcs/image_repository/__init__.py +0 -13
  199. snowflake/cli/plugins/spcs/image_repository/commands.py +0 -196
  200. snowflake/cli/plugins/spcs/image_repository/manager.py +0 -84
  201. snowflake/cli/plugins/spcs/jobs/__init__.py +0 -13
  202. snowflake/cli/plugins/spcs/jobs/commands.py +0 -78
  203. snowflake/cli/plugins/spcs/jobs/manager.py +0 -53
  204. snowflake/cli/plugins/spcs/plugin_spec.py +0 -30
  205. snowflake/cli/plugins/spcs/services/__init__.py +0 -13
  206. snowflake/cli/plugins/spcs/services/commands.py +0 -311
  207. snowflake/cli/plugins/spcs/services/manager.py +0 -170
  208. snowflake/cli/plugins/sql/__init__.py +0 -13
  209. snowflake/cli/plugins/sql/commands.py +0 -83
  210. snowflake/cli/plugins/sql/manager.py +0 -92
  211. snowflake/cli/plugins/sql/plugin_spec.py +0 -30
  212. snowflake/cli/plugins/sql/snowsql_templating.py +0 -28
  213. snowflake/cli/plugins/stage/__init__.py +0 -13
  214. snowflake/cli/plugins/stage/commands.py +0 -261
  215. snowflake/cli/plugins/stage/diff.py +0 -326
  216. snowflake/cli/plugins/stage/manager.py +0 -544
  217. snowflake/cli/plugins/stage/md5.py +0 -160
  218. snowflake/cli/plugins/stage/plugin_spec.py +0 -30
  219. snowflake/cli/plugins/streamlit/__init__.py +0 -13
  220. snowflake/cli/plugins/streamlit/commands.py +0 -186
  221. snowflake/cli/plugins/streamlit/manager.py +0 -222
  222. snowflake/cli/plugins/streamlit/plugin_spec.py +0 -30
  223. snowflake/cli/plugins/workspace/__init__.py +0 -13
  224. snowflake/cli/plugins/workspace/commands.py +0 -35
  225. snowflake/cli/plugins/workspace/plugin_spec.py +0 -30
  226. snowflake/cli/templates/default_snowpark/.gitignore +0 -4
  227. snowflake/cli/templates/default_snowpark/app/__init__.py +0 -0
  228. snowflake/cli/templates/default_snowpark/app/common.py +0 -2
  229. snowflake/cli/templates/default_snowpark/app/functions.py +0 -15
  230. snowflake/cli/templates/default_snowpark/app/procedures.py +0 -22
  231. snowflake/cli/templates/default_snowpark/requirements.txt +0 -1
  232. snowflake/cli/templates/default_snowpark/snowflake.yml +0 -23
  233. snowflake/cli/templates/default_streamlit/.gitignore +0 -4
  234. snowflake/cli/templates/default_streamlit/common/hello.py +0 -2
  235. snowflake/cli/templates/default_streamlit/environment.yml +0 -6
  236. snowflake/cli/templates/default_streamlit/pages/my_page.py +0 -3
  237. snowflake/cli/templates/default_streamlit/snowflake.yml +0 -10
  238. snowflake/cli/templates/default_streamlit/streamlit_app.py +0 -4
  239. snowflake_cli_labs-2.8.0rc1.dist-info/RECORD +0 -240
  240. snowflake_cli_labs-2.8.0rc1.dist-info/entry_points.txt +0 -2
  241. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-2.8.2.dist-info}/WHEEL +0 -0
  242. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-2.8.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,30 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from snowflake.cli.api.plugins.command import (
16
- SNOWCLI_ROOT_COMMAND_PATH,
17
- CommandSpec,
18
- CommandType,
19
- plugin_hook_impl,
20
- )
21
- from snowflake.cli.plugins.nativeapp import commands
22
-
23
-
24
- @plugin_hook_impl
25
- def command_spec():
26
- return CommandSpec(
27
- parent_command_path=SNOWCLI_ROOT_COMMAND_PATH,
28
- command_type=CommandType.COMMAND_GROUP,
29
- typer_instance=commands.app.create_instance(),
30
- )
@@ -1,50 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from __future__ import annotations
16
-
17
- from abc import ABC, abstractmethod
18
- from typing import Optional
19
-
20
- import typer
21
-
22
-
23
- class PolicyBase(ABC):
24
- """Abstract Class for various policies that govern if a Snowflake CLI command can continue execution when it asks for a decision."""
25
-
26
- @abstractmethod
27
- def should_proceed(self, user_prompt: Optional[str]) -> bool:
28
- pass
29
-
30
-
31
- class AllowAlwaysPolicy(PolicyBase):
32
- """Always allow a Snowflake CLI command to continue execution."""
33
-
34
- def should_proceed(self, user_prompt: Optional[str] = None):
35
- return True
36
-
37
-
38
- class DenyAlwaysPolicy(PolicyBase):
39
- """Never allow a Snowflake CLI command to continue execution."""
40
-
41
- def should_proceed(self, user_prompt: Optional[str] = None):
42
- return False
43
-
44
-
45
- class AskAlwaysPolicy(PolicyBase):
46
- """Ask the user whether to continue execution of a Snowflake CLI command."""
47
-
48
- def should_proceed(self, user_prompt: Optional[str]):
49
- should_continue = typer.confirm(user_prompt)
50
- return should_continue
@@ -1,195 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from __future__ import annotations
16
-
17
- from functools import cached_property
18
- from pathlib import Path
19
- from typing import List, Optional
20
-
21
- from snowflake.cli.api.cli_global_context import cli_context
22
- from snowflake.cli.api.project.definition import (
23
- default_app_package,
24
- default_application,
25
- default_role,
26
- )
27
- from snowflake.cli.api.project.schemas.native_app.application import (
28
- PostDeployHook,
29
- )
30
- from snowflake.cli.api.project.schemas.native_app.native_app import NativeApp
31
- from snowflake.cli.api.project.schemas.native_app.path_mapping import PathMapping
32
- from snowflake.cli.api.project.util import extract_schema, to_identifier
33
- from snowflake.cli.plugins.nativeapp.artifacts import resolve_without_follow
34
- from snowflake.connector import DictCursor
35
-
36
-
37
- def current_role() -> str:
38
- conn = cli_context.connection
39
- *_, cursor = conn.execute_string("select current_role()", cursor_class=DictCursor)
40
- role_result = cursor.fetchone()
41
- return role_result["CURRENT_ROLE()"]
42
-
43
-
44
- class NativeAppProjectModel:
45
- """
46
- Exposes properties of a native app project defined in a Snowflake Project Definition file. Whenever
47
- appropriate, APIs defined in this class provide suitable defaults or fallback logic to access properties
48
- of the project.
49
- """
50
-
51
- def __init__(
52
- self,
53
- project_definition: NativeApp,
54
- project_root: Path,
55
- ):
56
- self._project_definition = project_definition
57
- self._project_root = resolve_without_follow(project_root)
58
-
59
- @property
60
- def project_root(self) -> Path:
61
- return self._project_root
62
-
63
- @property
64
- def definition(self) -> NativeApp:
65
- return self._project_definition
66
-
67
- @cached_property
68
- def artifacts(self) -> List[PathMapping]:
69
- return self.definition.artifacts
70
-
71
- @cached_property
72
- def bundle_root(self) -> Path:
73
- return self.project_root / self.definition.bundle_root
74
-
75
- @cached_property
76
- def deploy_root(self) -> Path:
77
- return self.project_root / self.definition.deploy_root
78
-
79
- @cached_property
80
- def generated_root(self) -> Path:
81
- return self.deploy_root / self.definition.generated_root
82
-
83
- @cached_property
84
- def package_scripts(self) -> List[str]:
85
- """
86
- Relative paths to package scripts from the project root.
87
- """
88
- if self.definition.package and self.definition.package.scripts:
89
- return self.definition.package.scripts
90
- else:
91
- return []
92
-
93
- @cached_property
94
- def stage_fqn(self) -> str:
95
- return f"{self.package_name}.{self.definition.source_stage}"
96
-
97
- @cached_property
98
- def scratch_stage_fqn(self) -> str:
99
- return f"{self.package_name}.{self.definition.scratch_stage}"
100
-
101
- @cached_property
102
- def stage_schema(self) -> Optional[str]:
103
- return extract_schema(self.stage_fqn)
104
-
105
- @cached_property
106
- def package_warehouse(self) -> Optional[str]:
107
- if self.definition.package and self.definition.package.warehouse:
108
- return to_identifier(self.definition.package.warehouse)
109
- else:
110
- if cli_context.connection.warehouse:
111
- return to_identifier(cli_context.connection.warehouse)
112
- return None
113
-
114
- @cached_property
115
- def application_warehouse(self) -> Optional[str]:
116
- if self.definition.application and self.definition.application.warehouse:
117
- return to_identifier(self.definition.application.warehouse)
118
- else:
119
- if cli_context.connection.warehouse:
120
- return to_identifier(cli_context.connection.warehouse)
121
- return None
122
-
123
- @cached_property
124
- def project_identifier(self) -> str:
125
- # name is expected to be a valid Snowflake identifier, but YAML parsers will
126
- # sometimes strip out double quotes, so we try to get them back here.
127
- return to_identifier(self.definition.name)
128
-
129
- @cached_property
130
- def package_name(self) -> str:
131
- if self.definition.package and self.definition.package.name:
132
- return to_identifier(self.definition.package.name)
133
- else:
134
- return to_identifier(default_app_package(self.project_identifier))
135
-
136
- @cached_property
137
- def package_role(self) -> str:
138
- if self.definition.package and self.definition.package.role:
139
- return self.definition.package.role
140
- else:
141
- return self._default_role
142
-
143
- @cached_property
144
- def package_distribution(self) -> str:
145
- if self.definition.package and self.definition.package.distribution:
146
- return self.definition.package.distribution.lower()
147
- else:
148
- return "internal"
149
-
150
- @cached_property
151
- def app_name(self) -> str:
152
- if self.definition.application and self.definition.application.name:
153
- return to_identifier(self.definition.application.name)
154
- else:
155
- return to_identifier(default_application(self.project_identifier))
156
-
157
- @cached_property
158
- def app_role(self) -> str:
159
- if self.definition.application and self.definition.application.role:
160
- return self.definition.application.role
161
- else:
162
- return self._default_role
163
-
164
- @cached_property
165
- def app_post_deploy_hooks(self) -> Optional[List[PostDeployHook]]:
166
- """
167
- List of application instance post deploy hooks.
168
- """
169
- if self.definition.application and self.definition.application.post_deploy:
170
- return self.definition.application.post_deploy
171
- else:
172
- return None
173
-
174
- @cached_property
175
- def package_post_deploy_hooks(self) -> Optional[List[PostDeployHook]]:
176
- """
177
- List of application package post deploy hooks.
178
- """
179
- if self.definition.package and self.definition.package.post_deploy:
180
- return self.definition.package.post_deploy
181
- else:
182
- return None
183
-
184
- @cached_property
185
- def _default_role(self) -> str:
186
- role = default_role()
187
- if role is None:
188
- role = current_role()
189
- return role
190
-
191
- @cached_property
192
- def debug_mode(self) -> Optional[bool]:
193
- if self.definition.application:
194
- return self.definition.application.debug
195
- return None
@@ -1,389 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from __future__ import annotations
16
-
17
- from pathlib import Path
18
- from textwrap import dedent
19
- from typing import Optional
20
-
21
- import typer
22
- from click import UsageError
23
- from snowflake.cli.api.console import cli_console as cc
24
- from snowflake.cli.api.errno import (
25
- APPLICATION_NO_LONGER_AVAILABLE,
26
- APPLICATION_OWNS_EXTERNAL_OBJECTS,
27
- CANNOT_UPGRADE_FROM_LOOSE_FILES_TO_VERSION,
28
- CANNOT_UPGRADE_FROM_VERSION_TO_LOOSE_FILES,
29
- NOT_SUPPORTED_ON_DEV_MODE_APPLICATIONS,
30
- ONLY_SUPPORTED_ON_DEV_MODE_APPLICATIONS,
31
- )
32
- from snowflake.cli.api.exceptions import SnowflakeSQLExecutionError
33
- from snowflake.cli.api.project.schemas.native_app.native_app import NativeApp
34
- from snowflake.cli.api.project.util import (
35
- identifier_to_show_like_pattern,
36
- unquote_identifier,
37
- )
38
- from snowflake.cli.api.utils.cursor import find_all_rows
39
- from snowflake.cli.plugins.nativeapp.artifacts import BundleMap
40
- from snowflake.cli.plugins.nativeapp.constants import (
41
- ALLOWED_SPECIAL_COMMENTS,
42
- COMMENT_COL,
43
- PATCH_COL,
44
- SPECIAL_COMMENT,
45
- VERSION_COL,
46
- )
47
- from snowflake.cli.plugins.nativeapp.exceptions import (
48
- ApplicationCreatedExternallyError,
49
- ApplicationPackageDoesNotExistError,
50
- )
51
- from snowflake.cli.plugins.nativeapp.manager import (
52
- NativeAppCommandProcessor,
53
- NativeAppManager,
54
- ensure_correct_owner,
55
- generic_sql_error_handler,
56
- )
57
- from snowflake.cli.plugins.nativeapp.policy import PolicyBase
58
- from snowflake.cli.plugins.nativeapp.project_model import (
59
- NativeAppProjectModel,
60
- )
61
- from snowflake.cli.plugins.stage.manager import StageManager
62
- from snowflake.connector import ProgrammingError
63
- from snowflake.connector.cursor import DictCursor, SnowflakeCursor
64
-
65
- # Reasons why an `alter application ... upgrade` might fail
66
- UPGRADE_RESTRICTION_CODES = {
67
- CANNOT_UPGRADE_FROM_LOOSE_FILES_TO_VERSION,
68
- CANNOT_UPGRADE_FROM_VERSION_TO_LOOSE_FILES,
69
- ONLY_SUPPORTED_ON_DEV_MODE_APPLICATIONS,
70
- NOT_SUPPORTED_ON_DEV_MODE_APPLICATIONS,
71
- APPLICATION_NO_LONGER_AVAILABLE,
72
- }
73
-
74
-
75
- def print_messages(create_or_upgrade_cursor: Optional[SnowflakeCursor]):
76
- """
77
- Shows messages in the console returned by the CREATE or UPGRADE
78
- APPLICATION command.
79
- """
80
- if not create_or_upgrade_cursor:
81
- return
82
-
83
- messages = [row[0] for row in create_or_upgrade_cursor.fetchall()]
84
- for message in messages:
85
- cc.warning(message)
86
- cc.message("")
87
-
88
-
89
- class SameAccountInstallMethod:
90
- _requires_created_by_cli: bool
91
- _from_release_directive: bool
92
- version: Optional[str]
93
- patch: Optional[int]
94
-
95
- def __init__(
96
- self,
97
- requires_created_by_cli: bool,
98
- version: Optional[str] = None,
99
- patch: Optional[int] = None,
100
- from_release_directive: bool = False,
101
- ):
102
- self._requires_created_by_cli = requires_created_by_cli
103
- self.version = version
104
- self.patch = patch
105
- self._from_release_directive = from_release_directive
106
-
107
- @classmethod
108
- def unversioned_dev(cls):
109
- """aka. stage dev aka loose files"""
110
- return cls(True)
111
-
112
- @classmethod
113
- def versioned_dev(cls, version: str, patch: Optional[int] = None):
114
- return cls(False, version, patch)
115
-
116
- @classmethod
117
- def release_directive(cls):
118
- return cls(False, from_release_directive=True)
119
-
120
- @property
121
- def is_dev_mode(self) -> bool:
122
- return not self._from_release_directive
123
-
124
- def using_clause(self, app: NativeAppProjectModel) -> str:
125
- if self._from_release_directive:
126
- return ""
127
-
128
- if self.version:
129
- patch_clause = f"patch {self.patch}" if self.patch else ""
130
- return f"using version {self.version} {patch_clause}"
131
-
132
- stage_name = StageManager.quote_stage_name(app.stage_fqn)
133
- return f"using {stage_name}"
134
-
135
- def ensure_app_usable(self, app: NativeAppProjectModel, show_app_row: dict):
136
- """Raise an exception if we cannot proceed with install given the pre-existing application object"""
137
-
138
- if self._requires_created_by_cli:
139
- if show_app_row[COMMENT_COL] not in ALLOWED_SPECIAL_COMMENTS:
140
- # this application object was not created by this tooling
141
- raise ApplicationCreatedExternallyError(app.app_name)
142
-
143
- # expected owner
144
- ensure_correct_owner(row=show_app_row, role=app.app_role, obj_name=app.app_name)
145
-
146
-
147
- class NativeAppRunProcessor(NativeAppManager, NativeAppCommandProcessor):
148
- def __init__(self, project_definition: NativeApp, project_root: Path):
149
- super().__init__(project_definition, project_root)
150
-
151
- def get_all_existing_versions(self) -> SnowflakeCursor:
152
- """
153
- Get all existing versions, if defined, for an application package.
154
- It executes a 'show versions in application package' query and returns all the results.
155
- """
156
- with self.use_role(self.package_role):
157
- show_obj_query = f"show versions in application package {self.package_name}"
158
- show_obj_cursor = self._execute_query(show_obj_query)
159
-
160
- if show_obj_cursor.rowcount is None:
161
- raise SnowflakeSQLExecutionError(show_obj_query)
162
-
163
- return show_obj_cursor
164
-
165
- def get_existing_version_info(self, version: str) -> Optional[dict]:
166
- """
167
- Get the latest patch on an existing version by name in the application package.
168
- Executes 'show versions like ... in application package' query and returns
169
- the latest patch in the version as a single row, if one exists. Otherwise,
170
- returns None.
171
- """
172
- with self.use_role(self.package_role):
173
- try:
174
- query = f"show versions like {identifier_to_show_like_pattern(version)} in application package {self.package_name}"
175
- cursor = self._execute_query(query, cursor_class=DictCursor)
176
-
177
- if cursor.rowcount is None:
178
- raise SnowflakeSQLExecutionError(query)
179
-
180
- matching_rows = find_all_rows(
181
- cursor, lambda row: row[VERSION_COL] == unquote_identifier(version)
182
- )
183
-
184
- if not matching_rows:
185
- return None
186
-
187
- return max(matching_rows, key=lambda row: row[PATCH_COL])
188
-
189
- except ProgrammingError as err:
190
- if err.msg.__contains__("does not exist or not authorized"):
191
- raise ApplicationPackageDoesNotExistError(self.package_name)
192
- else:
193
- generic_sql_error_handler(err=err, role=self.package_role)
194
- return None
195
-
196
- def drop_application_before_upgrade(
197
- self, policy: PolicyBase, is_interactive: bool, cascade: bool = False
198
- ):
199
- """
200
- This method will attempt to drop an application object if a previous upgrade fails.
201
- """
202
- if cascade:
203
- try:
204
- if application_objects := self.get_objects_owned_by_application():
205
- application_objects_str = self._application_objects_to_str(
206
- application_objects
207
- )
208
- cc.message(
209
- f"The following objects are owned by application {self.app_name} and need to be dropped:\n{application_objects_str}"
210
- )
211
- except ProgrammingError as err:
212
- if err.errno != APPLICATION_NO_LONGER_AVAILABLE:
213
- generic_sql_error_handler(err)
214
- cc.warning(
215
- "The application owns other objects but they could not be determined."
216
- )
217
- user_prompt = "Do you want the Snowflake CLI to drop these objects, then drop the existing application object and recreate it?"
218
- else:
219
- user_prompt = "Do you want the Snowflake CLI to drop the existing application object and recreate it?"
220
-
221
- if not policy.should_proceed(user_prompt):
222
- if is_interactive:
223
- cc.message("Not upgrading the application object.")
224
- raise typer.Exit(0)
225
- else:
226
- cc.message(
227
- "Cannot upgrade the application object non-interactively without --force."
228
- )
229
- raise typer.Exit(1)
230
- try:
231
- cascade_msg = " (cascade)" if cascade else ""
232
- cc.step(f"Dropping application object {self.app_name}{cascade_msg}.")
233
- cascade_sql = " cascade" if cascade else ""
234
- self._execute_query(f"drop application {self.app_name}{cascade_sql}")
235
- except ProgrammingError as err:
236
- if err.errno == APPLICATION_OWNS_EXTERNAL_OBJECTS and not cascade:
237
- # We need to cascade the deletion, let's try again (only if we didn't try with cascade already)
238
- return self.drop_application_before_upgrade(
239
- policy, is_interactive, cascade=True
240
- )
241
- else:
242
- generic_sql_error_handler(err)
243
-
244
- def create_or_upgrade_app(
245
- self,
246
- policy: PolicyBase,
247
- install_method: SameAccountInstallMethod,
248
- is_interactive: bool = False,
249
- ):
250
- with self.use_role(self.app_role):
251
-
252
- # 1. Need to use a warehouse to create an application object
253
- with self.use_warehouse(self.application_warehouse):
254
-
255
- # 2. Check for an existing application by the same name
256
- show_app_row = self.get_existing_app_info()
257
-
258
- # 3. If existing application is found, perform a few validations and upgrade the application object.
259
- if show_app_row:
260
-
261
- install_method.ensure_app_usable(self._na_project, show_app_row)
262
-
263
- # If all the above checks are in order, proceed to upgrade
264
- try:
265
- cc.step(
266
- f"Upgrading existing application object {self.app_name}."
267
- )
268
- using_clause = install_method.using_clause(self._na_project)
269
- upgrade_cursor = self._execute_query(
270
- f"alter application {self.app_name} upgrade {using_clause}",
271
- )
272
- print_messages(upgrade_cursor)
273
-
274
- if install_method.is_dev_mode:
275
- # if debug_mode is present (controlled), ensure it is up-to-date
276
- if self.debug_mode is not None:
277
- self._execute_query(
278
- f"alter application {self.app_name} set debug_mode = {self.debug_mode}"
279
- )
280
-
281
- # hooks always executed after a create or upgrade
282
- self.execute_app_post_deploy_hooks()
283
- return
284
-
285
- except ProgrammingError as err:
286
- if err.errno not in UPGRADE_RESTRICTION_CODES:
287
- generic_sql_error_handler(err=err)
288
- else: # The existing application object was created from a different process.
289
- cc.warning(err.msg)
290
- self.drop_application_before_upgrade(policy, is_interactive)
291
-
292
- # 4. With no (more) existing application objects, create an application object using the release directives
293
- cc.step(f"Creating new application object {self.app_name} in account.")
294
-
295
- if self.app_role != self.package_role:
296
- with self.use_role(self.package_role):
297
- self._execute_query(
298
- f"grant install, develop on application package {self.package_name} to role {self.app_role}"
299
- )
300
- self._execute_query(
301
- f"grant usage on schema {self.package_name}.{self.stage_schema} to role {self.app_role}"
302
- )
303
- self._execute_query(
304
- f"grant read on stage {self.stage_fqn} to role {self.app_role}"
305
- )
306
-
307
- try:
308
- # by default, applications are created in debug mode when possible;
309
- # this can be overridden in the project definition
310
- debug_mode_clause = ""
311
- if install_method.is_dev_mode:
312
- initial_debug_mode = (
313
- self.debug_mode if self.debug_mode is not None else True
314
- )
315
- debug_mode_clause = f"debug_mode = {initial_debug_mode}"
316
-
317
- using_clause = install_method.using_clause(self._na_project)
318
- create_cursor = self._execute_query(
319
- dedent(
320
- f"""\
321
- create application {self.app_name}
322
- from application package {self.package_name} {using_clause} {debug_mode_clause}
323
- comment = {SPECIAL_COMMENT}
324
- """
325
- ),
326
- )
327
- print_messages(create_cursor)
328
-
329
- # hooks always executed after a create or upgrade
330
- self.execute_app_post_deploy_hooks()
331
-
332
- except ProgrammingError as err:
333
- generic_sql_error_handler(err)
334
-
335
- def process(
336
- self,
337
- bundle_map: BundleMap,
338
- policy: PolicyBase,
339
- version: Optional[str] = None,
340
- patch: Optional[int] = None,
341
- from_release_directive: bool = False,
342
- is_interactive: bool = False,
343
- validate: bool = True,
344
- *args,
345
- **kwargs,
346
- ):
347
- """
348
- Create or upgrade the application object using the given strategy
349
- (unversioned dev, versioned dev, or same-account release directive).
350
- """
351
-
352
- # same-account release directive
353
- if from_release_directive:
354
- self.create_or_upgrade_app(
355
- policy=policy,
356
- is_interactive=is_interactive,
357
- install_method=SameAccountInstallMethod.release_directive(),
358
- )
359
- return
360
-
361
- # versioned dev
362
- if version:
363
- try:
364
- version_exists = self.get_existing_version_info(version)
365
- if not version_exists:
366
- raise UsageError(
367
- f"Application package {self.package_name} does not have any version {version} defined. Use 'snow app version create' to define a version in the application package first."
368
- )
369
- except ApplicationPackageDoesNotExistError as app_err:
370
- raise UsageError(
371
- f"Application package {self.package_name} does not exist. Use 'snow app version create' to first create an application package and then define a version in it."
372
- )
373
-
374
- self.create_or_upgrade_app(
375
- policy=policy,
376
- install_method=SameAccountInstallMethod.versioned_dev(version, patch),
377
- is_interactive=is_interactive,
378
- )
379
- return
380
-
381
- # unversioned dev
382
- self.deploy(
383
- bundle_map=bundle_map, prune=True, recursive=True, validate=validate
384
- )
385
- self.create_or_upgrade_app(
386
- policy=policy,
387
- is_interactive=is_interactive,
388
- install_method=SameAccountInstallMethod.unversioned_dev(),
389
- )