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,307 +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 re
18
- from typing import Dict, List, Optional, Set, Union
19
-
20
- from snowflake.cli.api.constants import ObjectType
21
- from snowflake.cli.api.identifiers import FQN
22
- from snowflake.cli.api.project.schemas.snowpark.callable import (
23
- FunctionSchema,
24
- ProcedureSchema,
25
- )
26
- from snowflake.cli.api.sql_execution import SqlExecutionMixin
27
- from snowflake.cli.plugins.snowpark.models import Requirement
28
- from snowflake.cli.plugins.snowpark.package_utils import (
29
- generate_deploy_stage_name,
30
- )
31
- from snowflake.connector.cursor import SnowflakeCursor
32
-
33
- DEFAULT_RUNTIME = "3.8"
34
- FunctionOrProcedure = Union[FunctionSchema, ProcedureSchema]
35
-
36
-
37
- def check_if_replace_is_required(
38
- object_type: ObjectType,
39
- current_state,
40
- handler: str,
41
- return_type: str,
42
- snowflake_dependencies: List[str],
43
- external_access_integrations: List[str],
44
- imports: List[str],
45
- stage_artifact_file: str,
46
- runtime_ver: Optional[str] = None,
47
- execute_as_caller: Optional[bool] = None,
48
- ) -> bool:
49
- import logging
50
-
51
- log = logging.getLogger(__name__)
52
- resource_json = _convert_resource_details_to_dict(current_state)
53
- old_dependencies = resource_json["packages"]
54
- log.info(
55
- "Found %d defined Anaconda packages in deployed %s...",
56
- len(old_dependencies),
57
- object_type,
58
- )
59
- log.info("Checking if app configuration has changed...")
60
-
61
- if _snowflake_dependencies_differ(old_dependencies, snowflake_dependencies):
62
- log.info(
63
- "Found difference of package requirements. Replacing the %s.", object_type
64
- )
65
- return True
66
-
67
- if set(external_access_integrations) != set(
68
- resource_json.get("external_access_integrations", [])
69
- ):
70
- log.info(
71
- "Found difference of external access integrations. Replacing the %s.",
72
- object_type,
73
- )
74
- return True
75
-
76
- if (
77
- resource_json["handler"].lower() != handler.lower()
78
- or _sql_to_python_return_type_mapper(resource_json["returns"]).lower()
79
- != return_type.lower()
80
- ):
81
- log.info(
82
- "Return type or handler types do not match. Replacing the %s.", object_type
83
- )
84
- return True
85
-
86
- if _compare_imports(resource_json, imports, stage_artifact_file):
87
- log.info("Imports do not match. Replacing the %s", object_type)
88
- return True
89
-
90
- if runtime_ver is not None and runtime_ver != resource_json.get(
91
- "runtime_version", "RUNTIME_NOT_SET"
92
- ):
93
- log.info("Runtime versions do not match. Replacing the %s", object_type)
94
- return True
95
-
96
- if execute_as_caller is not None and (
97
- resource_json.get("execute as", "OWNER")
98
- != ("CALLER" if execute_as_caller else "OWNER")
99
- ):
100
- log.info(
101
- "Execute as caller settings do not match. Replacing the %s", object_type
102
- )
103
- return True
104
-
105
- return False
106
-
107
-
108
- def _convert_resource_details_to_dict(function_details: SnowflakeCursor) -> dict:
109
- import json
110
-
111
- function_dict = {}
112
- json_properties = ["packages", "installed_packages"]
113
- for function in function_details:
114
- if function[0] in json_properties:
115
- function_dict[function[0]] = json.loads(
116
- function[1].replace("'", '"'),
117
- )
118
- else:
119
- function_dict[function[0]] = function[1]
120
- return function_dict
121
-
122
-
123
- def _snowflake_dependencies_differ(
124
- old_dependencies: List[str], new_dependencies: List[str]
125
- ) -> bool:
126
- def _standardize(packages: List[str]) -> Set[str]:
127
- return set(
128
- Requirement.parse_line(package).name_and_version for package in packages
129
- )
130
-
131
- return _standardize(old_dependencies) != _standardize(new_dependencies)
132
-
133
-
134
- def _sql_to_python_return_type_mapper(resource_return_type: str) -> str:
135
- """
136
- Some of the Python data types get converted to SQL types, when function/procedure is created.
137
- So, to properly compare types, we use mapping based on:
138
- https://docs.snowflake.com/en/developer-guide/udf-stored-procedure-data-type-mapping#sql-python-data-type-mappings
139
-
140
- Mind you, this only applies to cases, in which Snowflake accepts Python type as return.
141
- Ie. if function returns list, it has to be declared as 'array' during creation,
142
- therefore any conversion is not necessary
143
- """
144
- mapping = {
145
- "number(38,0)": "int",
146
- "timestamp_ntz(9)": "datetime",
147
- "timestamp_tz(9)": "datetime",
148
- "varchar(16777216)": "string",
149
- }
150
-
151
- return mapping.get(resource_return_type.lower(), resource_return_type.lower())
152
-
153
-
154
- class SnowparkObjectManager(SqlExecutionMixin):
155
- @property
156
- def _object_type(self) -> ObjectType:
157
- raise NotImplementedError()
158
-
159
- @property
160
- def _object_execute(self):
161
- raise NotImplementedError()
162
-
163
- def create(self, *args, **kwargs) -> SnowflakeCursor:
164
- raise NotImplementedError()
165
-
166
- def execute(self, execution_identifier: str) -> SnowflakeCursor:
167
- return self._execute_query(f"{self._object_execute} {execution_identifier}")
168
-
169
- @staticmethod
170
- def artifact_stage_path(identifier: str):
171
- return generate_deploy_stage_name(identifier).lower()
172
-
173
- def create_query(
174
- self,
175
- identifier: UdfSprocIdentifier,
176
- return_type: str,
177
- handler: str,
178
- artifact_file: str,
179
- packages: List[str],
180
- imports: List[str],
181
- external_access_integrations: Optional[List[str]] = None,
182
- secrets: Optional[Dict[str, str]] = None,
183
- runtime: Optional[str] = None,
184
- execute_as_caller: bool = False,
185
- ) -> str:
186
- imports.append(artifact_file)
187
- imports = [f"'{x}'" for x in imports]
188
- packages_list = ",".join(f"'{p}'" for p in packages)
189
-
190
- query = [
191
- f"create or replace {self._object_type.value.sf_name} {identifier.identifier_for_sql}",
192
- f"copy grants",
193
- f"returns {return_type}",
194
- "language python",
195
- f"runtime_version={runtime or DEFAULT_RUNTIME}",
196
- f"imports=({', '.join(imports)})",
197
- f"handler='{handler}'",
198
- f"packages=({packages_list})",
199
- ]
200
-
201
- if external_access_integrations:
202
- external_access_integration_name = ",".join(
203
- f"{e}" for e in external_access_integrations
204
- )
205
- query.append(
206
- f"external_access_integrations=({external_access_integration_name})"
207
- )
208
-
209
- if secrets:
210
- secret_name = ",".join(f"'{k}'={v}" for k, v in secrets.items())
211
- query.append(f"secrets=({secret_name})")
212
-
213
- if execute_as_caller:
214
- query.append("execute as caller")
215
-
216
- return "\n".join(query)
217
-
218
-
219
- def _is_signature_type_a_string(sig_type: str) -> bool:
220
- return sig_type.lower() in ["string", "varchar"]
221
-
222
-
223
- class UdfSprocIdentifier:
224
- def __init__(self, identifier: FQN, arg_names, arg_types, arg_defaults):
225
- self._identifier = identifier
226
- self._arg_names = arg_names
227
- self._arg_types = arg_types
228
- self._arg_defaults = arg_defaults
229
-
230
- def _identifier_from_signature(self, sig: List[str], for_sql: bool = False):
231
- signature = self._comma_join(sig)
232
- id_ = self._identifier.sql_identifier if for_sql else self._identifier
233
- return f"{id_}({signature})"
234
-
235
- @staticmethod
236
- def _comma_join(*args):
237
- return ", ".join(*args)
238
-
239
- @property
240
- def identifier_with_arg_names(self):
241
- return self._identifier_from_signature(self._arg_names)
242
-
243
- @property
244
- def identifier_with_arg_types(self):
245
- return self._identifier_from_signature(self._arg_types)
246
-
247
- @property
248
- def identifier_with_arg_names_types(self):
249
- sig = [f"{n} {t}" for n, t in zip(self._arg_names, self._arg_types)]
250
- return self._identifier_from_signature(sig)
251
-
252
- @property
253
- def identifier_with_arg_names_types_defaults(self):
254
- return self._identifier_from_signature(self._full_signature())
255
-
256
- def _full_signature(self):
257
- sig = []
258
- for name, _type, _default in zip(
259
- self._arg_names, self._arg_types, self._arg_defaults
260
- ):
261
- s = f"{name} {_type}"
262
- if _default:
263
- if _is_signature_type_a_string(_type):
264
- _default = f"'{_default}'"
265
- s += f" default {_default}"
266
- sig.append(s)
267
- return sig
268
-
269
- @property
270
- def identifier_for_sql(self):
271
- return self._identifier_from_signature(self._full_signature(), for_sql=True)
272
-
273
- @classmethod
274
- def from_definition(cls, udf_sproc: FunctionOrProcedure):
275
- names = []
276
- types = []
277
- defaults = []
278
- if udf_sproc.signature and udf_sproc.signature != "null":
279
- for arg in udf_sproc.signature:
280
- names.append(arg.name)
281
- types.append(arg.arg_type)
282
- defaults.append(arg.default)
283
-
284
- identifier = FQN.from_identifier_model(udf_sproc).using_context()
285
- return cls(identifier, names, types, defaults)
286
-
287
-
288
- def _compare_imports(
289
- resource_json: dict, imports: List[str], artifact_file: str
290
- ) -> bool:
291
- pattern = re.compile(r"(?:\[@?\w+_\w+\.)?(\w+(?:/\w+)+\.\w+)(?:\])?")
292
-
293
- project_imports = {
294
- imp
295
- for import_string in [*imports, artifact_file]
296
- for imp in pattern.findall(import_string.lower())
297
- }
298
-
299
- if "imports" not in resource_json.keys():
300
- object_imports = set()
301
- else:
302
- object_imports = {
303
- imp.lower()
304
- for imp in pattern.findall(resource_json.get("imports", "").lower())
305
- }
306
-
307
- return project_imports != object_imports
@@ -1,109 +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
- from typing import Dict, List, Optional
19
-
20
- from snowflake.cli.api.constants import ObjectType
21
- from snowflake.cli.plugins.snowpark.common import (
22
- SnowparkObjectManager,
23
- UdfSprocIdentifier,
24
- )
25
- from snowflake.connector.cursor import SnowflakeCursor
26
-
27
- log = logging.getLogger(__name__)
28
-
29
-
30
- class FunctionManager(SnowparkObjectManager):
31
- @property
32
- def _object_type(self):
33
- return ObjectType.FUNCTION
34
-
35
- @property
36
- def _object_execute(self):
37
- return "select"
38
-
39
- def create_or_replace(
40
- self,
41
- identifier: UdfSprocIdentifier,
42
- return_type: str,
43
- handler: str,
44
- artifact_file: str,
45
- packages: List[str],
46
- imports: List[str],
47
- external_access_integrations: Optional[List[str]] = None,
48
- secrets: Optional[Dict[str, str]] = None,
49
- runtime: Optional[str] = None,
50
- ) -> SnowflakeCursor:
51
- log.debug(
52
- "Creating function %s using @%s",
53
- identifier.identifier_with_arg_names_types_defaults,
54
- artifact_file,
55
- )
56
- query = self.create_query(
57
- identifier,
58
- return_type,
59
- handler,
60
- artifact_file,
61
- packages,
62
- imports,
63
- external_access_integrations,
64
- secrets,
65
- runtime,
66
- )
67
- return self._execute_query(query)
68
-
69
-
70
- class ProcedureManager(SnowparkObjectManager):
71
- @property
72
- def _object_type(self):
73
- return ObjectType.PROCEDURE
74
-
75
- @property
76
- def _object_execute(self):
77
- return "call"
78
-
79
- def create_or_replace(
80
- self,
81
- identifier: UdfSprocIdentifier,
82
- return_type: str,
83
- handler: str,
84
- artifact_file: str,
85
- packages: List[str],
86
- imports: List[str],
87
- external_access_integrations: Optional[List[str]] = None,
88
- secrets: Optional[Dict[str, str]] = None,
89
- runtime: Optional[str] = None,
90
- execute_as_caller: bool = False,
91
- ) -> SnowflakeCursor:
92
- log.debug(
93
- "Creating procedure %s using @%s",
94
- identifier.identifier_with_arg_names_types_defaults,
95
- artifact_file,
96
- )
97
- query = self.create_query(
98
- identifier,
99
- return_type,
100
- handler,
101
- artifact_file,
102
- packages,
103
- imports,
104
- external_access_integrations,
105
- secrets,
106
- runtime,
107
- execute_as_caller,
108
- )
109
- return self._execute_query(query)
@@ -1,156 +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 re
18
- import zipfile
19
- from dataclasses import dataclass
20
- from enum import Enum
21
- from pathlib import Path
22
- from typing import List
23
-
24
- from requirements import requirement
25
-
26
-
27
- class YesNoAsk(Enum):
28
- YES = "yes"
29
- NO = "no"
30
- ASK = "ask"
31
-
32
-
33
- class Requirement(requirement.Requirement):
34
- extra_pattern = re.compile("'([^']*)'")
35
-
36
- def __init__(self, *args, **kwargs):
37
- super().__init__(*args, **kwargs)
38
- self.package_name = None
39
-
40
- @classmethod
41
- def parse_line(cls, line: str) -> Requirement:
42
- if len(line_elements := line.split(";")) > 1:
43
- line = line_elements[0]
44
- result = super().parse_line(line)
45
-
46
- if len(line_elements) > 1:
47
- for element in line_elements[1:]:
48
- if "extra" in element and (extras := cls.extra_pattern.search(element)):
49
- result.extras.extend(extras.groups())
50
-
51
- result.package_name = result.name
52
-
53
- if result.uri and not result.name:
54
- result.name = get_package_name(result.uri)
55
- result.name = cls.standardize_name(result.name)
56
-
57
- return result
58
-
59
- @staticmethod
60
- def standardize_name(name: str) -> str:
61
- return WheelMetadata.to_wheel_name_format(name.lower())
62
-
63
- @property
64
- def formatted_specs(self):
65
- return ",".join(sorted(spec[0] + spec[1] for spec in self.specs))
66
-
67
- @property
68
- def name_and_version(self):
69
- return self.name + self.formatted_specs
70
-
71
-
72
- @dataclass
73
- class RequirementWithFiles:
74
- """A dataclass to hold a requirement and the path to the
75
- downloaded files/folders that belong to it"""
76
-
77
- requirement: Requirement
78
- files: List[str]
79
-
80
-
81
- @dataclass
82
- class RequirementWithWheel:
83
- """A dataclass to hold a requirement and corresponding .whl file."""
84
-
85
- requirement: Requirement
86
- wheel_path: Path | None
87
-
88
- def extract_files(self, destination: Path) -> None:
89
- if self.wheel_path is not None:
90
- zipfile.ZipFile(self.wheel_path).extractall(destination)
91
-
92
- def namelist(self) -> List[str]:
93
- if self.wheel_path is None:
94
- return []
95
- return zipfile.ZipFile(self.wheel_path).namelist()
96
-
97
-
98
- @dataclass
99
- class WheelMetadata:
100
- """A dataclass to hold metadata from .whl file.
101
- [name] is the name of the package standardized according to
102
- https://peps.python.org/pep-0491/#escaping-and-unicode
103
- """
104
-
105
- name: str
106
- wheel_path: Path
107
- dependencies: List[str]
108
-
109
- @classmethod
110
- def from_wheel(cls, wheel_path: Path):
111
- """Parses wheel metadata according to
112
- https://peps.python.org/pep-0491/#file-contents"""
113
- with zipfile.ZipFile(wheel_path, "r") as whl:
114
- metadata_path = [
115
- path for path in whl.namelist() if path.endswith(".dist-info/METADATA")
116
- ]
117
- if len(metadata_path) != 1:
118
- # malformatted wheel package
119
- return None
120
-
121
- root = zipfile.Path(whl)
122
- metadata = (root / metadata_path[0]).read_text(encoding="utf-8")
123
-
124
- dep_keyword = "Requires-Dist:"
125
- dependencies = [
126
- line[len(dep_keyword) :].strip()
127
- for line in metadata.splitlines()
128
- if line.startswith(dep_keyword)
129
- ]
130
- name = cls._get_name_from_wheel_filename(wheel_path.name)
131
- return cls(name=name, wheel_path=wheel_path, dependencies=dependencies)
132
-
133
- @staticmethod
134
- def _get_name_from_wheel_filename(wheel_filename: str) -> str:
135
- # wheel filename is in format {name}-{version}[-{extra info}]
136
- # https://peps.python.org/pep-0491/#file-name-convention
137
- return wheel_filename.split("-")[0]
138
-
139
- @staticmethod
140
- def to_wheel_name_format(package_name: str) -> str:
141
- # https://peps.python.org/pep-0491/#escaping-and-unicode
142
- return re.sub(r"[^\w\d.]+", "_", package_name, re.UNICODE)
143
-
144
-
145
- def get_package_name(name: str) -> str:
146
- if name.lower().startswith(("git+", "http")):
147
- pattern = re.compile(r"github\.com\/[^\/]+\/([^\/][^.@$/]+)")
148
- if match := pattern.search(name):
149
- return match.group(1)
150
- else:
151
- return name
152
-
153
- elif name.endswith(".zip"):
154
- return name.replace(".zip", "")
155
- else:
156
- return name
@@ -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.