snowflake-cli-labs 3.0.0rc5__py3-none-any.whl → 3.0.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 (244) hide show
  1. README.md +21 -0
  2. {snowflake_cli_labs-3.0.0rc5.dist-info → snowflake_cli_labs-3.0.2.dist-info}/METADATA +6 -96
  3. snowflake_cli_labs-3.0.2.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 -90
  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 -400
  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.0rc5.dist-info/RECORD +0 -242
  242. snowflake_cli_labs-3.0.0rc5.dist-info/entry_points.txt +0 -2
  243. {snowflake_cli_labs-3.0.0rc5.dist-info → snowflake_cli_labs-3.0.2.dist-info}/WHEEL +0 -0
  244. {snowflake_cli_labs-3.0.0rc5.dist-info → snowflake_cli_labs-3.0.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,309 +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 contextlib
18
- import logging
19
- import os
20
- from typing import Dict, Optional
21
-
22
- import snowflake.connector
23
- from click.exceptions import ClickException
24
- from snowflake.cli._app.constants import (
25
- PARAM_APPLICATION_NAME,
26
- )
27
- from snowflake.cli._app.secret import SecretType
28
- from snowflake.cli._app.telemetry import command_info
29
- from snowflake.cli.api.config import (
30
- get_connection_dict,
31
- get_env_value,
32
- )
33
- from snowflake.cli.api.constants import DEFAULT_SIZE_LIMIT_MB
34
- from snowflake.cli.api.exceptions import (
35
- InvalidConnectionConfiguration,
36
- SnowflakeConnectionError,
37
- )
38
- from snowflake.cli.api.secure_path import SecurePath
39
- from snowflake.connector import SnowflakeConnection
40
- from snowflake.connector.errors import DatabaseError, ForbiddenError
41
-
42
- log = logging.getLogger(__name__)
43
-
44
-
45
- ENCRYPTED_PKCS8_PK_HEADER = b"-----BEGIN ENCRYPTED PRIVATE KEY-----"
46
- UNENCRYPTED_PKCS8_PK_HEADER = b"-----BEGIN PRIVATE KEY-----"
47
-
48
- # connection keys that can be set using SNOWFLAKE_* env vars
49
- SUPPORTED_ENV_OVERRIDES = [
50
- "account",
51
- "user",
52
- "password",
53
- "authenticator",
54
- "private_key_file",
55
- "private_key_path",
56
- "database",
57
- "schema",
58
- "role",
59
- "warehouse",
60
- "session_token",
61
- "master_token",
62
- "token_file_path",
63
- ]
64
-
65
- # mapping of found key -> key to set
66
- CONNECTION_KEY_ALIASES = {"private_key_path": "private_key_file"}
67
-
68
-
69
- def _resolve_alias(key_or_alias: str):
70
- """
71
- Given the key of an override / env var, what key should it be set as in the connection parameters?
72
- """
73
- return CONNECTION_KEY_ALIASES.get(key_or_alias, key_or_alias)
74
-
75
-
76
- def connect_to_snowflake(
77
- temporary_connection: bool = False,
78
- mfa_passcode: Optional[str] = None,
79
- enable_diag: Optional[bool] = False,
80
- diag_log_path: Optional[str] = None,
81
- diag_allowlist_path: Optional[str] = None,
82
- connection_name: Optional[str] = None,
83
- **overrides,
84
- ) -> SnowflakeConnection:
85
- if temporary_connection and connection_name:
86
- raise ClickException("Can't use connection name and temporary connection.")
87
- elif not temporary_connection and not connection_name:
88
- raise ClickException(
89
- "One of connection name or temporary connection is required."
90
- )
91
-
92
- using_session_token = (
93
- "session_token" in overrides and overrides["session_token"] is not None
94
- )
95
- using_master_token = (
96
- "master_token" in overrides and overrides["master_token"] is not None
97
- )
98
- _raise_errors_related_to_session_token(
99
- temporary_connection, using_session_token, using_master_token
100
- )
101
-
102
- if connection_name:
103
- connection_parameters = {
104
- _resolve_alias(k): v
105
- for k, v in get_connection_dict(connection_name).items()
106
- }
107
- elif temporary_connection:
108
- connection_parameters = {} # we will apply overrides in next step
109
-
110
- # Apply overrides to connection details
111
- # (1) Command line override case
112
- for key, value in overrides.items():
113
- if value is not None:
114
- connection_parameters[_resolve_alias(key)] = value
115
-
116
- # (2) Generic environment variable case
117
- # ... apply only if value not passed via flag or connection variable
118
- for key in SUPPORTED_ENV_OVERRIDES:
119
- generic_env_value = get_env_value(key=key)
120
- connection_key = _resolve_alias(key)
121
- if connection_key not in connection_parameters and generic_env_value:
122
- connection_parameters[connection_key] = generic_env_value
123
-
124
- # Clean up connection params
125
- connection_parameters = {
126
- k: v for k, v in connection_parameters.items() if v is not None
127
- }
128
-
129
- update_connection_details_with_private_key(connection_parameters)
130
-
131
- if mfa_passcode:
132
- connection_parameters["passcode"] = mfa_passcode
133
-
134
- if connection_parameters.get("authenticator") == "username_password_mfa":
135
- connection_parameters["client_request_mfa_token"] = True
136
-
137
- if enable_diag:
138
- connection_parameters["enable_connection_diag"] = enable_diag
139
- if diag_log_path:
140
- connection_parameters["connection_diag_log_path"] = diag_log_path
141
- if diag_allowlist_path:
142
- connection_parameters[
143
- "connection_diag_allowlist_path"
144
- ] = diag_allowlist_path
145
-
146
- # Make sure the connection is not closed if it was shared to the SnowCLI, instead of being created in the SnowCLI
147
- _avoid_closing_the_connection_if_it_was_shared(
148
- using_session_token, using_master_token, connection_parameters
149
- )
150
-
151
- _update_connection_application_name(connection_parameters)
152
-
153
- try:
154
- # Whatever output is generated when creating connection,
155
- # we don't want it in our output. This is particularly important
156
- # for cases when external browser and json format are used.
157
- # Redirecting both stdout and stderr for offline usage.
158
- with contextlib.redirect_stdout(None), contextlib.redirect_stderr(None):
159
- return snowflake.connector.connect(
160
- application=command_info(),
161
- **connection_parameters,
162
- )
163
- except ForbiddenError as err:
164
- raise SnowflakeConnectionError(err)
165
- except DatabaseError as err:
166
- raise InvalidConnectionConfiguration(err.msg)
167
-
168
-
169
- def _avoid_closing_the_connection_if_it_was_shared(
170
- using_session_token: bool, using_master_token: bool, connection_parameters: Dict
171
- ):
172
- if using_session_token and using_master_token:
173
- connection_parameters["server_session_keep_alive"] = True
174
-
175
-
176
- def _raise_errors_related_to_session_token(
177
- temporary_connection: bool, using_session_token: bool, using_master_token: bool
178
- ):
179
- if not temporary_connection and (using_session_token or using_master_token):
180
- raise ClickException(
181
- "When using a session or master token, you must use a temporary connection"
182
- )
183
- if using_session_token and not using_master_token:
184
- raise ClickException(
185
- "When using a session token, you must provide the corresponding master token"
186
- )
187
- if using_master_token and not using_session_token:
188
- raise ClickException(
189
- "When using a master token, you must provide the corresponding session token"
190
- )
191
-
192
-
193
- def update_connection_details_with_private_key(connection_parameters: Dict):
194
- if "private_key_file" in connection_parameters:
195
- _load_private_key(connection_parameters, "private_key_file")
196
- elif "private_key_path" in connection_parameters:
197
- _load_private_key(connection_parameters, "private_key_path")
198
- elif "private_key_raw" in connection_parameters:
199
- _load_private_key_from_parameters(connection_parameters, "private_key_raw")
200
- return connection_parameters
201
-
202
-
203
- def _load_private_key(connection_parameters: Dict, private_key_var_name: str) -> None:
204
- if connection_parameters.get("authenticator") == "SNOWFLAKE_JWT":
205
- private_key_pem = _load_pem_from_file(
206
- connection_parameters[private_key_var_name]
207
- )
208
- private_key = _load_pem_to_der(private_key_pem)
209
- connection_parameters["private_key"] = private_key.value
210
- del connection_parameters[private_key_var_name]
211
- else:
212
- raise ClickException(
213
- "Private Key authentication requires authenticator set to SNOWFLAKE_JWT"
214
- )
215
-
216
-
217
- def _load_private_key_from_parameters(
218
- connection_parameters: Dict, private_key_var_name: str
219
- ) -> None:
220
- if connection_parameters.get("authenticator") == "SNOWFLAKE_JWT":
221
- private_key_pem = _load_pem_from_parameters(
222
- connection_parameters[private_key_var_name]
223
- )
224
- private_key = _load_pem_to_der(private_key_pem)
225
- connection_parameters["private_key"] = private_key.value
226
- del connection_parameters[private_key_var_name]
227
- else:
228
- raise ClickException(
229
- "Private Key authentication requires authenticator set to SNOWFLAKE_JWT"
230
- )
231
-
232
-
233
- def _update_connection_application_name(connection_parameters: Dict):
234
- """Update version and name of app handling connection."""
235
- connection_application_params = {
236
- "application_name": PARAM_APPLICATION_NAME,
237
- }
238
- connection_parameters.update(connection_application_params)
239
-
240
-
241
- def _load_pem_from_file(private_key_file: str) -> SecretType:
242
- with SecurePath(private_key_file).open(
243
- "rb", read_file_limit_mb=DEFAULT_SIZE_LIMIT_MB
244
- ) as f:
245
- private_key_pem = SecretType(f.read())
246
- return private_key_pem
247
-
248
-
249
- def _load_pem_from_parameters(private_key_raw: str) -> SecretType:
250
- return SecretType(private_key_raw.encode("utf-8"))
251
-
252
-
253
- def _load_pem_to_der(private_key_pem: SecretType) -> SecretType:
254
- """
255
- Given a private key file path (in PEM format), decode key data into DER
256
- format
257
- """
258
- private_key_passphrase = SecretType(os.getenv("PRIVATE_KEY_PASSPHRASE", None))
259
- if (
260
- private_key_pem.value.startswith(ENCRYPTED_PKCS8_PK_HEADER)
261
- and private_key_passphrase.value is None
262
- ):
263
- raise ClickException(
264
- "Encrypted private key, you must provide the"
265
- "passphrase in the environment variable PRIVATE_KEY_PASSPHRASE"
266
- )
267
-
268
- if not private_key_pem.value.startswith(
269
- ENCRYPTED_PKCS8_PK_HEADER
270
- ) and not private_key_pem.value.startswith(UNENCRYPTED_PKCS8_PK_HEADER):
271
- raise ClickException(
272
- "Private key provided is not in PKCS#8 format. Please use correct format."
273
- )
274
-
275
- if private_key_pem.value.startswith(UNENCRYPTED_PKCS8_PK_HEADER):
276
- private_key_passphrase = SecretType(None)
277
-
278
- return prepare_private_key(private_key_pem, private_key_passphrase)
279
-
280
-
281
- def prepare_private_key(
282
- private_key_pem: SecretType, private_key_passphrase: SecretType = SecretType(None)
283
- ):
284
- from cryptography.hazmat.backends import default_backend
285
- from cryptography.hazmat.primitives.serialization import (
286
- Encoding,
287
- NoEncryption,
288
- PrivateFormat,
289
- load_pem_private_key,
290
- )
291
-
292
- private_key = SecretType(
293
- load_pem_private_key(
294
- private_key_pem.value,
295
- (
296
- str.encode(private_key_passphrase.value)
297
- if private_key_passphrase.value is not None
298
- else private_key_passphrase.value
299
- ),
300
- default_backend(),
301
- )
302
- )
303
- return SecretType(
304
- private_key.value.private_bytes(
305
- encoding=Encoding.DER,
306
- format=PrivateFormat.PKCS8,
307
- encryption_algorithm=NoEncryption(),
308
- )
309
- )
@@ -1,220 +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 platform
18
- import sys
19
- from enum import Enum, unique
20
- from typing import Any, Dict, Union
21
-
22
- import click
23
- from snowflake.cli.__about__ import VERSION
24
- from snowflake.cli._app.constants import PARAM_APPLICATION_NAME
25
- from snowflake.cli.api.cli_global_context import (
26
- _CliGlobalContextAccess,
27
- get_cli_context,
28
- )
29
- from snowflake.cli.api.commands.execution_metadata import ExecutionMetadata
30
- from snowflake.cli.api.config import get_feature_flags_section
31
- from snowflake.cli.api.output.formats import OutputFormat
32
- from snowflake.cli.api.utils.error_handling import ignore_exceptions
33
- from snowflake.connector.telemetry import (
34
- TelemetryData,
35
- TelemetryField,
36
- )
37
- from snowflake.connector.time_util import get_time_millis
38
-
39
-
40
- @unique
41
- class CLIInstallationSource(Enum):
42
- BINARY = "binary"
43
- PYPI = "pypi"
44
-
45
-
46
- @unique
47
- class CLITelemetryField(Enum):
48
- # Basic information
49
- SOURCE = "source"
50
- VERSION_CLI = "version_cli"
51
- VERSION_PYTHON = "version_python"
52
- VERSION_OS = "version_os"
53
- INSTALLATION_SOURCE = "installation_source"
54
- # Command execution context
55
- COMMAND = "command"
56
- COMMAND_GROUP = "command_group"
57
- COMMAND_FLAGS = "command_flags"
58
- COMMAND_EXECUTION_ID = "command_execution_id"
59
- COMMAND_RESULT_STATUS = "command_result_status"
60
- COMMAND_OUTPUT_TYPE = "command_output_type"
61
- COMMAND_EXECUTION_TIME = "command_execution_time"
62
- # Configuration
63
- CONFIG_FEATURE_FLAGS = "config_feature_flags"
64
- # Metrics
65
- COUNTERS = "counters"
66
- # Information
67
- EVENT = "event"
68
- ERROR_MSG = "error_msg"
69
- ERROR_TYPE = "error_type"
70
- IS_CLI_EXCEPTION = "is_cli_exception"
71
- # Project context
72
- PROJECT_DEFINITION_VERSION = "project_definition_version"
73
-
74
-
75
- class TelemetryEvent(Enum):
76
- CMD_EXECUTION = "executing_command"
77
- CMD_EXECUTION_ERROR = "error_executing_command"
78
- CMD_EXECUTION_RESULT = "result_executing_command"
79
-
80
-
81
- TelemetryDict = Dict[Union[CLITelemetryField, TelemetryField], Any]
82
-
83
-
84
- def _get_command_metrics() -> TelemetryDict:
85
- cli_context = get_cli_context()
86
-
87
- return {
88
- CLITelemetryField.COUNTERS: {
89
- **cli_context.metrics.counters,
90
- }
91
- }
92
-
93
-
94
- def _find_command_info() -> TelemetryDict:
95
- ctx = click.get_current_context()
96
- command_path = ctx.command_path.split(" ")[1:]
97
- return {
98
- CLITelemetryField.COMMAND: command_path,
99
- CLITelemetryField.COMMAND_GROUP: command_path[0],
100
- CLITelemetryField.COMMAND_FLAGS: {
101
- k: ctx.get_parameter_source(k).name # type: ignore[attr-defined]
102
- for k, v in ctx.params.items()
103
- if v # noqa
104
- },
105
- CLITelemetryField.COMMAND_OUTPUT_TYPE: ctx.params.get(
106
- "format", OutputFormat.TABLE
107
- ).value,
108
- CLITelemetryField.PROJECT_DEFINITION_VERSION: str(_get_definition_version()),
109
- }
110
-
111
-
112
- def _get_definition_version() -> str | None:
113
- cli_context = get_cli_context()
114
- if cli_context.project_definition:
115
- return cli_context.project_definition.definition_version
116
- return None
117
-
118
-
119
- def _get_installation_source() -> CLIInstallationSource:
120
- if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
121
- return CLIInstallationSource.BINARY
122
- return CLIInstallationSource.PYPI
123
-
124
-
125
- def command_info() -> str:
126
- info = _find_command_info()
127
- command = ".".join(info[CLITelemetryField.COMMAND])
128
- return f"{PARAM_APPLICATION_NAME}.{command}".upper()
129
-
130
-
131
- def python_version() -> str:
132
- py_ver = sys.version_info
133
- return f"{py_ver.major}.{py_ver.minor}.{py_ver.micro}"
134
-
135
-
136
- class CLITelemetryClient:
137
- @property
138
- def _ctx(self) -> _CliGlobalContextAccess:
139
- return get_cli_context()
140
-
141
- @staticmethod
142
- def generate_telemetry_data_dict(
143
- telemetry_payload: TelemetryDict,
144
- ) -> Dict[str, Any]:
145
- data = {
146
- CLITelemetryField.SOURCE: PARAM_APPLICATION_NAME,
147
- CLITelemetryField.INSTALLATION_SOURCE: _get_installation_source().value,
148
- CLITelemetryField.VERSION_CLI: VERSION,
149
- CLITelemetryField.VERSION_OS: platform.platform(),
150
- CLITelemetryField.VERSION_PYTHON: python_version(),
151
- CLITelemetryField.CONFIG_FEATURE_FLAGS: {
152
- k: str(v) for k, v in get_feature_flags_section().items()
153
- },
154
- **_find_command_info(),
155
- **telemetry_payload,
156
- }
157
- # To map Enum to string, so we don't have to use .value every time
158
- return {getattr(k, "value", k): v for k, v in data.items()} # type: ignore[arg-type]
159
-
160
- @property
161
- def _telemetry(self):
162
- return self._ctx.connection._telemetry # noqa
163
-
164
- def send(self, payload: TelemetryDict):
165
- if self._telemetry:
166
- message = self.generate_telemetry_data_dict(payload)
167
- telemetry_data = TelemetryData.from_telemetry_data_dict(
168
- from_dict=message, timestamp=get_time_millis()
169
- )
170
- self._telemetry.try_add_log_to_batch(telemetry_data)
171
-
172
- def flush(self):
173
- self._telemetry.send_batch()
174
-
175
-
176
- _telemetry = CLITelemetryClient()
177
-
178
-
179
- @ignore_exceptions()
180
- def log_command_usage(execution: ExecutionMetadata):
181
- _telemetry.send(
182
- {
183
- TelemetryField.KEY_TYPE: TelemetryEvent.CMD_EXECUTION.value,
184
- CLITelemetryField.COMMAND_EXECUTION_ID: execution.execution_id,
185
- }
186
- )
187
-
188
-
189
- @ignore_exceptions()
190
- def log_command_result(execution: ExecutionMetadata):
191
- _telemetry.send(
192
- {
193
- TelemetryField.KEY_TYPE: TelemetryEvent.CMD_EXECUTION_RESULT.value,
194
- CLITelemetryField.COMMAND_EXECUTION_ID: execution.execution_id,
195
- CLITelemetryField.COMMAND_RESULT_STATUS: execution.status.value,
196
- CLITelemetryField.COMMAND_EXECUTION_TIME: execution.get_duration(),
197
- **_get_command_metrics(),
198
- }
199
- )
200
-
201
-
202
- @ignore_exceptions()
203
- def log_command_execution_error(exception: Exception, execution: ExecutionMetadata):
204
- exception_type: str = type(exception).__name__
205
- is_cli_exception: bool = issubclass(exception.__class__, click.ClickException)
206
- _telemetry.send(
207
- {
208
- TelemetryField.KEY_TYPE: TelemetryEvent.CMD_EXECUTION_ERROR.value,
209
- CLITelemetryField.COMMAND_EXECUTION_ID: execution.execution_id,
210
- CLITelemetryField.ERROR_TYPE: exception_type,
211
- CLITelemetryField.IS_CLI_EXCEPTION: is_cli_exception,
212
- CLITelemetryField.COMMAND_EXECUTION_TIME: execution.get_duration(),
213
- **_get_command_metrics(),
214
- }
215
- )
216
-
217
-
218
- @ignore_exceptions()
219
- def flush_telemetry():
220
- _telemetry.flush()
@@ -1,74 +0,0 @@
1
- import json
2
- import time
3
-
4
- import requests
5
- from packaging.version import Version
6
- from snowflake.cli.__about__ import VERSION
7
- from snowflake.cli.api.console import cli_console
8
- from snowflake.cli.api.secure_path import SecurePath
9
- from snowflake.connector.config_manager import CONFIG_MANAGER
10
-
11
-
12
- def get_new_version_msg() -> str | None:
13
- last = _VersionCache().get_last_version()
14
- current = Version(VERSION)
15
- if last and last > current:
16
- return f"\nNew version of Snowflake CLI available. Newest: {last}, current: {VERSION}\n"
17
- return None
18
-
19
-
20
- def show_new_version_banner_callback(msg):
21
- def _callback(*args, **kwargs):
22
- if msg:
23
- cli_console.message(msg)
24
-
25
- return _callback
26
-
27
-
28
- class _VersionCache:
29
- _last_time = "last_time_check"
30
- _version = "version"
31
- _version_cache_file = SecurePath(
32
- CONFIG_MANAGER.file_path.parent / ".cli_version.cache"
33
- )
34
-
35
- def __init__(self):
36
- self._cache_file = _VersionCache._version_cache_file
37
-
38
- def _save_latest_version(self, version: str):
39
- data = {
40
- _VersionCache._last_time: time.time(),
41
- _VersionCache._version: str(version),
42
- }
43
- self._cache_file.write_text(json.dumps(data))
44
-
45
- @staticmethod
46
- def _get_version_from_pypi() -> str | None:
47
- headers = {"Content-Type": "application/vnd.pypi.simple.v1+json"}
48
- response = requests.get(
49
- "https://pypi.org/pypi/snowflake-cli-labs/json", headers=headers, timeout=3
50
- )
51
- response.raise_for_status()
52
- return response.json()["info"]["version"]
53
-
54
- def _update_latest_version(self) -> Version | None:
55
- version = self._get_version_from_pypi()
56
- if version is None:
57
- return None
58
- self._save_latest_version(version)
59
- return Version(version)
60
-
61
- def _read_latest_version(self) -> Version | None:
62
- if self._cache_file.exists():
63
- data = json.loads(self._cache_file.read_text())
64
- now = time.time()
65
- if data[_VersionCache._last_time] > now - 60 * 60:
66
- return Version(data[_VersionCache._version])
67
-
68
- return self._update_latest_version()
69
-
70
- def get_last_version(self) -> Version | None:
71
- try:
72
- return self._read_latest_version()
73
- except: # anything, this it not crucial feature
74
- return None
@@ -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,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.