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,99 +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
- import sys
18
- from typing import TextIO
19
-
20
- from click import ClickException
21
- from snowflake.cli.api.constants import ObjectType
22
- from snowflake.cli.api.exceptions import ObjectAlreadyExistsError
23
- from snowflake.cli.api.project.util import unquote_identifier
24
- from snowflake.connector.errors import ProgrammingError
25
-
26
- if not sys.stdout.closed and sys.stdout.isatty():
27
- GREEN = "\033[32m"
28
- BLUE = "\033[34m"
29
- ORANGE = "\033[38:2:238:76:44m"
30
- GRAY = "\033[2m"
31
- ENDC = "\033[0m"
32
- else:
33
- GREEN = ""
34
- ORANGE = ""
35
- BLUE = ""
36
- GRAY = ""
37
- ENDC = ""
38
-
39
-
40
- def _prefix_line(prefix: str, line: str) -> str:
41
- """
42
- _prefix_line ensure the prefix is still present even when dealing with return characters
43
- """
44
- if "\r" in line:
45
- line = line.replace("\r", f"\r{prefix}")
46
- if "\n" in line[:-1]:
47
- line = line[:-1].replace("\n", f"\n{prefix}") + line[-1:]
48
- if not line.startswith("\r"):
49
- line = f"{prefix}{line}"
50
- return line
51
-
52
-
53
- def print_log_lines(file: TextIO, name, identifier, logs):
54
- prefix = f"{GREEN}{name}/{identifier}{ENDC} "
55
- logs = logs[0:-1]
56
- for log in logs:
57
- print(_prefix_line(prefix, log + "\n"), file=file, end="", flush=True)
58
-
59
-
60
- def strip_empty_lines(lines: list[str]) -> str:
61
- return "\n".join(stripped for l in lines if (stripped := l.strip()))
62
-
63
-
64
- def validate_and_set_instances(min_instances, max_instances, instance_name):
65
- """
66
- Used to validate that min_instances is positive and that max_instances is not less than min_instances. In the
67
- case that max_instances is none, sets it equal to min_instances by default. Used like `max_instances =
68
- validate_and_set_instances(min_instances, max_instances, "name")`.
69
- """
70
- if min_instances < 1:
71
- raise ClickException(f"min_{instance_name} must be positive")
72
-
73
- if max_instances is None:
74
- max_instances = min_instances
75
- elif max_instances < min_instances:
76
- raise ClickException(
77
- f"max_{instance_name} must be greater or equal to min_{instance_name}"
78
- )
79
- return max_instances
80
-
81
-
82
- def handle_object_already_exists(
83
- error: ProgrammingError,
84
- object_type: ObjectType,
85
- object_name: str,
86
- replace_available: bool = False,
87
- ):
88
- if error.errno == 2002:
89
- raise ObjectAlreadyExistsError(
90
- object_type=object_type,
91
- name=unquote_identifier(object_name),
92
- replace_available=replace_available,
93
- )
94
- else:
95
- raise error
96
-
97
-
98
- class NoPropertiesProvidedError(ClickException):
99
- pass
@@ -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,240 +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 typing import Optional
18
-
19
- import typer
20
- from click import ClickException
21
- from snowflake.cli.api.commands.flags import (
22
- IfNotExistsOption,
23
- OverrideableOption,
24
- like_option,
25
- )
26
- from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
27
- from snowflake.cli.api.constants import ObjectType
28
- from snowflake.cli.api.output.types import CommandResult, SingleQueryResult
29
- from snowflake.cli.api.project.util import is_valid_object_name
30
- from snowflake.cli.plugins.object.command_aliases import (
31
- add_object_command_aliases,
32
- )
33
- from snowflake.cli.plugins.object.common import CommentOption
34
- from snowflake.cli.plugins.spcs.common import (
35
- validate_and_set_instances,
36
- )
37
- from snowflake.cli.plugins.spcs.compute_pool.manager import ComputePoolManager
38
-
39
- app = SnowTyperFactory(
40
- name="compute-pool",
41
- help="Manages Snowpark Container Services compute pools.",
42
- short_help="Manages compute pools.",
43
- )
44
-
45
-
46
- def _compute_pool_name_callback(name: str) -> str:
47
- """
48
- Verifies that compute pool name is a single valid identifier.
49
- """
50
- if not is_valid_object_name(name, max_depth=0, allow_quoted=False):
51
- raise ClickException(
52
- f"'{name}' is not a valid compute pool name. Note that compute pool names must be unquoted identifiers."
53
- )
54
- return name
55
-
56
-
57
- ComputePoolNameArgument = typer.Argument(
58
- ...,
59
- help="Name of the compute pool.",
60
- callback=_compute_pool_name_callback,
61
- show_default=False,
62
- )
63
-
64
-
65
- MinNodesOption = OverrideableOption(
66
- 1,
67
- "--min-nodes",
68
- help="Minimum number of nodes for the compute pool.",
69
- min=1,
70
- )
71
- MaxNodesOption = OverrideableOption(
72
- None,
73
- "--max-nodes",
74
- help="Maximum number of nodes for the compute pool.",
75
- min=1,
76
- )
77
-
78
- _AUTO_RESUME_HELP = "The compute pool will automatically resume when a service or job is submitted to it."
79
-
80
- AutoResumeOption = OverrideableOption(
81
- True,
82
- "--auto-resume/--no-auto-resume",
83
- help=_AUTO_RESUME_HELP,
84
- )
85
-
86
- _AUTO_SUSPEND_SECS_HELP = "Number of seconds of inactivity after which you want Snowflake to automatically suspend the compute pool."
87
- AutoSuspendSecsOption = OverrideableOption(
88
- 3600,
89
- "--auto-suspend-secs",
90
- help=_AUTO_SUSPEND_SECS_HELP,
91
- min=1,
92
- )
93
-
94
- _COMMENT_HELP = "Comment for the compute pool."
95
-
96
- add_object_command_aliases(
97
- app=app,
98
- object_type=ObjectType.COMPUTE_POOL,
99
- name_argument=ComputePoolNameArgument,
100
- like_option=like_option(
101
- help_example='`list --like "my%"` lists all compute pools that begin with “my”.'
102
- ),
103
- scope_option=None,
104
- )
105
-
106
-
107
- @app.command(requires_connection=True)
108
- def create(
109
- name: str = ComputePoolNameArgument,
110
- instance_family: str = typer.Option(
111
- ...,
112
- "--family",
113
- help="Name of the instance family. For more information about instance families, refer to the SQL CREATE COMPUTE POOL command.",
114
- show_default=False,
115
- ),
116
- min_nodes: int = MinNodesOption(),
117
- max_nodes: Optional[int] = MaxNodesOption(),
118
- auto_resume: bool = AutoResumeOption(),
119
- initially_suspended: bool = typer.Option(
120
- False,
121
- "--init-suspend/--no-init-suspend",
122
- help="Starts the compute pool in a suspended state.",
123
- ),
124
- auto_suspend_secs: int = AutoSuspendSecsOption(),
125
- comment: Optional[str] = CommentOption(help=_COMMENT_HELP),
126
- if_not_exists: bool = IfNotExistsOption(),
127
- **options,
128
- ) -> CommandResult:
129
- """
130
- Creates a new compute pool.
131
- """
132
- max_nodes = validate_and_set_instances(min_nodes, max_nodes, "nodes")
133
- cursor = ComputePoolManager().create(
134
- pool_name=name,
135
- min_nodes=min_nodes,
136
- max_nodes=max_nodes,
137
- instance_family=instance_family,
138
- auto_resume=auto_resume,
139
- initially_suspended=initially_suspended,
140
- auto_suspend_secs=auto_suspend_secs,
141
- comment=comment,
142
- if_not_exists=if_not_exists,
143
- )
144
- return SingleQueryResult(cursor)
145
-
146
-
147
- @app.command("stop-all", requires_connection=True)
148
- def stop_all(name: str = ComputePoolNameArgument, **options) -> CommandResult:
149
- """
150
- Deletes all services running on the compute pool.
151
- """
152
- cursor = ComputePoolManager().stop(pool_name=name)
153
- return SingleQueryResult(cursor)
154
-
155
-
156
- @app.command(requires_connection=True)
157
- def suspend(name: str = ComputePoolNameArgument, **options) -> CommandResult:
158
- """
159
- Suspends the compute pool by suspending all currently running services and then releasing compute pool nodes.
160
- """
161
- return SingleQueryResult(ComputePoolManager().suspend(name))
162
-
163
-
164
- @app.command(requires_connection=True)
165
- def resume(name: str = ComputePoolNameArgument, **options) -> CommandResult:
166
- """
167
- Resumes the compute pool from a SUSPENDED state.
168
- """
169
- return SingleQueryResult(ComputePoolManager().resume(name))
170
-
171
-
172
- @app.command("set", requires_connection=True)
173
- def set_property(
174
- name: str = ComputePoolNameArgument,
175
- min_nodes: Optional[int] = MinNodesOption(default=None, show_default=False),
176
- max_nodes: Optional[int] = MaxNodesOption(show_default=False),
177
- auto_resume: Optional[bool] = AutoResumeOption(default=None, show_default=False),
178
- auto_suspend_secs: Optional[int] = AutoSuspendSecsOption(
179
- default=None, show_default=False
180
- ),
181
- comment: Optional[str] = CommentOption(
182
- help="Comment for the compute pool.", show_default=False
183
- ),
184
- **options,
185
- ) -> CommandResult:
186
- """
187
- Sets one or more properties for the compute pool.
188
- """
189
- cursor = ComputePoolManager().set_property(
190
- pool_name=name,
191
- min_nodes=min_nodes,
192
- max_nodes=max_nodes,
193
- auto_resume=auto_resume,
194
- auto_suspend_secs=auto_suspend_secs,
195
- comment=comment,
196
- )
197
- return SingleQueryResult(cursor)
198
-
199
-
200
- @app.command("unset", requires_connection=True)
201
- def unset_property(
202
- name: str = ComputePoolNameArgument,
203
- auto_resume: bool = AutoResumeOption(
204
- default=False,
205
- param_decls=["--auto-resume"],
206
- help=f"Reset the AUTO_RESUME property - {_AUTO_RESUME_HELP}",
207
- show_default=False,
208
- ),
209
- auto_suspend_secs: bool = AutoSuspendSecsOption(
210
- default=False,
211
- help=f"Reset the AUTO_SUSPEND_SECS property - {_AUTO_SUSPEND_SECS_HELP}",
212
- show_default=False,
213
- ),
214
- comment: bool = CommentOption(
215
- default=False,
216
- help=f"Reset the COMMENT property - {_COMMENT_HELP}",
217
- callback=None,
218
- show_default=False,
219
- ),
220
- **options,
221
- ) -> CommandResult:
222
- """
223
- Resets one or more properties for the compute pool to their default value(s).
224
- """
225
- cursor = ComputePoolManager().unset_property(
226
- pool_name=name,
227
- auto_resume=auto_resume,
228
- auto_suspend_secs=auto_suspend_secs,
229
- comment=comment,
230
- )
231
- return SingleQueryResult(cursor)
232
-
233
-
234
- @app.command(requires_connection=True)
235
- def status(pool_name: str = ComputePoolNameArgument, **options) -> CommandResult:
236
- """
237
- Retrieves the status of a compute pool along with a relevant message, if one exists.
238
- """
239
- cursor = ComputePoolManager().status(pool_name=pool_name)
240
- return SingleQueryResult(cursor)
@@ -1,121 +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 typing import List, Optional
18
-
19
- from snowflake.cli.api.constants import ObjectType
20
- from snowflake.cli.api.sql_execution import SqlExecutionMixin
21
- from snowflake.cli.plugins.spcs.common import (
22
- NoPropertiesProvidedError,
23
- handle_object_already_exists,
24
- strip_empty_lines,
25
- )
26
- from snowflake.connector.cursor import SnowflakeCursor
27
- from snowflake.connector.errors import ProgrammingError
28
-
29
-
30
- class ComputePoolManager(SqlExecutionMixin):
31
- def create(
32
- self,
33
- pool_name: str,
34
- min_nodes: int,
35
- max_nodes: int,
36
- instance_family: str,
37
- auto_resume: bool,
38
- initially_suspended: bool,
39
- auto_suspend_secs: int,
40
- comment: Optional[str],
41
- if_not_exists: bool,
42
- ) -> SnowflakeCursor:
43
- create_statement = "CREATE COMPUTE POOL"
44
- if if_not_exists:
45
- create_statement = f"{create_statement} IF NOT EXISTS"
46
- query = f"""\
47
- {create_statement} {pool_name}
48
- MIN_NODES = {min_nodes}
49
- MAX_NODES = {max_nodes}
50
- INSTANCE_FAMILY = {instance_family}
51
- AUTO_RESUME = {auto_resume}
52
- INITIALLY_SUSPENDED = {initially_suspended}
53
- AUTO_SUSPEND_SECS = {auto_suspend_secs}
54
- """.splitlines()
55
- if comment:
56
- query.append(f"COMMENT = {comment}")
57
-
58
- try:
59
- return self._execute_query(strip_empty_lines(query))
60
- except ProgrammingError as e:
61
- handle_object_already_exists(e, ObjectType.COMPUTE_POOL, pool_name)
62
-
63
- def stop(self, pool_name: str) -> SnowflakeCursor:
64
- return self._execute_query(f"alter compute pool {pool_name} stop all")
65
-
66
- def suspend(self, pool_name: str) -> SnowflakeCursor:
67
- return self._execute_query(f"alter compute pool {pool_name} suspend")
68
-
69
- def resume(self, pool_name: str) -> SnowflakeCursor:
70
- return self._execute_query(f"alter compute pool {pool_name} resume")
71
-
72
- def set_property(
73
- self,
74
- pool_name: str,
75
- min_nodes: Optional[int],
76
- max_nodes: Optional[int],
77
- auto_resume: Optional[bool],
78
- auto_suspend_secs: Optional[int],
79
- comment: Optional[str],
80
- ) -> SnowflakeCursor:
81
- property_pairs = [
82
- ("min_nodes", min_nodes),
83
- ("max_nodes", max_nodes),
84
- ("auto_resume", auto_resume),
85
- ("auto_suspend_secs", auto_suspend_secs),
86
- ("comment", comment),
87
- ]
88
-
89
- # Check if all provided properties are set to None (no properties are being set)
90
- if all([value is None for property_name, value in property_pairs]):
91
- raise NoPropertiesProvidedError(
92
- f"No properties specified for compute pool '{pool_name}'. Please provide at least one property to set."
93
- )
94
- query: List[str] = [f"alter compute pool {pool_name} set"]
95
- for property_name, value in property_pairs:
96
- if value is not None:
97
- query.append(f"{property_name} = {value}")
98
- return self._execute_query(strip_empty_lines(query))
99
-
100
- def unset_property(
101
- self, pool_name: str, auto_resume: bool, auto_suspend_secs: bool, comment: bool
102
- ):
103
- property_pairs = [
104
- ("auto_resume", auto_resume),
105
- ("auto_suspend_secs", auto_suspend_secs),
106
- ("comment", comment),
107
- ]
108
-
109
- # Check if all properties provided are False (no properties are being unset)
110
- if not any([value for property_name, value in property_pairs]):
111
- raise NoPropertiesProvidedError(
112
- f"No properties specified for compute pool '{pool_name}'. Please provide at least one property to reset to its default value."
113
- )
114
- unset_list = [property_name for property_name, value in property_pairs if value]
115
- query = f"alter compute pool {pool_name} unset {','.join(unset_list)}"
116
- return self._execute_query(query)
117
-
118
- def status(self, pool_name: str):
119
- return self._execute_query(
120
- f"call system$get_compute_pool_status('{pool_name}')"
121
- )
@@ -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,65 +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.commands.snow_typer import SnowTyperFactory
16
- from snowflake.cli.api.output.types import MessageResult, ObjectResult
17
- from snowflake.cli.plugins.spcs.image_registry.manager import (
18
- RegistryManager,
19
- )
20
-
21
- app = SnowTyperFactory(
22
- name="image-registry",
23
- help="Manages Snowpark Container Services image registries.",
24
- short_help="Manages image registries.",
25
- )
26
-
27
-
28
- _TOKEN_EPILOG = """\
29
- Usage Example: snow spcs image-registry token --format JSON | docker login $(snow spcs image-registry url) -u 0sessiontoken --password-stdin
30
-
31
- See the following for how to use this command to authenticate with SSO:
32
- https://community.snowflake.com/s/article/Authenticating-with-Snowpark-Container-Services-Image-Repository-via-SSO-and-Token-with-Snow-CLI\
33
- """
34
-
35
-
36
- @app.command(requires_connection=True, epilog=_TOKEN_EPILOG)
37
- def token(**options) -> ObjectResult:
38
- """
39
- Retrieves a registry authentication token based on your current connection.
40
-
41
- Note that this token is specific to your current user and will not grant access to any repositories that your current user cannot access.
42
-
43
-
44
- """
45
- return ObjectResult(RegistryManager().get_token())
46
-
47
-
48
- @app.command(requires_connection=True)
49
- def url(**options) -> MessageResult:
50
- """
51
- Gets the image registry URL for the current account.
52
-
53
- Must be called from a role that can view at least one image repository in the image registry.
54
- """
55
- return MessageResult(RegistryManager().get_registry_url())
56
-
57
-
58
- @app.command(requires_connection=True)
59
- def login(**options) -> MessageResult:
60
- """
61
- Logs in to the account image registry with the current user's credentials through Docker.
62
-
63
- Must be called from a role that can view at least one image repository in the image registry.
64
- """
65
- return MessageResult(RegistryManager().docker_registry_login().strip())
@@ -1,105 +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
- import base64
16
- import json
17
- import re
18
- import subprocess
19
- from urllib.parse import urlparse
20
-
21
- import requests
22
- from click import ClickException
23
- from snowflake.cli.api.sql_execution import SqlExecutionMixin
24
- from snowflake.connector.cursor import DictCursor
25
-
26
-
27
- class NoImageRepositoriesFoundError(ClickException):
28
- def __init__(self):
29
- super().__init__(
30
- f"No image repository found. To run this command, please switch to a role with read access to at least one image repository or create a new image repository first."
31
- )
32
-
33
-
34
- class RegistryManager(SqlExecutionMixin):
35
- def get_token(self):
36
- """
37
- Get token to authenticate with registry.
38
- """
39
- self._execute_query(
40
- "alter session set PYTHON_CONNECTOR_QUERY_RESULT_FORMAT = 'json'"
41
- ).fetchall()
42
- # disable session deletion
43
- self._conn._all_async_queries_finished = lambda: False # noqa: SLF001
44
- if self._conn._rest is None: # noqa: SLF001
45
- raise Exception("Failed to connect to Snowflake to retrieve token.")
46
- # obtain and create the token
47
- token_data = self._conn._rest._token_request("ISSUE") # noqa: SLF001
48
-
49
- return {
50
- "token": token_data["data"]["sessionToken"],
51
- "expires_in": token_data["data"]["validityInSecondsST"],
52
- }
53
-
54
- def login_to_registry(self, repo_url):
55
- """
56
- Logs in to the registry using basic authentication and generates a bearer authentication token.
57
- """
58
- token = json.dumps(self.get_token())
59
- parsed_url = urlparse(repo_url)
60
-
61
- scheme = parsed_url.scheme
62
- host = parsed_url.netloc
63
-
64
- login_url = f"{scheme}://{host}/login"
65
- creds = base64.b64encode(f"0sessiontoken:{token}".encode("utf-8"))
66
- creds = creds.decode("utf-8")
67
- resp = requests.get(login_url, headers={"Authorization": f"Basic {creds}"})
68
-
69
- if resp.status_code != 200:
70
- raise ClickException(f"Failed to login to the repository {resp.text}")
71
- return json.loads(resp.text)["token"]
72
-
73
- def _has_url_scheme(self, url: str):
74
- return re.fullmatch(r"^.*//.+", url) is not None
75
-
76
- def get_registry_url(self) -> str:
77
- repositories_query = "show image repositories in account"
78
- result_set = self._execute_query(repositories_query, cursor_class=DictCursor)
79
- results = result_set.fetchall()
80
- if len(results) == 0:
81
- raise NoImageRepositoriesFoundError()
82
- sample_repository_url = results[0]["repository_url"]
83
- if not self._has_url_scheme(sample_repository_url):
84
- sample_repository_url = f"//{sample_repository_url}"
85
- return urlparse(sample_repository_url).netloc
86
-
87
- def docker_registry_login(self) -> str:
88
- registry_url = self.get_registry_url()
89
- token = self.get_token()
90
- command = [
91
- "docker",
92
- "login",
93
- "--username",
94
- "0sessiontoken",
95
- "--password-stdin",
96
- registry_url,
97
- ]
98
- try:
99
- return subprocess.check_output(
100
- command, input=json.dumps(token), text=True, stderr=subprocess.PIPE
101
- )
102
- except subprocess.CalledProcessError as e:
103
- raise ClickException(f"Login Failed: {e.stderr}".strip())
104
- except FileNotFoundError:
105
- raise ClickException("Docker is not installed.")
@@ -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.