snowflake-cli-labs 2.8.0rc1__py3-none-any.whl → 3.0.0__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 (251) hide show
  1. snowflake/cli/__about__.py +1 -1
  2. snowflake/cli/{app → _app}/__main__.py +1 -1
  3. snowflake/cli/{app → _app}/cli_app.py +22 -13
  4. snowflake/cli/{app → _app}/commands_registration/builtin_plugins.py +15 -19
  5. snowflake/cli/{app → _app}/commands_registration/command_plugins_loader.py +9 -9
  6. snowflake/cli/{app → _app}/commands_registration/commands_registration_with_callbacks.py +4 -4
  7. snowflake/cli/{app → _app}/commands_registration/exception_logging.py +2 -2
  8. snowflake/cli/{app → _app}/commands_registration/typer_registration.py +2 -2
  9. snowflake/cli/{app → _app}/dev/docs/commands_docs_generator.py +30 -12
  10. snowflake/cli/{app → _app}/dev/docs/generator.py +3 -3
  11. snowflake/cli/{app → _app}/dev/docs/project_definition_docs_generator.py +4 -4
  12. snowflake/cli/{app → _app}/dev/docs/templates/usage.rst.jinja2 +14 -4
  13. snowflake/cli/{app → _app}/main_typer.py +2 -2
  14. snowflake/cli/{app → _app}/printing.py +2 -2
  15. snowflake/cli/_app/secret.py +9 -0
  16. snowflake/cli/{app → _app}/snow_connector.py +127 -61
  17. snowflake/cli/{app → _app}/telemetry.py +38 -7
  18. snowflake/cli/_app/version_check.py +74 -0
  19. snowflake/cli/{plugins → _plugins}/connection/commands.py +34 -11
  20. snowflake/cli/_plugins/connection/plugin_spec.py +30 -0
  21. snowflake/cli/{plugins → _plugins}/connection/util.py +16 -0
  22. snowflake/cli/{plugins → _plugins}/cortex/commands.py +54 -49
  23. snowflake/cli/{plugins → _plugins}/cortex/constants.py +1 -1
  24. snowflake/cli/{plugins → _plugins}/cortex/manager.py +5 -5
  25. snowflake/cli/{plugins → _plugins}/cortex/plugin_spec.py +1 -1
  26. snowflake/cli/{plugins → _plugins}/git/commands.py +79 -26
  27. snowflake/cli/{plugins → _plugins}/git/manager.py +72 -17
  28. snowflake/cli/{plugins → _plugins}/git/plugin_spec.py +1 -1
  29. snowflake/cli/_plugins/helpers/commands.py +90 -0
  30. snowflake/cli/{plugins/notebook → _plugins/helpers}/plugin_spec.py +1 -1
  31. snowflake/cli/{plugins → _plugins}/init/commands.py +10 -6
  32. snowflake/cli/{plugins → _plugins}/init/plugin_spec.py +1 -1
  33. snowflake/cli/{plugins → _plugins}/nativeapp/artifacts.py +24 -9
  34. snowflake/cli/_plugins/nativeapp/bundle_context.py +31 -0
  35. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/artifact_processor.py +4 -4
  36. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/compiler.py +37 -18
  37. snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +249 -0
  38. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/setup/setup_driver.py.source +5 -2
  39. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/extension_function_utils.py +5 -5
  40. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/models.py +1 -1
  41. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/python_processor.py +29 -34
  42. snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +114 -0
  43. snowflake/cli/{plugins → _plugins}/nativeapp/commands.py +252 -132
  44. snowflake/cli/{plugins → _plugins}/nativeapp/common_flags.py +1 -1
  45. snowflake/cli/_plugins/nativeapp/entities/application.py +878 -0
  46. snowflake/cli/_plugins/nativeapp/entities/application_package.py +1392 -0
  47. snowflake/cli/{plugins → _plugins}/nativeapp/exceptions.py +3 -12
  48. snowflake/cli/_plugins/nativeapp/manager.py +415 -0
  49. snowflake/cli/{plugins/connection → _plugins/nativeapp}/plugin_spec.py +1 -1
  50. snowflake/cli/{plugins → _plugins}/nativeapp/policy.py +3 -0
  51. snowflake/cli/{plugins → _plugins}/nativeapp/project_model.py +36 -20
  52. snowflake/cli/_plugins/nativeapp/run_processor.py +184 -0
  53. snowflake/cli/_plugins/nativeapp/same_account_install_method.py +70 -0
  54. snowflake/cli/_plugins/nativeapp/teardown_processor.py +70 -0
  55. snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +262 -0
  56. snowflake/cli/{plugins → _plugins}/nativeapp/version/commands.py +20 -49
  57. snowflake/cli/_plugins/nativeapp/version/version_processor.py +98 -0
  58. snowflake/cli/{plugins → _plugins}/notebook/commands.py +8 -6
  59. snowflake/cli/{plugins → _plugins}/notebook/manager.py +14 -14
  60. snowflake/cli/{plugins/nativeapp → _plugins/notebook}/plugin_spec.py +1 -1
  61. snowflake/cli/{plugins → _plugins}/notebook/types.py +0 -1
  62. snowflake/cli/{plugins → _plugins}/object/command_aliases.py +6 -5
  63. snowflake/cli/{plugins → _plugins}/object/commands.py +16 -10
  64. snowflake/cli/{plugins → _plugins}/object/manager.py +43 -21
  65. snowflake/cli/{plugins → _plugins}/object/plugin_spec.py +1 -1
  66. snowflake/cli/_plugins/snowpark/commands.py +450 -0
  67. snowflake/cli/_plugins/snowpark/common.py +268 -0
  68. snowflake/cli/{plugins → _plugins}/snowpark/models.py +2 -8
  69. snowflake/cli/{plugins → _plugins}/snowpark/package/anaconda_packages.py +2 -36
  70. snowflake/cli/{plugins → _plugins}/snowpark/package/commands.py +13 -74
  71. snowflake/cli/{plugins → _plugins}/snowpark/package/manager.py +4 -3
  72. snowflake/cli/{plugins → _plugins}/snowpark/package_utils.py +5 -5
  73. snowflake/cli/_plugins/snowpark/plugin_spec.py +30 -0
  74. snowflake/cli/_plugins/snowpark/snowpark_entity.py +29 -0
  75. snowflake/cli/_plugins/snowpark/snowpark_entity_model.py +173 -0
  76. snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +109 -0
  77. snowflake/cli/{plugins → _plugins}/snowpark/snowpark_shared.py +0 -36
  78. snowflake/cli/{plugins → _plugins}/snowpark/zipper.py +16 -8
  79. snowflake/cli/{plugins → _plugins}/spcs/__init__.py +5 -7
  80. snowflake/cli/{plugins → _plugins}/spcs/compute_pool/commands.py +29 -28
  81. snowflake/cli/{plugins → _plugins}/spcs/compute_pool/manager.py +3 -3
  82. snowflake/cli/{plugins → _plugins}/spcs/image_registry/commands.py +3 -3
  83. snowflake/cli/{plugins → _plugins}/spcs/image_repository/commands.py +25 -19
  84. snowflake/cli/{plugins → _plugins}/spcs/image_repository/manager.py +1 -1
  85. snowflake/cli/{plugins → _plugins}/spcs/plugin_spec.py +1 -1
  86. snowflake/cli/{plugins → _plugins}/spcs/services/commands.py +66 -32
  87. snowflake/cli/{plugins → _plugins}/spcs/services/manager.py +43 -5
  88. snowflake/cli/{plugins → _plugins}/sql/commands.py +20 -17
  89. snowflake/cli/{plugins → _plugins}/sql/manager.py +1 -1
  90. snowflake/cli/{plugins → _plugins}/sql/plugin_spec.py +1 -1
  91. snowflake/cli/{plugins → _plugins}/stage/commands.py +20 -17
  92. snowflake/cli/{plugins → _plugins}/stage/diff.py +1 -47
  93. snowflake/cli/{plugins → _plugins}/stage/manager.py +62 -24
  94. snowflake/cli/{plugins → _plugins}/stage/plugin_spec.py +1 -1
  95. snowflake/cli/_plugins/stage/utils.py +54 -0
  96. snowflake/cli/{plugins → _plugins}/streamlit/commands.py +71 -62
  97. snowflake/cli/{plugins → _plugins}/streamlit/manager.py +68 -70
  98. snowflake/cli/_plugins/streamlit/plugin_spec.py +30 -0
  99. snowflake/cli/_plugins/streamlit/streamlit_entity.py +12 -0
  100. snowflake/cli/_plugins/streamlit/streamlit_entity_model.py +66 -0
  101. snowflake/cli/_plugins/workspace/action_context.py +18 -0
  102. snowflake/cli/_plugins/workspace/commands.py +306 -0
  103. snowflake/cli/_plugins/workspace/manager.py +74 -0
  104. snowflake/cli/_plugins/workspace/plugin_spec.py +30 -0
  105. snowflake/cli/api/cli_global_context.py +152 -295
  106. snowflake/cli/api/commands/common.py +25 -0
  107. snowflake/cli/api/commands/decorators.py +19 -4
  108. snowflake/cli/api/commands/experimental_behaviour.py +2 -3
  109. snowflake/cli/api/commands/flags.py +143 -222
  110. snowflake/cli/api/commands/overrideable_parameter.py +143 -0
  111. snowflake/cli/api/commands/snow_typer.py +21 -11
  112. snowflake/cli/api/commands/utils.py +18 -0
  113. snowflake/cli/api/config.py +44 -12
  114. snowflake/cli/api/connections.py +216 -0
  115. snowflake/cli/api/console/abc.py +8 -3
  116. snowflake/cli/api/constants.py +11 -0
  117. snowflake/cli/api/entities/common.py +56 -0
  118. snowflake/cli/api/entities/utils.py +370 -0
  119. snowflake/cli/api/errno.py +1 -0
  120. snowflake/cli/api/exceptions.py +31 -5
  121. snowflake/cli/api/feature_flags.py +0 -1
  122. snowflake/cli/api/identifiers.py +45 -9
  123. snowflake/cli/api/metrics.py +92 -0
  124. snowflake/cli/api/project/definition.py +48 -6
  125. snowflake/cli/api/project/definition_conversion.py +400 -0
  126. snowflake/cli/api/project/definition_manager.py +16 -5
  127. snowflake/cli/api/project/project_verification.py +3 -3
  128. snowflake/cli/api/project/schemas/entities/common.py +91 -16
  129. snowflake/cli/api/project/schemas/entities/entities.py +37 -6
  130. snowflake/cli/api/project/schemas/project_definition.py +180 -49
  131. snowflake/cli/api/project/schemas/updatable_model.py +11 -3
  132. snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
  133. snowflake/cli/api/project/schemas/{identifier_model.py → v1/identifier_model.py} +3 -1
  134. snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
  135. snowflake/cli/api/project/schemas/{native_app → v1/native_app}/application.py +8 -9
  136. snowflake/cli/api/project/schemas/{native_app → v1/native_app}/native_app.py +4 -4
  137. snowflake/cli/api/project/schemas/{native_app → v1/native_app}/package.py +7 -1
  138. snowflake/cli/api/project/schemas/v1/snowpark/__init__.py +0 -0
  139. snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/callable.py +2 -2
  140. snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/snowpark.py +2 -2
  141. snowflake/cli/api/project/schemas/v1/streamlit/__init__.py +0 -0
  142. snowflake/cli/api/project/schemas/{streamlit → v1/streamlit}/streamlit.py +2 -1
  143. snowflake/cli/api/project/util.py +23 -6
  144. snowflake/cli/api/rendering/jinja.py +14 -8
  145. snowflake/cli/api/rendering/project_definition_templates.py +5 -1
  146. snowflake/cli/api/rendering/sql_templates.py +56 -11
  147. snowflake/cli/api/rest_api.py +11 -5
  148. snowflake/cli/api/secure_path.py +16 -18
  149. snowflake/cli/api/secure_utils.py +90 -1
  150. snowflake/cli/api/sql_execution.py +47 -27
  151. snowflake/cli/api/utils/definition_rendering.py +45 -13
  152. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/METADATA +20 -18
  153. snowflake_cli_labs-3.0.0.dist-info/RECORD +242 -0
  154. snowflake_cli_labs-3.0.0.dist-info/entry_points.txt +2 -0
  155. snowflake/cli/api/commands/project_initialisation.py +0 -65
  156. snowflake/cli/api/commands/typer_pre_execute.py +0 -26
  157. snowflake/cli/api/project/schemas/entities/application_entity.py +0 -44
  158. snowflake/cli/api/project/schemas/entities/application_package_entity.py +0 -66
  159. snowflake/cli/app/build_and_push.sh +0 -8
  160. snowflake/cli/plugins/nativeapp/codegen/setup/native_app_setup_processor.py +0 -172
  161. snowflake/cli/plugins/nativeapp/init.py +0 -345
  162. snowflake/cli/plugins/nativeapp/manager.py +0 -823
  163. snowflake/cli/plugins/nativeapp/run_processor.py +0 -389
  164. snowflake/cli/plugins/nativeapp/teardown_processor.py +0 -301
  165. snowflake/cli/plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +0 -135
  166. snowflake/cli/plugins/nativeapp/version/version_processor.py +0 -362
  167. snowflake/cli/plugins/object_stage_deprecated/__init__.py +0 -15
  168. snowflake/cli/plugins/object_stage_deprecated/commands.py +0 -122
  169. snowflake/cli/plugins/object_stage_deprecated/plugin_spec.py +0 -32
  170. snowflake/cli/plugins/snowpark/commands.py +0 -548
  171. snowflake/cli/plugins/snowpark/common.py +0 -307
  172. snowflake/cli/plugins/snowpark/manager.py +0 -109
  173. snowflake/cli/plugins/snowpark/plugin_spec.py +0 -30
  174. snowflake/cli/plugins/snowpark/snowpark_package_paths.py +0 -65
  175. snowflake/cli/plugins/spcs/jobs/commands.py +0 -78
  176. snowflake/cli/plugins/spcs/jobs/manager.py +0 -53
  177. snowflake/cli/plugins/streamlit/__init__.py +0 -13
  178. snowflake/cli/plugins/streamlit/plugin_spec.py +0 -30
  179. snowflake/cli/plugins/workspace/__init__.py +0 -13
  180. snowflake/cli/plugins/workspace/commands.py +0 -35
  181. snowflake/cli/plugins/workspace/plugin_spec.py +0 -30
  182. snowflake/cli/templates/default_snowpark/.gitignore +0 -4
  183. snowflake/cli/templates/default_snowpark/app/common.py +0 -2
  184. snowflake/cli/templates/default_snowpark/app/functions.py +0 -15
  185. snowflake/cli/templates/default_snowpark/app/procedures.py +0 -22
  186. snowflake/cli/templates/default_snowpark/requirements.txt +0 -1
  187. snowflake/cli/templates/default_snowpark/snowflake.yml +0 -23
  188. snowflake/cli/templates/default_streamlit/.gitignore +0 -4
  189. snowflake/cli/templates/default_streamlit/common/hello.py +0 -2
  190. snowflake/cli/templates/default_streamlit/environment.yml +0 -6
  191. snowflake/cli/templates/default_streamlit/pages/my_page.py +0 -3
  192. snowflake/cli/templates/default_streamlit/snowflake.yml +0 -10
  193. snowflake/cli/templates/default_streamlit/streamlit_app.py +0 -4
  194. snowflake_cli_labs-2.8.0rc1.dist-info/RECORD +0 -240
  195. snowflake_cli_labs-2.8.0rc1.dist-info/entry_points.txt +0 -2
  196. /snowflake/cli/{app → _app}/__init__.py +0 -0
  197. /snowflake/cli/{api/project/schemas/native_app → _app/api_impl}/__init__.py +0 -0
  198. /snowflake/cli/{api/project/schemas/snowpark → _app/api_impl/plugin}/__init__.py +0 -0
  199. /snowflake/cli/{app → _app}/api_impl/plugin/plugin_config_provider_impl.py +0 -0
  200. /snowflake/cli/{app → _app}/commands_registration/__init__.py +0 -0
  201. /snowflake/cli/{app → _app}/commands_registration/threadsafe.py +0 -0
  202. /snowflake/cli/{app → _app}/constants.py +0 -0
  203. /snowflake/cli/{api/project/schemas/streamlit → _app/dev}/__init__.py +0 -0
  204. /snowflake/cli/{app → _app}/dev/commands_structure.py +0 -0
  205. /snowflake/cli/{app/api_impl → _app/dev/docs}/__init__.py +0 -0
  206. /snowflake/cli/{app → _app}/dev/docs/project_definition_generate_json_schema.py +0 -0
  207. /snowflake/cli/{app → _app}/dev/docs/template_utils.py +0 -0
  208. /snowflake/cli/{app → _app}/dev/docs/templates/definition_description.rst.jinja2 +0 -0
  209. /snowflake/cli/{app → _app}/dev/docs/templates/overview.rst.jinja2 +0 -0
  210. /snowflake/cli/{app → _app}/dev/pycharm_remote_debug.py +0 -0
  211. /snowflake/cli/{app → _app}/loggers.py +0 -0
  212. /snowflake/cli/{app/api_impl/plugin → _plugins}/__init__.py +0 -0
  213. /snowflake/cli/{app/dev → _plugins/connection}/__init__.py +0 -0
  214. /snowflake/cli/{app/dev/docs → _plugins/cortex}/__init__.py +0 -0
  215. /snowflake/cli/{plugins → _plugins}/cortex/types.py +0 -0
  216. /snowflake/cli/{plugins → _plugins/git}/__init__.py +0 -0
  217. /snowflake/cli/{plugins/connection → _plugins/helpers}/__init__.py +0 -0
  218. /snowflake/cli/{plugins/cortex → _plugins/init}/__init__.py +0 -0
  219. /snowflake/cli/{plugins/git → _plugins/nativeapp}/__init__.py +0 -0
  220. /snowflake/cli/{plugins/init → _plugins/nativeapp/codegen}/__init__.py +0 -0
  221. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/sandbox.py +0 -0
  222. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -0
  223. /snowflake/cli/{plugins → _plugins}/nativeapp/constants.py +0 -0
  224. /snowflake/cli/{templates/default_snowpark/app → _plugins/nativeapp/entities}/__init__.py +0 -0
  225. /snowflake/cli/{plugins → _plugins}/nativeapp/feature_flags.py +0 -0
  226. /snowflake/cli/{plugins → _plugins}/nativeapp/utils.py +0 -0
  227. /snowflake/cli/{plugins/nativeapp → _plugins/nativeapp/version}/__init__.py +0 -0
  228. /snowflake/cli/{plugins/nativeapp/codegen → _plugins/notebook}/__init__.py +0 -0
  229. /snowflake/cli/{plugins → _plugins}/notebook/exceptions.py +0 -0
  230. /snowflake/cli/{plugins/nativeapp/version → _plugins/object}/__init__.py +0 -0
  231. /snowflake/cli/{plugins → _plugins}/object/common.py +0 -0
  232. /snowflake/cli/{plugins/notebook → _plugins/snowpark}/__init__.py +0 -0
  233. /snowflake/cli/{plugins/object → _plugins/snowpark/package}/__init__.py +0 -0
  234. /snowflake/cli/{plugins → _plugins}/snowpark/package/utils.py +0 -0
  235. /snowflake/cli/{plugins → _plugins}/spcs/common.py +0 -0
  236. /snowflake/cli/{plugins/snowpark → _plugins/spcs/compute_pool}/__init__.py +0 -0
  237. /snowflake/cli/{plugins/snowpark/package → _plugins/spcs/image_registry}/__init__.py +0 -0
  238. /snowflake/cli/{plugins → _plugins}/spcs/image_registry/manager.py +0 -0
  239. /snowflake/cli/{plugins/spcs/compute_pool → _plugins/spcs/image_repository}/__init__.py +0 -0
  240. /snowflake/cli/{plugins/spcs/image_registry → _plugins/spcs/services}/__init__.py +0 -0
  241. /snowflake/cli/{plugins/spcs/image_repository → _plugins/sql}/__init__.py +0 -0
  242. /snowflake/cli/{plugins → _plugins}/sql/snowsql_templating.py +0 -0
  243. /snowflake/cli/{plugins/spcs/jobs → _plugins/stage}/__init__.py +0 -0
  244. /snowflake/cli/{plugins → _plugins}/stage/md5.py +0 -0
  245. /snowflake/cli/{plugins/spcs/services → _plugins/streamlit}/__init__.py +0 -0
  246. /snowflake/cli/{plugins/sql → _plugins/workspace}/__init__.py +0 -0
  247. /snowflake/cli/{plugins/stage → api/project/schemas/entities}/__init__.py +0 -0
  248. /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/path_mapping.py +0 -0
  249. /snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/argument.py +0 -0
  250. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/WHEEL +0 -0
  251. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0.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,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.api.plugins.command import (
16
- SNOWCLI_ROOT_COMMAND_PATH,
17
- CommandSpec,
18
- CommandType,
19
- plugin_hook_impl,
20
- )
21
- from snowflake.cli.plugins.snowpark import commands
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,65 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from dataclasses import dataclass
16
-
17
- from snowflake.cli.api.project.schemas.snowpark.snowpark import Snowpark
18
- from snowflake.cli.api.secure_path import SecurePath
19
-
20
- _DEFINED_REQUIREMENTS = "requirements.txt"
21
- _REQUIREMENTS_SNOWFLAKE = "requirements.snowflake.txt"
22
-
23
-
24
- @dataclass
25
- class SnowparkPackagePaths:
26
- source: SecurePath
27
- artifact_file: SecurePath
28
- defined_requirements_file: SecurePath = SecurePath(_DEFINED_REQUIREMENTS)
29
- snowflake_requirements_file: SecurePath = SecurePath(_REQUIREMENTS_SNOWFLAKE)
30
-
31
- @classmethod
32
- def for_snowpark_project(
33
- cls, project_root: SecurePath, snowpark_project_definition: Snowpark
34
- ) -> "SnowparkPackagePaths":
35
- defined_source_path = SecurePath(snowpark_project_definition.src)
36
- return cls(
37
- source=cls._get_snowpark_project_source_absolute_path(
38
- project_root=project_root,
39
- defined_source_path=defined_source_path,
40
- ),
41
- artifact_file=cls._get_snowpark_project_artifact_absolute_path(
42
- project_root=project_root,
43
- defined_source_path=defined_source_path,
44
- ),
45
- defined_requirements_file=project_root / _DEFINED_REQUIREMENTS,
46
- snowflake_requirements_file=project_root / _REQUIREMENTS_SNOWFLAKE,
47
- )
48
-
49
- @classmethod
50
- def _get_snowpark_project_source_absolute_path(
51
- cls, project_root: SecurePath, defined_source_path: SecurePath
52
- ) -> SecurePath:
53
- if defined_source_path.path.is_absolute():
54
- return defined_source_path
55
- return SecurePath((project_root / defined_source_path.path).path.resolve())
56
-
57
- @classmethod
58
- def _get_snowpark_project_artifact_absolute_path(
59
- cls, project_root: SecurePath, defined_source_path: SecurePath
60
- ) -> SecurePath:
61
- source_path = cls._get_snowpark_project_source_absolute_path(
62
- project_root=project_root, defined_source_path=defined_source_path
63
- )
64
- artifact_file = project_root / (source_path.path.name + ".zip")
65
- return artifact_file
@@ -1,78 +0,0 @@
1
- # Copyright (c) 2024 Snowflake Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- import sys
16
- from pathlib import Path
17
-
18
- import typer
19
- from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
20
- from snowflake.cli.api.output.types import CommandResult, SingleQueryResult
21
- from snowflake.cli.plugins.spcs.common import print_log_lines
22
- from snowflake.cli.plugins.spcs.jobs.manager import JobManager
23
-
24
- app = SnowTyperFactory(
25
- name="job",
26
- help="Manages Snowpark jobs.",
27
- is_hidden=lambda: True,
28
- )
29
-
30
-
31
- @app.command(requires_connection=True)
32
- def create(
33
- compute_pool: str = typer.Option(
34
- ..., "--compute-pool", help="Name of the pool in which to run the job."
35
- ),
36
- spec_path: Path = typer.Option(
37
- ...,
38
- "--spec-path",
39
- help="Path to the `spec.yaml` file containing the job details.",
40
- file_okay=True,
41
- dir_okay=False,
42
- exists=True,
43
- ),
44
- **options,
45
- ) -> CommandResult:
46
- """
47
- Creates a job to run in a compute pool.
48
- """
49
- cursor = JobManager().create(compute_pool=compute_pool, spec_path=spec_path)
50
- return SingleQueryResult(cursor)
51
-
52
-
53
- @app.command(requires_connection=True)
54
- def logs(
55
- identifier: str = typer.Argument(..., help="Job id"),
56
- container_name: str = typer.Option(
57
- ..., "--container-name", help="Name of the container."
58
- ),
59
- **options,
60
- ):
61
- """
62
- Retrieves local logs from a job container.
63
- """
64
- results = JobManager().logs(job_name=identifier, container_name=container_name)
65
- cursor = results.fetchone()
66
- logs = next(iter(cursor)).split("\n")
67
- print_log_lines(sys.stdout, identifier, "0", logs)
68
-
69
-
70
- @app.command(requires_connection=True)
71
- def status(
72
- identifier: str = typer.Argument(..., help="ID of the job."), **options
73
- ) -> CommandResult:
74
- """
75
- Returns the status of a named Snowpark Container Services job.
76
- """
77
- cursor = JobManager().status(job_name=identifier)
78
- return SingleQueryResult(cursor)
@@ -1,53 +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 pathlib import Path
16
-
17
- from snowflake.cli.api.constants import DEFAULT_SIZE_LIMIT_MB
18
- from snowflake.cli.api.secure_path import SecurePath
19
- from snowflake.cli.api.sql_execution import SqlExecutionMixin
20
- from snowflake.connector.cursor import SnowflakeCursor
21
-
22
-
23
- class JobManager(SqlExecutionMixin):
24
- def create(self, compute_pool: str, spec_path: Path) -> SnowflakeCursor:
25
- spec = self._read_yaml(spec_path)
26
- return self._execute_schema_query(
27
- f"""\
28
- EXECUTE SERVICE
29
- IN COMPUTE POOL {compute_pool}
30
- FROM SPECIFICATION $$
31
- {spec}
32
- $$
33
- """
34
- )
35
-
36
- def _read_yaml(self, path: Path) -> str:
37
- # TODO(aivanou): Add validation towards schema
38
- # TODO(aivanou): Combine this with service manager
39
- import json
40
-
41
- import yaml
42
-
43
- with SecurePath(path).open("r", read_file_limit_mb=DEFAULT_SIZE_LIMIT_MB) as fh:
44
- data = yaml.safe_load(fh)
45
- return json.dumps(data)
46
-
47
- def status(self, job_name: str) -> SnowflakeCursor:
48
- return self._execute_query(f"CALL SYSTEM$GET_JOB_STATUS('{job_name}')")
49
-
50
- def logs(self, job_name: str, container_name: str):
51
- return self._execute_query(
52
- f"call SYSTEM$GET_JOB_LOGS('{job_name}', '{container_name}')"
53
- )
@@ -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,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.api.plugins.command import (
16
- SNOWCLI_ROOT_COMMAND_PATH,
17
- CommandSpec,
18
- CommandType,
19
- plugin_hook_impl,
20
- )
21
- from snowflake.cli.plugins.streamlit import commands
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
- )