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,353 +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 logging
18
- import os.path
19
-
20
- import typer
21
- from click import ClickException, Context, Parameter # type: ignore
22
- from click.core import ParameterSource # type: ignore
23
- from click.types import StringParamType
24
- from snowflake.cli._plugins.connection.util import (
25
- strip_and_check_if_exists,
26
- strip_if_value_present,
27
- )
28
- from snowflake.cli._plugins.object.manager import ObjectManager
29
- from snowflake.cli.api.cli_global_context import get_cli_context
30
- from snowflake.cli.api.commands.flags import (
31
- PLAIN_PASSWORD_MSG,
32
- )
33
- from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
34
- from snowflake.cli.api.config import (
35
- ConnectionConfig,
36
- add_connection_to_proper_file,
37
- connection_exists,
38
- get_all_connections,
39
- get_connection_dict,
40
- get_default_connection_name,
41
- set_config_value,
42
- )
43
- from snowflake.cli.api.console import cli_console
44
- from snowflake.cli.api.constants import ObjectType
45
- from snowflake.cli.api.output.types import (
46
- CollectionResult,
47
- CommandResult,
48
- MessageResult,
49
- ObjectResult,
50
- )
51
- from snowflake.connector import ProgrammingError
52
- from snowflake.connector.constants import CONNECTIONS_FILE
53
-
54
- app = SnowTyperFactory(
55
- name="connection",
56
- help="Manages connections to Snowflake.",
57
- )
58
- log = logging.getLogger(__name__)
59
-
60
-
61
- class EmptyInput:
62
- def __repr__(self):
63
- return "optional"
64
-
65
-
66
- class OptionalPrompt(StringParamType):
67
- def convert(self, value, param, ctx):
68
- return None if isinstance(value, EmptyInput) else value
69
-
70
-
71
- def _mask_password(connection_params: dict):
72
- if "password" in connection_params:
73
- connection_params["password"] = "****"
74
- return connection_params
75
-
76
-
77
- @app.command(name="list")
78
- def list_connections(**options) -> CommandResult:
79
- """
80
- Lists configured connections.
81
- """
82
- connections = get_all_connections()
83
- default_connection = get_default_connection_name()
84
- result = (
85
- {
86
- "connection_name": connection_name,
87
- "parameters": _mask_password(
88
- connection_config.to_dict_of_known_non_empty_values()
89
- ),
90
- "is_default": connection_name == default_connection,
91
- }
92
- for connection_name, connection_config in connections.items()
93
- )
94
-
95
- if CONNECTIONS_FILE.exists():
96
- cli_console.warning(
97
- f"Reading connections from {CONNECTIONS_FILE}. Entries from config.toml are ignored."
98
- )
99
- return CollectionResult(result)
100
-
101
-
102
- def require_integer(field_name: str):
103
- def callback(value: str):
104
- if value is None:
105
- return None
106
- if value.strip().isdigit():
107
- return value.strip()
108
- raise ClickException(f"Value of {field_name} must be integer")
109
-
110
- return callback
111
-
112
-
113
- def _password_callback(ctx: Context, param: Parameter, value: str):
114
- if value and ctx.get_parameter_source(param.name) == ParameterSource.COMMANDLINE: # type: ignore
115
- cli_console.warning(PLAIN_PASSWORD_MSG)
116
-
117
- return value
118
-
119
-
120
- @app.command()
121
- def add(
122
- connection_name: str = typer.Option(
123
- None,
124
- "--connection-name",
125
- "-n",
126
- prompt="Name for this connection",
127
- help="Name of the new connection.",
128
- show_default=False,
129
- callback=strip_if_value_present,
130
- ),
131
- account: str = typer.Option(
132
- None,
133
- "--account",
134
- "-a",
135
- "--accountname",
136
- prompt="Snowflake account name",
137
- help="Account name to use when authenticating with Snowflake.",
138
- show_default=False,
139
- callback=strip_if_value_present,
140
- ),
141
- user: str = typer.Option(
142
- None,
143
- "--user",
144
- "-u",
145
- "--username",
146
- prompt="Snowflake username",
147
- show_default=False,
148
- help="Username to connect to Snowflake.",
149
- callback=strip_if_value_present,
150
- ),
151
- password: str = typer.Option(
152
- EmptyInput(),
153
- "--password",
154
- "-p",
155
- click_type=OptionalPrompt(),
156
- callback=_password_callback,
157
- prompt="Snowflake password",
158
- help="Snowflake password.",
159
- hide_input=True,
160
- ),
161
- role: str = typer.Option(
162
- EmptyInput(),
163
- "--role",
164
- "-r",
165
- click_type=OptionalPrompt(),
166
- prompt="Role for the connection",
167
- help="Role to use on Snowflake.",
168
- callback=strip_if_value_present,
169
- ),
170
- warehouse: str = typer.Option(
171
- EmptyInput(),
172
- "--warehouse",
173
- "-w",
174
- click_type=OptionalPrompt(),
175
- prompt="Warehouse for the connection",
176
- help="Warehouse to use on Snowflake.",
177
- callback=strip_if_value_present,
178
- ),
179
- database: str = typer.Option(
180
- EmptyInput(),
181
- "--database",
182
- "-d",
183
- click_type=OptionalPrompt(),
184
- prompt="Database for the connection",
185
- help="Database to use on Snowflake.",
186
- callback=strip_if_value_present,
187
- ),
188
- schema: str = typer.Option(
189
- EmptyInput(),
190
- "--schema",
191
- "-s",
192
- click_type=OptionalPrompt(),
193
- prompt="Schema for the connection",
194
- help="Schema to use on Snowflake.",
195
- callback=strip_if_value_present,
196
- ),
197
- host: str = typer.Option(
198
- EmptyInput(),
199
- "--host",
200
- "-h",
201
- click_type=OptionalPrompt(),
202
- prompt="Connection host",
203
- help="Host name the connection attempts to connect to Snowflake.",
204
- callback=strip_if_value_present,
205
- ),
206
- port: int = typer.Option(
207
- EmptyInput(),
208
- "--port",
209
- "-P",
210
- click_type=OptionalPrompt(),
211
- prompt="Connection port",
212
- help="Port to communicate with on the host.",
213
- callback=require_integer(field_name="port"),
214
- ),
215
- region: str = typer.Option(
216
- EmptyInput(),
217
- "--region",
218
- "-R",
219
- click_type=OptionalPrompt(),
220
- prompt="Snowflake region",
221
- help="Region name if not the default Snowflake deployment.",
222
- callback=strip_if_value_present,
223
- ),
224
- authenticator: str = typer.Option(
225
- EmptyInput(),
226
- "--authenticator",
227
- "-A",
228
- click_type=OptionalPrompt(),
229
- prompt="Authentication method",
230
- help="Chosen authenticator, if other than password-based",
231
- ),
232
- private_key_file: str = typer.Option(
233
- EmptyInput(),
234
- "--private-key",
235
- "--private-key-path",
236
- "-k",
237
- click_type=OptionalPrompt(),
238
- prompt="Path to private key file",
239
- help="Path to file containing private key",
240
- callback=strip_and_check_if_exists,
241
- ),
242
- token_file_path: str = typer.Option(
243
- EmptyInput(),
244
- "--token-file-path",
245
- "-t",
246
- click_type=OptionalPrompt(),
247
- prompt="Path to token file",
248
- help="Path to file with an OAuth token that should be used when connecting to Snowflake",
249
- callback=strip_and_check_if_exists,
250
- ),
251
- set_as_default: bool = typer.Option(
252
- False,
253
- "--default",
254
- is_flag=True,
255
- help="If provided the connection will be configured as default connection.",
256
- ),
257
- **options,
258
- ) -> CommandResult:
259
- """Adds a connection to configuration file."""
260
- if connection_exists(connection_name):
261
- raise ClickException(f"Connection {connection_name} already exists")
262
-
263
- connections_file = add_connection_to_proper_file(
264
- connection_name,
265
- ConnectionConfig(
266
- account=account,
267
- user=user,
268
- password=password,
269
- host=host,
270
- region=region,
271
- port=port,
272
- database=database,
273
- schema=schema,
274
- warehouse=warehouse,
275
- role=role,
276
- authenticator=authenticator,
277
- private_key_file=private_key_file,
278
- token_file_path=token_file_path,
279
- ),
280
- )
281
- if set_as_default:
282
- set_config_value(
283
- section=None, key="default_connection_name", value=connection_name
284
- )
285
-
286
- return MessageResult(
287
- f"Wrote new connection {connection_name} to {connections_file}"
288
- )
289
-
290
-
291
- @app.command(requires_connection=True)
292
- def test(
293
- **options,
294
- ) -> CommandResult:
295
- """
296
- Tests the connection to Snowflake.
297
- """
298
-
299
- # Test connection
300
- cli_context = get_cli_context()
301
- conn = cli_context.connection
302
-
303
- # Test session attributes
304
- om = ObjectManager()
305
- try:
306
- # "use database" operation changes schema to default "public",
307
- # so to test schema set up by user we need to copy it here:
308
- schema = conn.schema
309
-
310
- if conn.role:
311
- om.use(object_type=ObjectType.ROLE, name=f'"{conn.role}"')
312
- if conn.database:
313
- om.use(object_type=ObjectType.DATABASE, name=f'"{conn.database}"')
314
- if schema:
315
- om.use(object_type=ObjectType.SCHEMA, name=f'"{schema}"')
316
- if conn.warehouse:
317
- om.use(object_type=ObjectType.WAREHOUSE, name=f'"{conn.warehouse}"')
318
-
319
- except ProgrammingError as err:
320
- raise ClickException(str(err))
321
-
322
- conn_ctx = cli_context.connection_context
323
- result = {
324
- "Connection name": conn_ctx.connection_name,
325
- "Status": "OK",
326
- "Host": conn.host,
327
- "Account": conn.account,
328
- "User": conn.user,
329
- "Role": f'{conn.role or "not set"}',
330
- "Database": f'{conn.database or "not set"}',
331
- "Warehouse": f'{conn.warehouse or "not set"}',
332
- }
333
-
334
- if conn_ctx.enable_diag:
335
- result["Diag Report Location"] = os.path.join(
336
- conn_ctx.diag_log_path, "SnowflakeConnectionTestReport.txt"
337
- )
338
-
339
- return ObjectResult(result)
340
-
341
-
342
- @app.command(requires_connection=False)
343
- def set_default(
344
- name: str = typer.Argument(
345
- help="Name of the connection, as defined in your `config.toml`",
346
- show_default=False,
347
- ),
348
- **options,
349
- ):
350
- """Changes default connection to provided value."""
351
- get_connection_dict(connection_name=name)
352
- set_config_value(section=None, key="default_connection_name", value=name)
353
- return MessageResult(f"Default connection set to: {name}")
@@ -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._plugins.connection import commands
16
- from snowflake.cli.api.plugins.command import (
17
- SNOWCLI_ROOT_COMMAND_PATH,
18
- CommandSpec,
19
- CommandType,
20
- plugin_hook_impl,
21
- )
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,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
- import json
18
- import logging
19
- import os
20
- from typing import Optional
21
-
22
- from click.exceptions import ClickException
23
- from snowflake.connector import SnowflakeConnection
24
- from snowflake.connector.cursor import DictCursor
25
-
26
- log = logging.getLogger(__name__)
27
-
28
- REGIONLESS_QUERY = """
29
- select value['value'] as REGIONLESS from table(flatten(
30
- input => parse_json(SYSTEM$BOOTSTRAP_DATA_REQUEST()),
31
- path => 'clientParamsInfo'
32
- )) where value['name'] = 'UI_SNOWSIGHT_ENABLE_REGIONLESS_REDIRECT';
33
- """
34
-
35
- ALLOWLIST_QUERY = "SELECT SYSTEM$ALLOWLIST()"
36
- SNOWFLAKE_DEPLOYMENT = "SNOWFLAKE_DEPLOYMENT"
37
- LOCAL_DEPLOYMENT_REGION: str = "us-west-2"
38
-
39
-
40
- class MissingConnectionAccountError(ClickException):
41
- def __init__(self, conn: SnowflakeConnection):
42
- super().__init__(
43
- "Could not determine account by system call, configured account name, or configured host. Connection: "
44
- + repr(conn)
45
- )
46
-
47
-
48
- class MissingConnectionRegionError(ClickException):
49
- def __init__(self, host: str | None):
50
- super().__init__(
51
- f"The connection host ({host}) was missing or not in "
52
- "the expected format "
53
- "(<account>.<deployment>.snowflakecomputing.com)"
54
- )
55
-
56
-
57
- def is_regionless_redirect(conn: SnowflakeConnection) -> bool:
58
- """
59
- Determines if the deployment this connection refers to uses
60
- regionless URLs in Snowsight (/orgname/account) or regional URLs
61
- (/region/account). If we cannot determine the correct value we
62
- assume it's regionless, as this is true for most production deployments.
63
- """
64
- try:
65
- *_, cursor = conn.execute_string(REGIONLESS_QUERY, cursor_class=DictCursor)
66
- return cursor.fetchone()["REGIONLESS"].lower() == "true"
67
- except:
68
- log.warning(
69
- "Cannot determine regionless redirect; assuming True.", exc_info=True
70
- )
71
- return True
72
-
73
-
74
- def get_host_region(host: str) -> str | None:
75
- """
76
- Looks for hosts of form
77
- <account>.[x.y.z].snowflakecomputing.com
78
- Returns the three-part [region identifier] or None.
79
- """
80
- host_parts = host.split(".")
81
- if host_parts[-1] == "local":
82
- return LOCAL_DEPLOYMENT_REGION
83
- elif len(host_parts) == 6:
84
- return ".".join(host_parts[1:4])
85
- return None
86
-
87
-
88
- def guess_regioned_host_from_allowlist(conn: SnowflakeConnection) -> str | None:
89
- """
90
- Use SYSTEM$ALLOWLIST to find a regioned host (<account>.x.y.z.snowflakecomputing.com)
91
- that corresponds to the given Snowflake connection object.
92
- """
93
- try:
94
- *_, cursor = conn.execute_string(ALLOWLIST_QUERY, cursor_class=DictCursor)
95
- allowlist_tuples = json.loads(cursor.fetchone()["SYSTEM$ALLOWLIST()"])
96
- for t in allowlist_tuples:
97
- if t["type"] == SNOWFLAKE_DEPLOYMENT:
98
- if get_host_region(t["host"]) is not None:
99
- return t["host"]
100
- except:
101
- log.warning(
102
- "Could not call SYSTEM$ALLOWLIST; returning an empty guess.", exc_info=True
103
- )
104
- return None
105
-
106
-
107
- def get_region(conn: SnowflakeConnection) -> str:
108
- """
109
- Get the region of the given connection, or raise MissingConnectionRegionError.
110
- """
111
- if conn.host:
112
- if region := get_host_region(conn.host):
113
- return region
114
-
115
- if host := guess_regioned_host_from_allowlist(conn):
116
- if region := get_host_region(host):
117
- return region
118
-
119
- raise MissingConnectionRegionError(host or conn.host)
120
-
121
-
122
- def get_context(conn: SnowflakeConnection) -> str:
123
- """
124
- Determines the first part of the path in a Snowsight URL.
125
- This could be a region or it could be an organization, depending
126
- on whether or not the underlying deployment uses regionless URLs.
127
- """
128
- if is_regionless_redirect(conn):
129
- *_, cursor = conn.execute_string(
130
- f"select system$return_current_org_name()", cursor_class=DictCursor
131
- )
132
- return cursor.fetchone()["SYSTEM$RETURN_CURRENT_ORG_NAME()"]
133
-
134
- return get_region(conn)
135
-
136
-
137
- def get_account(conn: SnowflakeConnection) -> str:
138
- """
139
- Determines the account that this connection refers to.
140
- """
141
- try:
142
- *_, cursor = conn.execute_string(
143
- f"select current_account_name()", cursor_class=DictCursor
144
- )
145
- return cursor.fetchone()["CURRENT_ACCOUNT_NAME()"].lower()
146
- except Exception as e:
147
- # try to extract the account from the connection information
148
- if conn.account:
149
- return conn.account
150
-
151
- if conn.host:
152
- host_parts = conn.host.split(".")
153
- return host_parts[0]
154
-
155
- raise MissingConnectionAccountError(conn)
156
-
157
-
158
- def get_snowsight_host(conn: SnowflakeConnection) -> str:
159
- try:
160
- *_, cursor = conn.execute_string(
161
- f"select system$get_snowsight_host()", cursor_class=DictCursor
162
- )
163
- return cursor.fetchone()["SYSTEM$GET_SNOWSIGHT_HOST()"]
164
- except Exception as e:
165
- # if we cannot determine the host, assume we're on prod
166
- return "https://app.snowflake.com"
167
-
168
-
169
- def make_snowsight_url(conn: SnowflakeConnection, path: str) -> str:
170
- """
171
- Returns a URL on the correct Snowsight instance for the connected account.
172
- The path that is passed in must already be properly URL-encoded, and
173
- can optionally contain a hash/fragment (e.g. #).
174
-
175
- See also identifier_for_url.
176
- """
177
- snowsight_host = get_snowsight_host(conn)
178
- deployment = get_context(conn)
179
- account = get_account(conn)
180
- path_with_slash = path if path.startswith("/") else f"/{path}"
181
- return f"{snowsight_host}/{deployment}/{account}{path_with_slash}"
182
-
183
-
184
- def strip_if_value_present(value: Optional[str]) -> Optional[str]:
185
- return value.strip() if value else value
186
-
187
-
188
- def ensure_that_path_exist(path: Optional[str]) -> Optional[str]:
189
- if path and not os.path.exists(path):
190
- raise ClickException(f"Path {path} does not exist.")
191
- return path
192
-
193
-
194
- def strip_and_check_if_exists(value: Optional[str]) -> Optional[str]:
195
- return ensure_that_path_exist(strip_if_value_present(value))
@@ -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.