snowflake-cli-labs 3.0.0rc4__py3-none-any.whl → 3.0.1__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 (244) hide show
  1. README.md +21 -0
  2. {snowflake_cli_labs-3.0.0rc4.dist-info → snowflake_cli_labs-3.0.1.dist-info}/METADATA +6 -96
  3. snowflake_cli_labs-3.0.1.dist-info/RECORD +5 -0
  4. snowflake/cli/__about__.py +0 -17
  5. snowflake/cli/__init__.py +0 -13
  6. snowflake/cli/_app/__init__.py +0 -22
  7. snowflake/cli/_app/__main__.py +0 -31
  8. snowflake/cli/_app/api_impl/__init__.py +0 -13
  9. snowflake/cli/_app/api_impl/plugin/__init__.py +0 -13
  10. snowflake/cli/_app/api_impl/plugin/plugin_config_provider_impl.py +0 -66
  11. snowflake/cli/_app/cli_app.py +0 -252
  12. snowflake/cli/_app/commands_registration/__init__.py +0 -33
  13. snowflake/cli/_app/commands_registration/builtin_plugins.py +0 -50
  14. snowflake/cli/_app/commands_registration/command_plugins_loader.py +0 -169
  15. snowflake/cli/_app/commands_registration/commands_registration_with_callbacks.py +0 -105
  16. snowflake/cli/_app/commands_registration/exception_logging.py +0 -26
  17. snowflake/cli/_app/commands_registration/threadsafe.py +0 -48
  18. snowflake/cli/_app/commands_registration/typer_registration.py +0 -153
  19. snowflake/cli/_app/constants.py +0 -19
  20. snowflake/cli/_app/dev/__init__.py +0 -13
  21. snowflake/cli/_app/dev/commands_structure.py +0 -48
  22. snowflake/cli/_app/dev/docs/__init__.py +0 -13
  23. snowflake/cli/_app/dev/docs/commands_docs_generator.py +0 -118
  24. snowflake/cli/_app/dev/docs/generator.py +0 -35
  25. snowflake/cli/_app/dev/docs/project_definition_docs_generator.py +0 -58
  26. snowflake/cli/_app/dev/docs/project_definition_generate_json_schema.py +0 -227
  27. snowflake/cli/_app/dev/docs/template_utils.py +0 -23
  28. snowflake/cli/_app/dev/docs/templates/definition_description.rst.jinja2 +0 -38
  29. snowflake/cli/_app/dev/docs/templates/overview.rst.jinja2 +0 -9
  30. snowflake/cli/_app/dev/docs/templates/usage.rst.jinja2 +0 -67
  31. snowflake/cli/_app/dev/pycharm_remote_debug.py +0 -46
  32. snowflake/cli/_app/loggers.py +0 -199
  33. snowflake/cli/_app/main_typer.py +0 -62
  34. snowflake/cli/_app/printing.py +0 -181
  35. snowflake/cli/_app/secret.py +0 -9
  36. snowflake/cli/_app/snow_connector.py +0 -309
  37. snowflake/cli/_app/telemetry.py +0 -220
  38. snowflake/cli/_app/version_check.py +0 -74
  39. snowflake/cli/_plugins/__init__.py +0 -13
  40. snowflake/cli/_plugins/connection/__init__.py +0 -13
  41. snowflake/cli/_plugins/connection/commands.py +0 -353
  42. snowflake/cli/_plugins/connection/plugin_spec.py +0 -30
  43. snowflake/cli/_plugins/connection/util.py +0 -195
  44. snowflake/cli/_plugins/cortex/__init__.py +0 -13
  45. snowflake/cli/_plugins/cortex/commands.py +0 -332
  46. snowflake/cli/_plugins/cortex/constants.py +0 -17
  47. snowflake/cli/_plugins/cortex/manager.py +0 -189
  48. snowflake/cli/_plugins/cortex/plugin_spec.py +0 -30
  49. snowflake/cli/_plugins/cortex/types.py +0 -22
  50. snowflake/cli/_plugins/git/__init__.py +0 -13
  51. snowflake/cli/_plugins/git/commands.py +0 -358
  52. snowflake/cli/_plugins/git/manager.py +0 -151
  53. snowflake/cli/_plugins/git/plugin_spec.py +0 -30
  54. snowflake/cli/_plugins/helpers/__init__.py +0 -13
  55. snowflake/cli/_plugins/helpers/commands.py +0 -61
  56. snowflake/cli/_plugins/helpers/plugin_spec.py +0 -30
  57. snowflake/cli/_plugins/init/__init__.py +0 -13
  58. snowflake/cli/_plugins/init/commands.py +0 -248
  59. snowflake/cli/_plugins/init/plugin_spec.py +0 -30
  60. snowflake/cli/_plugins/nativeapp/__init__.py +0 -13
  61. snowflake/cli/_plugins/nativeapp/artifacts.py +0 -757
  62. snowflake/cli/_plugins/nativeapp/bundle_context.py +0 -31
  63. snowflake/cli/_plugins/nativeapp/codegen/__init__.py +0 -13
  64. snowflake/cli/_plugins/nativeapp/codegen/artifact_processor.py +0 -91
  65. snowflake/cli/_plugins/nativeapp/codegen/compiler.py +0 -149
  66. snowflake/cli/_plugins/nativeapp/codegen/sandbox.py +0 -306
  67. snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +0 -249
  68. snowflake/cli/_plugins/nativeapp/codegen/setup/setup_driver.py.source +0 -59
  69. snowflake/cli/_plugins/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -181
  70. snowflake/cli/_plugins/nativeapp/codegen/snowpark/extension_function_utils.py +0 -217
  71. snowflake/cli/_plugins/nativeapp/codegen/snowpark/models.py +0 -61
  72. snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +0 -523
  73. snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +0 -114
  74. snowflake/cli/_plugins/nativeapp/commands.py +0 -559
  75. snowflake/cli/_plugins/nativeapp/common_flags.py +0 -44
  76. snowflake/cli/_plugins/nativeapp/constants.py +0 -27
  77. snowflake/cli/_plugins/nativeapp/entities/__init__.py +0 -0
  78. snowflake/cli/_plugins/nativeapp/entities/application.py +0 -878
  79. snowflake/cli/_plugins/nativeapp/entities/application_package.py +0 -1392
  80. snowflake/cli/_plugins/nativeapp/exceptions.py +0 -113
  81. snowflake/cli/_plugins/nativeapp/feature_flags.py +0 -24
  82. snowflake/cli/_plugins/nativeapp/manager.py +0 -415
  83. snowflake/cli/_plugins/nativeapp/plugin_spec.py +0 -30
  84. snowflake/cli/_plugins/nativeapp/policy.py +0 -53
  85. snowflake/cli/_plugins/nativeapp/project_model.py +0 -211
  86. snowflake/cli/_plugins/nativeapp/run_processor.py +0 -184
  87. snowflake/cli/_plugins/nativeapp/same_account_install_method.py +0 -70
  88. snowflake/cli/_plugins/nativeapp/teardown_processor.py +0 -70
  89. snowflake/cli/_plugins/nativeapp/utils.py +0 -98
  90. snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +0 -262
  91. snowflake/cli/_plugins/nativeapp/version/__init__.py +0 -13
  92. snowflake/cli/_plugins/nativeapp/version/commands.py +0 -141
  93. snowflake/cli/_plugins/nativeapp/version/version_processor.py +0 -98
  94. snowflake/cli/_plugins/notebook/__init__.py +0 -13
  95. snowflake/cli/_plugins/notebook/commands.py +0 -86
  96. snowflake/cli/_plugins/notebook/exceptions.py +0 -20
  97. snowflake/cli/_plugins/notebook/manager.py +0 -71
  98. snowflake/cli/_plugins/notebook/plugin_spec.py +0 -30
  99. snowflake/cli/_plugins/notebook/types.py +0 -15
  100. snowflake/cli/_plugins/object/__init__.py +0 -13
  101. snowflake/cli/_plugins/object/command_aliases.py +0 -95
  102. snowflake/cli/_plugins/object/commands.py +0 -180
  103. snowflake/cli/_plugins/object/common.py +0 -85
  104. snowflake/cli/_plugins/object/manager.py +0 -118
  105. snowflake/cli/_plugins/object/plugin_spec.py +0 -30
  106. snowflake/cli/_plugins/snowpark/__init__.py +0 -13
  107. snowflake/cli/_plugins/snowpark/commands.py +0 -450
  108. snowflake/cli/_plugins/snowpark/common.py +0 -268
  109. snowflake/cli/_plugins/snowpark/models.py +0 -150
  110. snowflake/cli/_plugins/snowpark/package/__init__.py +0 -13
  111. snowflake/cli/_plugins/snowpark/package/anaconda_packages.py +0 -199
  112. snowflake/cli/_plugins/snowpark/package/commands.py +0 -195
  113. snowflake/cli/_plugins/snowpark/package/manager.py +0 -44
  114. snowflake/cli/_plugins/snowpark/package/utils.py +0 -26
  115. snowflake/cli/_plugins/snowpark/package_utils.py +0 -354
  116. snowflake/cli/_plugins/snowpark/plugin_spec.py +0 -30
  117. snowflake/cli/_plugins/snowpark/snowpark_entity.py +0 -29
  118. snowflake/cli/_plugins/snowpark/snowpark_entity_model.py +0 -173
  119. snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +0 -109
  120. snowflake/cli/_plugins/snowpark/snowpark_shared.py +0 -59
  121. snowflake/cli/_plugins/snowpark/zipper.py +0 -89
  122. snowflake/cli/_plugins/spcs/__init__.py +0 -33
  123. snowflake/cli/_plugins/spcs/common.py +0 -99
  124. snowflake/cli/_plugins/spcs/compute_pool/__init__.py +0 -13
  125. snowflake/cli/_plugins/spcs/compute_pool/commands.py +0 -241
  126. snowflake/cli/_plugins/spcs/compute_pool/manager.py +0 -121
  127. snowflake/cli/_plugins/spcs/image_registry/__init__.py +0 -13
  128. snowflake/cli/_plugins/spcs/image_registry/commands.py +0 -65
  129. snowflake/cli/_plugins/spcs/image_registry/manager.py +0 -105
  130. snowflake/cli/_plugins/spcs/image_repository/__init__.py +0 -13
  131. snowflake/cli/_plugins/spcs/image_repository/commands.py +0 -202
  132. snowflake/cli/_plugins/spcs/image_repository/manager.py +0 -84
  133. snowflake/cli/_plugins/spcs/plugin_spec.py +0 -30
  134. snowflake/cli/_plugins/spcs/services/__init__.py +0 -13
  135. snowflake/cli/_plugins/spcs/services/commands.py +0 -345
  136. snowflake/cli/_plugins/spcs/services/manager.py +0 -208
  137. snowflake/cli/_plugins/sql/__init__.py +0 -13
  138. snowflake/cli/_plugins/sql/commands.py +0 -86
  139. snowflake/cli/_plugins/sql/manager.py +0 -92
  140. snowflake/cli/_plugins/sql/plugin_spec.py +0 -30
  141. snowflake/cli/_plugins/sql/snowsql_templating.py +0 -28
  142. snowflake/cli/_plugins/stage/__init__.py +0 -13
  143. snowflake/cli/_plugins/stage/commands.py +0 -264
  144. snowflake/cli/_plugins/stage/diff.py +0 -280
  145. snowflake/cli/_plugins/stage/manager.py +0 -582
  146. snowflake/cli/_plugins/stage/md5.py +0 -160
  147. snowflake/cli/_plugins/stage/plugin_spec.py +0 -30
  148. snowflake/cli/_plugins/stage/utils.py +0 -54
  149. snowflake/cli/_plugins/streamlit/__init__.py +0 -13
  150. snowflake/cli/_plugins/streamlit/commands.py +0 -195
  151. snowflake/cli/_plugins/streamlit/manager.py +0 -220
  152. snowflake/cli/_plugins/streamlit/plugin_spec.py +0 -30
  153. snowflake/cli/_plugins/streamlit/streamlit_entity.py +0 -12
  154. snowflake/cli/_plugins/streamlit/streamlit_entity_model.py +0 -66
  155. snowflake/cli/_plugins/workspace/__init__.py +0 -13
  156. snowflake/cli/_plugins/workspace/action_context.py +0 -18
  157. snowflake/cli/_plugins/workspace/commands.py +0 -306
  158. snowflake/cli/_plugins/workspace/manager.py +0 -74
  159. snowflake/cli/_plugins/workspace/plugin_spec.py +0 -30
  160. snowflake/cli/api/__init__.py +0 -48
  161. snowflake/cli/api/cli_global_context.py +0 -247
  162. snowflake/cli/api/commands/__init__.py +0 -13
  163. snowflake/cli/api/commands/alias.py +0 -23
  164. snowflake/cli/api/commands/common.py +0 -25
  165. snowflake/cli/api/commands/decorators.py +0 -369
  166. snowflake/cli/api/commands/execution_metadata.py +0 -40
  167. snowflake/cli/api/commands/experimental_behaviour.py +0 -18
  168. snowflake/cli/api/commands/flags.py +0 -561
  169. snowflake/cli/api/commands/overrideable_parameter.py +0 -143
  170. snowflake/cli/api/commands/snow_typer.py +0 -247
  171. snowflake/cli/api/commands/utils.py +0 -18
  172. snowflake/cli/api/config.py +0 -380
  173. snowflake/cli/api/connections.py +0 -216
  174. snowflake/cli/api/console/__init__.py +0 -17
  175. snowflake/cli/api/console/abc.py +0 -94
  176. snowflake/cli/api/console/console.py +0 -134
  177. snowflake/cli/api/console/enum.py +0 -17
  178. snowflake/cli/api/constants.py +0 -90
  179. snowflake/cli/api/entities/common.py +0 -56
  180. snowflake/cli/api/entities/utils.py +0 -370
  181. snowflake/cli/api/errno.py +0 -28
  182. snowflake/cli/api/exceptions.py +0 -190
  183. snowflake/cli/api/feature_flags.py +0 -54
  184. snowflake/cli/api/identifiers.py +0 -190
  185. snowflake/cli/api/metrics.py +0 -92
  186. snowflake/cli/api/output/__init__.py +0 -13
  187. snowflake/cli/api/output/formats.py +0 -20
  188. snowflake/cli/api/output/types.py +0 -118
  189. snowflake/cli/api/plugins/__init__.py +0 -13
  190. snowflake/cli/api/plugins/command/__init__.py +0 -72
  191. snowflake/cli/api/plugins/command/plugin_hook_specs.py +0 -21
  192. snowflake/cli/api/plugins/plugin_config.py +0 -32
  193. snowflake/cli/api/project/__init__.py +0 -13
  194. snowflake/cli/api/project/definition.py +0 -126
  195. snowflake/cli/api/project/definition_conversion.py +0 -395
  196. snowflake/cli/api/project/definition_manager.py +0 -145
  197. snowflake/cli/api/project/errors.py +0 -56
  198. snowflake/cli/api/project/project_verification.py +0 -23
  199. snowflake/cli/api/project/schemas/__init__.py +0 -13
  200. snowflake/cli/api/project/schemas/entities/__init__.py +0 -13
  201. snowflake/cli/api/project/schemas/entities/common.py +0 -153
  202. snowflake/cli/api/project/schemas/entities/entities.py +0 -61
  203. snowflake/cli/api/project/schemas/project_definition.py +0 -330
  204. snowflake/cli/api/project/schemas/template.py +0 -77
  205. snowflake/cli/api/project/schemas/updatable_model.py +0 -202
  206. snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
  207. snowflake/cli/api/project/schemas/v1/identifier_model.py +0 -51
  208. snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
  209. snowflake/cli/api/project/schemas/v1/native_app/application.py +0 -61
  210. snowflake/cli/api/project/schemas/v1/native_app/native_app.py +0 -93
  211. snowflake/cli/api/project/schemas/v1/native_app/package.py +0 -84
  212. snowflake/cli/api/project/schemas/v1/native_app/path_mapping.py +0 -65
  213. snowflake/cli/api/project/schemas/v1/snowpark/__init__.py +0 -0
  214. snowflake/cli/api/project/schemas/v1/snowpark/argument.py +0 -28
  215. snowflake/cli/api/project/schemas/v1/snowpark/callable.py +0 -69
  216. snowflake/cli/api/project/schemas/v1/snowpark/snowpark.py +0 -36
  217. snowflake/cli/api/project/schemas/v1/streamlit/__init__.py +0 -0
  218. snowflake/cli/api/project/schemas/v1/streamlit/streamlit.py +0 -47
  219. snowflake/cli/api/project/util.py +0 -278
  220. snowflake/cli/api/rendering/__init__.py +0 -13
  221. snowflake/cli/api/rendering/jinja.py +0 -118
  222. snowflake/cli/api/rendering/project_definition_templates.py +0 -43
  223. snowflake/cli/api/rendering/project_templates.py +0 -98
  224. snowflake/cli/api/rendering/sql_templates.py +0 -105
  225. snowflake/cli/api/rest_api.py +0 -178
  226. snowflake/cli/api/sanitizers.py +0 -43
  227. snowflake/cli/api/secure_path.py +0 -360
  228. snowflake/cli/api/secure_utils.py +0 -118
  229. snowflake/cli/api/sql_execution.py +0 -280
  230. snowflake/cli/api/utils/__init__.py +0 -13
  231. snowflake/cli/api/utils/cursor.py +0 -34
  232. snowflake/cli/api/utils/definition_rendering.py +0 -415
  233. snowflake/cli/api/utils/dict_utils.py +0 -73
  234. snowflake/cli/api/utils/error_handling.py +0 -23
  235. snowflake/cli/api/utils/graph.py +0 -97
  236. snowflake/cli/api/utils/models.py +0 -63
  237. snowflake/cli/api/utils/naming_utils.py +0 -13
  238. snowflake/cli/api/utils/path_utils.py +0 -36
  239. snowflake/cli/api/utils/templating_functions.py +0 -144
  240. snowflake/cli/api/utils/types.py +0 -35
  241. snowflake_cli_labs-3.0.0rc4.dist-info/RECORD +0 -242
  242. snowflake_cli_labs-3.0.0rc4.dist-info/entry_points.txt +0 -2
  243. {snowflake_cli_labs-3.0.0rc4.dist-info → snowflake_cli_labs-3.0.1.dist-info}/WHEEL +0 -0
  244. {snowflake_cli_labs-3.0.0rc4.dist-info → snowflake_cli_labs-3.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,72 +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 dataclasses import dataclass
18
- from enum import Enum
19
- from functools import cached_property
20
- from typing import List
21
-
22
- import click
23
- import pluggy
24
- from typer import Typer
25
- from typer.main import get_command
26
-
27
- SNOWCLI_COMMAND_PLUGIN_NAMESPACE = "snowflake.cli.plugin.command"
28
-
29
- plugin_hook_spec = pluggy.HookspecMarker(SNOWCLI_COMMAND_PLUGIN_NAMESPACE)
30
- plugin_hook_impl = pluggy.HookimplMarker(SNOWCLI_COMMAND_PLUGIN_NAMESPACE)
31
-
32
-
33
- class CommandPath:
34
- def __init__(self, path_segments: List[str]):
35
- self._path_segments = tuple(path_segments)
36
-
37
- @property
38
- def path_segments(self) -> List[str]:
39
- return list(self._path_segments)
40
-
41
- def __hash__(self):
42
- return hash(self._path_segments)
43
-
44
- def __eq__(self, other):
45
- return self._path_segments == other._path_segments
46
-
47
- def __str__(self) -> str:
48
- return "snow " + " ".join(self.path_segments)
49
-
50
-
51
- SNOWCLI_ROOT_COMMAND_PATH = CommandPath(path_segments=[])
52
-
53
-
54
- class CommandType(Enum):
55
- SINGLE_COMMAND = "SINGLE_COMMAND"
56
- COMMAND_GROUP = "COMMAND_GROUP"
57
-
58
-
59
- @dataclass(frozen=True)
60
- class CommandSpec:
61
- parent_command_path: CommandPath
62
- command_type: CommandType
63
- typer_instance: Typer
64
-
65
- @cached_property
66
- def command(self) -> click.Command:
67
- self.typer_instance._add_completion = False # noqa: SLF001
68
- return get_command(self.typer_instance)
69
-
70
- @cached_property
71
- def full_command_path(self) -> CommandPath:
72
- return CommandPath(self.parent_command_path.path_segments + [self.command.name])
@@ -1,21 +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 plugin_hook_spec
16
-
17
-
18
- @plugin_hook_spec
19
- def command_spec():
20
- """Command spec"""
21
- pass
@@ -1,32 +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 dataclasses import dataclass
18
- from typing import Any, Dict, List
19
-
20
-
21
- @dataclass
22
- class PluginConfig:
23
- is_plugin_enabled: bool
24
- internal_config: Dict[str, Any]
25
-
26
-
27
- class PluginConfigProvider:
28
- def get_enabled_plugin_names(self) -> List[str]:
29
- raise NotImplementedError()
30
-
31
- def get_config(self, plugin_name: str) -> PluginConfig:
32
- raise NotImplementedError()
@@ -1,13 +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.
@@ -1,126 +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 typing import List, Optional
19
-
20
- import yaml
21
- from click import ClickException
22
- from snowflake.cli.api.cli_global_context import get_cli_context
23
- from snowflake.cli.api.constants import DEFAULT_SIZE_LIMIT_MB
24
- from snowflake.cli.api.project.schemas.project_definition import (
25
- ProjectProperties,
26
- YamlOverride,
27
- )
28
- from snowflake.cli.api.project.util import (
29
- append_to_identifier,
30
- get_env_username,
31
- sanitize_identifier,
32
- to_identifier,
33
- )
34
- from snowflake.cli.api.secure_path import SecurePath
35
- from snowflake.cli.api.utils.definition_rendering import (
36
- raw_project_properties,
37
- render_definition_template,
38
- )
39
- from snowflake.cli.api.utils.dict_utils import deep_merge_dicts
40
- from snowflake.cli.api.utils.types import Context, Definition
41
- from yaml import MappingNode, SequenceNode
42
-
43
- DEFAULT_USERNAME = "unknown_user"
44
-
45
-
46
- def _get_merged_definitions(paths: List[Path]) -> Optional[Definition]:
47
- spaths: List[SecurePath] = [SecurePath(p) for p in paths]
48
- if len(spaths) == 0:
49
- return None
50
-
51
- loader = yaml.BaseLoader
52
- loader.add_constructor(
53
- yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, _no_duplicates_constructor
54
- )
55
- loader.add_constructor("!override", _override_tag)
56
-
57
- with spaths[0].open("r", read_file_limit_mb=DEFAULT_SIZE_LIMIT_MB) as base_yml:
58
- definition = yaml.load(base_yml.read(), Loader=loader) or {}
59
-
60
- for override_path in spaths[1:]:
61
- with override_path.open(
62
- "r", read_file_limit_mb=DEFAULT_SIZE_LIMIT_MB
63
- ) as override_yml:
64
- overrides = (
65
- yaml.load(override_yml.read(), Loader=yaml.loader.BaseLoader) or {}
66
- )
67
- deep_merge_dicts(definition, overrides)
68
-
69
- return definition
70
-
71
-
72
- def load_project(
73
- paths: List[Path],
74
- context_overrides: Optional[Context] = None,
75
- render_templates: bool = True,
76
- ) -> ProjectProperties:
77
- """
78
- Loads project definition, optionally overriding values. Definition values
79
- are merged in left-to-right order (increasing precedence).
80
- Templating is also applied after the merging process.
81
- """
82
- merged_definitions = _get_merged_definitions(paths)
83
- if render_templates:
84
- return render_definition_template(merged_definitions, context_overrides or {})
85
- else:
86
- return raw_project_properties(merged_definitions)
87
-
88
-
89
- def default_app_package(project_name: str):
90
- user = sanitize_identifier(get_env_username() or DEFAULT_USERNAME).lower()
91
- return append_to_identifier(to_identifier(project_name), f"_pkg_{user}")
92
-
93
-
94
- def default_role():
95
- conn = get_cli_context().connection
96
- return conn.role
97
-
98
-
99
- def default_application(project_name: str):
100
- user = sanitize_identifier(get_env_username() or DEFAULT_USERNAME).lower()
101
- return append_to_identifier(to_identifier(project_name), f"_{user}")
102
-
103
-
104
- def _no_duplicates_constructor(loader, node, deep=False):
105
- """
106
- Raises error it there are duplicated keys on the same level in the yaml file
107
- """
108
- mapping = {}
109
-
110
- for key_node, value_node in node.value:
111
- key = loader.construct_object(key_node, deep=deep)
112
- value = loader.construct_object(value_node, deep=deep)
113
- if key in mapping.keys():
114
- raise ClickException(
115
- f"While loading the project definition file, duplicate key was found: {key}"
116
- )
117
- mapping[key] = value
118
- return loader.construct_mapping(node, deep)
119
-
120
-
121
- def _override_tag(loader, node, deep=False):
122
- if isinstance(node, SequenceNode):
123
- return YamlOverride(data=loader.construct_sequence(node, deep))
124
- if isinstance(node, MappingNode):
125
- return YamlOverride(data=loader.construct_mapping(node, deep))
126
- return node.value
@@ -1,395 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import logging
4
- from pathlib import Path
5
- from typing import Any, Dict, Literal, Optional
6
-
7
- from click import ClickException
8
- from snowflake.cli._plugins.nativeapp.artifacts import (
9
- build_bundle,
10
- )
11
- from snowflake.cli._plugins.snowpark.common import is_name_a_templated_one
12
- from snowflake.cli.api.constants import (
13
- DEFAULT_ENV_FILE,
14
- DEFAULT_PAGES_DIR,
15
- PROJECT_TEMPLATE_VARIABLE_CLOSING,
16
- PROJECT_TEMPLATE_VARIABLE_OPENING,
17
- SNOWPARK_SHARED_MIXIN,
18
- )
19
- from snowflake.cli.api.entities.utils import render_script_template
20
- from snowflake.cli.api.project.schemas.entities.common import (
21
- SqlScriptHookType,
22
- )
23
- from snowflake.cli.api.project.schemas.project_definition import (
24
- ProjectDefinition,
25
- ProjectDefinitionV2,
26
- )
27
- from snowflake.cli.api.project.schemas.v1.native_app.application import (
28
- Application,
29
- ApplicationV11,
30
- )
31
- from snowflake.cli.api.project.schemas.v1.native_app.native_app import NativeApp
32
- from snowflake.cli.api.project.schemas.v1.native_app.package import Package, PackageV11
33
- from snowflake.cli.api.project.schemas.v1.snowpark.callable import (
34
- FunctionSchema,
35
- ProcedureSchema,
36
- )
37
- from snowflake.cli.api.project.schemas.v1.snowpark.snowpark import Snowpark
38
- from snowflake.cli.api.project.schemas.v1.streamlit.streamlit import Streamlit
39
- from snowflake.cli.api.rendering.jinja import get_basic_jinja_env
40
-
41
- log = logging.getLogger(__name__)
42
-
43
-
44
- def _is_field_defined(template_context: Optional[Dict[str, Any]], *path: str) -> bool:
45
- """
46
- Determines if a field is defined in the provided template context. For example,
47
-
48
- _is_field_defined({"ctx": {"native_app": {"bundle_root": "my_root"}}}, "ctx", "native_app", "bundle_root")
49
-
50
- returns True. If the provided template context is None, this function returns True for all paths.
51
-
52
- """
53
- if template_context is None:
54
- return True # No context, so assume that all variables are defined
55
-
56
- current_dict = template_context
57
- for key in path:
58
- if not isinstance(current_dict, dict):
59
- return False
60
- if key not in current_dict:
61
- return False
62
- current_dict = current_dict[key]
63
-
64
- return True
65
-
66
-
67
- def convert_project_definition_to_v2(
68
- project_root: Path,
69
- pd: ProjectDefinition,
70
- accept_templates: bool = False,
71
- template_context: Optional[Dict[str, Any]] = None,
72
- ) -> ProjectDefinitionV2:
73
- _check_if_project_definition_meets_requirements(pd, accept_templates)
74
-
75
- snowpark_data = convert_snowpark_to_v2_data(pd.snowpark) if pd.snowpark else {}
76
- streamlit_data = convert_streamlit_to_v2_data(pd.streamlit) if pd.streamlit else {}
77
- native_app_data = (
78
- convert_native_app_to_v2_data(project_root, pd.native_app, template_context)
79
- if pd.native_app
80
- else {}
81
- )
82
- envs = convert_envs_to_v2(pd)
83
-
84
- data = {
85
- "definition_version": "2",
86
- "entities": get_list_of_all_entities(
87
- snowpark_data.get("entities", {}),
88
- streamlit_data.get("entities", {}),
89
- native_app_data.get("entities", {}),
90
- ),
91
- "mixins": snowpark_data.get("mixins", None),
92
- "env": envs,
93
- }
94
-
95
- return ProjectDefinitionV2(**data)
96
-
97
-
98
- def convert_snowpark_to_v2_data(snowpark: Snowpark) -> Dict[str, Any]:
99
- artifact_mapping = {"src": snowpark.src}
100
- if snowpark.project_name:
101
- artifact_mapping["dest"] = snowpark.project_name
102
-
103
- data: dict = {
104
- "mixins": {
105
- SNOWPARK_SHARED_MIXIN: {
106
- "stage": snowpark.stage_name,
107
- "artifacts": [artifact_mapping],
108
- }
109
- },
110
- "entities": {},
111
- }
112
-
113
- for index, entity in enumerate([*snowpark.procedures, *snowpark.functions]):
114
- identifier = {"name": entity.name}
115
- if entity.database is not None:
116
- identifier["database"] = entity.database
117
- if entity.schema_name is not None:
118
- identifier["schema"] = entity.schema_name
119
-
120
- entity_name = (
121
- f"snowpark_entity_{index}"
122
- if is_name_a_templated_one(entity.name)
123
- else entity.name
124
- )
125
-
126
- if entity_name in data["entities"]:
127
- raise ClickException(
128
- f"Entity with name {entity_name} seems to be duplicated. Please rename it and try again."
129
- )
130
-
131
- v2_entity = {
132
- "type": "function" if isinstance(entity, FunctionSchema) else "procedure",
133
- "stage": snowpark.stage_name,
134
- "handler": entity.handler,
135
- "returns": entity.returns,
136
- "signature": entity.signature,
137
- "runtime": entity.runtime,
138
- "external_access_integrations": entity.external_access_integrations,
139
- "secrets": entity.secrets,
140
- "imports": entity.imports,
141
- "identifier": identifier,
142
- "meta": {"use_mixins": [SNOWPARK_SHARED_MIXIN]},
143
- }
144
- if isinstance(entity, ProcedureSchema):
145
- v2_entity["execute_as_caller"] = entity.execute_as_caller
146
-
147
- data["entities"][entity_name] = v2_entity
148
-
149
- return data
150
-
151
-
152
- def convert_streamlit_to_v2_data(streamlit: Streamlit) -> Dict[str, Any]:
153
- # Process env file and pages dir
154
- environment_file = _process_streamlit_files(streamlit.env_file, "environment")
155
- pages_dir = _process_streamlit_files(streamlit.pages_dir, "pages")
156
-
157
- # Build V2 definition
158
- artifacts = [
159
- streamlit.main_file,
160
- environment_file,
161
- pages_dir,
162
- ]
163
- artifacts = [a for a in artifacts if a is not None]
164
-
165
- if streamlit.additional_source_files:
166
- artifacts.extend(streamlit.additional_source_files)
167
-
168
- identifier = {"name": streamlit.name}
169
- if streamlit.schema_name:
170
- identifier["schema"] = streamlit.schema_name
171
- if streamlit.database:
172
- identifier["database"] = streamlit.database
173
-
174
- streamlit_name = (
175
- "streamlit_entity_1"
176
- if is_name_a_templated_one(streamlit.name)
177
- else streamlit.name
178
- )
179
-
180
- data = {
181
- "entities": {
182
- streamlit_name: {
183
- "type": "streamlit",
184
- "identifier": identifier,
185
- "title": streamlit.title,
186
- "comment": streamlit.comment,
187
- "query_warehouse": streamlit.query_warehouse,
188
- "main_file": str(streamlit.main_file),
189
- "pages_dir": str(streamlit.pages_dir),
190
- "stage": streamlit.stage,
191
- "artifacts": artifacts,
192
- }
193
- }
194
- }
195
- return data
196
-
197
-
198
- def convert_native_app_to_v2_data(
199
- project_root,
200
- native_app: NativeApp,
201
- template_context: Optional[Dict[str, Any]] = None,
202
- ) -> Dict[str, Any]:
203
- def _make_meta(obj: Application | Package):
204
- meta = {}
205
- if obj.role:
206
- meta["role"] = obj.role
207
- if obj.warehouse:
208
- meta["warehouse"] = obj.warehouse
209
- if obj.post_deploy:
210
- meta["post_deploy"] = obj.post_deploy
211
- return meta
212
-
213
- def _find_manifest():
214
- # We don't know which file in the project directory is the actual manifest,
215
- # and we can't iterate through the artifacts property since the src can contain
216
- # glob patterns. The simplest solution is to bundle the app and find the
217
- # manifest file from the resultant BundleMap, since the bundle process ensures
218
- # that only a single source path can map to the corresponding destination path
219
- try:
220
- bundle_map = build_bundle(
221
- project_root, Path(native_app.deploy_root), native_app.artifacts
222
- )
223
- except Exception as e:
224
- # The manifest field is required, so we can't gracefully handle bundle failures
225
- raise ClickException(
226
- f"{e}\nCould not bundle Native App artifacts, unable to perform migration"
227
- ) from e
228
-
229
- manifest_path = bundle_map.to_project_path(Path("manifest.yml"))
230
- if not manifest_path:
231
- # The manifest field is required, so we can't gracefully handle it being missing
232
- raise ClickException(
233
- "manifest.yml file not found in any Native App artifact sources, "
234
- "unable to perform migration"
235
- )
236
-
237
- # Use a POSIX path to be consistent with other migrated fields
238
- # which use POSIX paths as default values
239
- return manifest_path.as_posix()
240
-
241
- def _make_template(template: str) -> str:
242
- return f"{PROJECT_TEMPLATE_VARIABLE_OPENING} {template} {PROJECT_TEMPLATE_VARIABLE_CLOSING}"
243
-
244
- def _convert_package_script_files(package_scripts: list[str]):
245
- # PDFv2 doesn't support package scripts, only post-deploy scripts, so we
246
- # need to convert the Jinja syntax from {{ }} to <% %>
247
- # Luckily, package scripts only support {{ package_name }}, so let's convert that tag
248
- # to v2 template syntax by running it though the template process with a fake
249
- # package name that's actually a valid v2 template, which will be evaluated
250
- # when the script is used as a post-deploy script
251
- fake_package_replacement_template = _make_template(
252
- f"ctx.entities.{package_entity_name}.identifier"
253
- )
254
- jinja_context = dict(package_name=fake_package_replacement_template)
255
- post_deploy_hooks = []
256
- for script_file in package_scripts:
257
- new_contents = render_script_template(
258
- project_root, jinja_context, script_file, get_basic_jinja_env()
259
- )
260
- (project_root / script_file).write_text(new_contents)
261
- post_deploy_hooks.append(SqlScriptHookType(sql_script=script_file))
262
- return post_deploy_hooks
263
-
264
- package_entity_name = "pkg"
265
- if (
266
- native_app.package
267
- and native_app.package.name
268
- and native_app.package.name != PackageV11.model_fields["name"].default
269
- ):
270
- package_identifier = native_app.package.name
271
- else:
272
- # Backport the PackageV11 default name template, updated for PDFv2
273
- package_identifier = _make_template(
274
- f"fn.concat_ids('{native_app.name}', '_pkg_', fn.sanitize_id(fn.get_username('unknown_user')) | lower)"
275
- )
276
- package = {
277
- "type": "application package",
278
- "identifier": package_identifier,
279
- "manifest": _find_manifest(),
280
- "artifacts": native_app.artifacts,
281
- }
282
-
283
- if _is_field_defined(template_context, "ctx", "native_app", "bundle_root"):
284
- package["bundle_root"] = native_app.bundle_root
285
- if _is_field_defined(template_context, "ctx", "native_app", "generated_root"):
286
- package["generated_root"] = native_app.generated_root
287
- if _is_field_defined(template_context, "ctx", "native_app", "deploy_root"):
288
- package["deploy_root"] = native_app.deploy_root
289
- if _is_field_defined(template_context, "ctx", "native_app", "source_stage"):
290
- package["stage"] = native_app.source_stage
291
- if _is_field_defined(template_context, "ctx", "native_app", "scratch_stage"):
292
- package["scratch_stage"] = native_app.scratch_stage
293
-
294
- if native_app.package:
295
- if _is_field_defined(
296
- template_context, "ctx", "native_app", "package", "distribution"
297
- ):
298
- package["distribution"] = native_app.package.distribution
299
- package_meta = _make_meta(native_app.package)
300
- if native_app.package.scripts:
301
- converted_post_deploy_hooks = _convert_package_script_files(
302
- native_app.package.scripts
303
- )
304
- package_meta["post_deploy"] = (
305
- package_meta.get("post_deploy", []) + converted_post_deploy_hooks
306
- )
307
- if package_meta:
308
- package["meta"] = package_meta
309
-
310
- app_entity_name = "app"
311
- if (
312
- native_app.application
313
- and native_app.application.name
314
- and native_app.application.name != ApplicationV11.model_fields["name"].default
315
- ):
316
- app_identifier = native_app.application.name
317
- else:
318
- # Backport the ApplicationV11 default name template, updated for PDFv2
319
- app_identifier = _make_template(
320
- f"fn.concat_ids('{native_app.name}', '_', fn.sanitize_id(fn.get_username('unknown_user')) | lower)"
321
- )
322
- app = {
323
- "type": "application",
324
- "identifier": app_identifier,
325
- "from": {"target": package_entity_name},
326
- }
327
- if native_app.application:
328
- if app_meta := _make_meta(native_app.application):
329
- app["meta"] = app_meta
330
- if _is_field_defined(
331
- template_context, "ctx", "native_app", "application", "debug"
332
- ):
333
- app["debug"] = native_app.application.debug
334
-
335
- return {
336
- "entities": {
337
- package_entity_name: package,
338
- app_entity_name: app,
339
- }
340
- }
341
-
342
-
343
- def convert_envs_to_v2(pd: ProjectDefinition):
344
- if hasattr(pd, "env") and pd.env:
345
- data = {k: v for k, v in pd.env.items()}
346
- return data
347
- return None
348
-
349
-
350
- def _check_if_project_definition_meets_requirements(
351
- pd: ProjectDefinition, accept_templates: bool
352
- ):
353
- if pd.meets_version_requirement("2"):
354
- raise ClickException("Project definition is already at version 2.")
355
-
356
- if PROJECT_TEMPLATE_VARIABLE_OPENING in str(pd):
357
- if not accept_templates:
358
- raise ClickException(
359
- "Project definition contains templates. They may not be migrated correctly, and require manual migration."
360
- "You can try again with --accept-templates option, to attempt automatic migration."
361
- )
362
- log.warning(
363
- "Your V1 definition contains templates. We cannot guarantee the correctness of the migration."
364
- )
365
-
366
-
367
- def _process_streamlit_files(
368
- file_name: Optional[str], file_type: Literal["pages", "environment"]
369
- ):
370
- default = DEFAULT_PAGES_DIR if file_type == "pages" else DEFAULT_ENV_FILE
371
-
372
- if file_name and not Path(file_name).exists():
373
- raise ClickException(f"Provided file {file_name} does not exist")
374
- elif file_name is None and Path(default).exists():
375
- file_name = default
376
- return file_name
377
-
378
-
379
- def get_list_of_all_entities(
380
- snowpark_entities: Dict[str, Any],
381
- streamlit_entities: Dict[str, Any],
382
- native_app_entities: Dict[str, Any],
383
- ):
384
- # Check all combinations of entity types for overlapping names
385
- # (No need to use itertools here, PDFv1 only supports these three types)
386
- for types, first, second in [
387
- ("streamlit and snowpark", streamlit_entities, snowpark_entities),
388
- ("streamlit and native app", streamlit_entities, native_app_entities),
389
- ("native app and snowpark", native_app_entities, snowpark_entities),
390
- ]:
391
- if first.keys() & second.keys():
392
- raise ClickException(
393
- f"In your project, {types} entities share the same name. Please rename them and try again."
394
- )
395
- return snowpark_entities | streamlit_entities | native_app_entities