snowflake-cli-labs 2.8.0rc1__py3-none-any.whl → 3.0.0rc1__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 (224) 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 +12 -12
  4. snowflake/cli/{app → _app}/commands_registration/builtin_plugins.py +13 -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 → _app}/snow_connector.py +24 -17
  16. snowflake/cli/{app → _app}/telemetry.py +4 -5
  17. snowflake/cli/{plugins → _plugins}/connection/commands.py +25 -7
  18. snowflake/cli/_plugins/connection/plugin_spec.py +30 -0
  19. snowflake/cli/{plugins → _plugins}/connection/util.py +16 -0
  20. snowflake/cli/{plugins → _plugins}/cortex/commands.py +54 -49
  21. snowflake/cli/{plugins → _plugins}/cortex/constants.py +1 -1
  22. snowflake/cli/{plugins → _plugins}/cortex/manager.py +5 -5
  23. snowflake/cli/{plugins → _plugins}/cortex/plugin_spec.py +1 -1
  24. snowflake/cli/{plugins → _plugins}/git/commands.py +32 -20
  25. snowflake/cli/{plugins → _plugins}/git/manager.py +20 -11
  26. snowflake/cli/{plugins → _plugins}/git/plugin_spec.py +1 -1
  27. snowflake/cli/{plugins → _plugins}/init/commands.py +10 -6
  28. snowflake/cli/{plugins → _plugins}/init/plugin_spec.py +1 -1
  29. snowflake/cli/{plugins → _plugins}/nativeapp/artifacts.py +14 -0
  30. snowflake/cli/_plugins/nativeapp/bundle_context.py +31 -0
  31. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/artifact_processor.py +3 -3
  32. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/compiler.py +32 -18
  33. snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +249 -0
  34. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/setup/setup_driver.py.source +5 -2
  35. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/extension_function_utils.py +4 -4
  36. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/python_processor.py +23 -29
  37. snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +93 -0
  38. snowflake/cli/{plugins → _plugins}/nativeapp/commands.py +171 -42
  39. snowflake/cli/{plugins → _plugins}/nativeapp/common_flags.py +1 -1
  40. snowflake/cli/{plugins → _plugins}/nativeapp/exceptions.py +3 -3
  41. snowflake/cli/{plugins → _plugins}/nativeapp/init.py +1 -1
  42. snowflake/cli/_plugins/nativeapp/manager.py +572 -0
  43. snowflake/cli/{plugins/connection → _plugins/nativeapp}/plugin_spec.py +1 -1
  44. snowflake/cli/{plugins → _plugins}/nativeapp/project_model.py +35 -19
  45. snowflake/cli/{plugins → _plugins}/nativeapp/run_processor.py +25 -23
  46. snowflake/cli/{plugins → _plugins}/nativeapp/teardown_processor.py +24 -110
  47. snowflake/cli/{plugins → _plugins}/nativeapp/v2_conversions/v2_to_v1_decorator.py +47 -28
  48. snowflake/cli/{plugins → _plugins}/nativeapp/version/commands.py +15 -12
  49. snowflake/cli/{plugins → _plugins}/nativeapp/version/version_processor.py +22 -20
  50. snowflake/cli/{plugins → _plugins}/notebook/commands.py +8 -6
  51. snowflake/cli/{plugins → _plugins}/notebook/manager.py +14 -14
  52. snowflake/cli/{plugins → _plugins}/notebook/plugin_spec.py +1 -1
  53. snowflake/cli/{plugins → _plugins}/notebook/types.py +0 -1
  54. snowflake/cli/{plugins → _plugins}/object/command_aliases.py +6 -5
  55. snowflake/cli/{plugins → _plugins}/object/commands.py +16 -10
  56. snowflake/cli/{plugins → _plugins}/object/manager.py +7 -6
  57. snowflake/cli/{plugins → _plugins}/object/plugin_spec.py +1 -1
  58. snowflake/cli/_plugins/snowpark/commands.py +450 -0
  59. snowflake/cli/_plugins/snowpark/common.py +268 -0
  60. snowflake/cli/{plugins → _plugins}/snowpark/models.py +0 -7
  61. snowflake/cli/{plugins → _plugins}/snowpark/package/anaconda_packages.py +2 -36
  62. snowflake/cli/{plugins → _plugins}/snowpark/package/commands.py +13 -74
  63. snowflake/cli/{plugins → _plugins}/snowpark/package/manager.py +4 -3
  64. snowflake/cli/{plugins → _plugins}/snowpark/package_utils.py +5 -5
  65. snowflake/cli/{plugins/nativeapp → _plugins/snowpark}/plugin_spec.py +1 -1
  66. snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +109 -0
  67. snowflake/cli/{plugins → _plugins}/snowpark/snowpark_shared.py +0 -36
  68. snowflake/cli/{plugins → _plugins}/snowpark/zipper.py +16 -8
  69. snowflake/cli/{plugins → _plugins}/spcs/__init__.py +5 -7
  70. snowflake/cli/{plugins → _plugins}/spcs/compute_pool/commands.py +29 -28
  71. snowflake/cli/{plugins → _plugins}/spcs/compute_pool/manager.py +3 -3
  72. snowflake/cli/{plugins → _plugins}/spcs/image_registry/commands.py +3 -3
  73. snowflake/cli/{plugins → _plugins}/spcs/image_repository/commands.py +25 -19
  74. snowflake/cli/{plugins → _plugins}/spcs/image_repository/manager.py +1 -1
  75. snowflake/cli/{plugins → _plugins}/spcs/plugin_spec.py +1 -1
  76. snowflake/cli/{plugins → _plugins}/spcs/services/commands.py +66 -32
  77. snowflake/cli/{plugins → _plugins}/spcs/services/manager.py +43 -5
  78. snowflake/cli/{plugins → _plugins}/sql/commands.py +20 -17
  79. snowflake/cli/{plugins → _plugins}/sql/manager.py +1 -1
  80. snowflake/cli/{plugins → _plugins}/sql/plugin_spec.py +1 -1
  81. snowflake/cli/{plugins → _plugins}/stage/commands.py +20 -17
  82. snowflake/cli/{plugins → _plugins}/stage/diff.py +1 -47
  83. snowflake/cli/{plugins → _plugins}/stage/manager.py +54 -21
  84. snowflake/cli/{plugins → _plugins}/stage/plugin_spec.py +1 -1
  85. snowflake/cli/_plugins/stage/utils.py +54 -0
  86. snowflake/cli/{plugins → _plugins}/streamlit/commands.py +59 -62
  87. snowflake/cli/{plugins → _plugins}/streamlit/manager.py +51 -70
  88. snowflake/cli/_plugins/streamlit/plugin_spec.py +30 -0
  89. snowflake/cli/_plugins/workspace/action_context.py +17 -0
  90. snowflake/cli/_plugins/workspace/commands.py +194 -0
  91. snowflake/cli/_plugins/workspace/manager.py +73 -0
  92. snowflake/cli/{plugins → _plugins}/workspace/plugin_spec.py +1 -1
  93. snowflake/cli/api/cli_global_context.py +40 -13
  94. snowflake/cli/api/commands/common.py +25 -0
  95. snowflake/cli/api/commands/decorators.py +5 -4
  96. snowflake/cli/api/commands/experimental_behaviour.py +2 -3
  97. snowflake/cli/api/commands/flags.py +97 -179
  98. snowflake/cli/api/commands/overrideable_parameter.py +143 -0
  99. snowflake/cli/api/commands/snow_typer.py +14 -6
  100. snowflake/cli/api/commands/typer_pre_execute.py +3 -3
  101. snowflake/cli/api/commands/utils.py +18 -0
  102. snowflake/cli/api/config.py +18 -5
  103. snowflake/cli/api/console/abc.py +5 -2
  104. snowflake/cli/api/constants.py +11 -0
  105. snowflake/cli/api/entities/application_entity.py +12 -0
  106. snowflake/cli/api/entities/application_package_entity.py +553 -0
  107. snowflake/cli/api/entities/common.py +51 -0
  108. snowflake/cli/api/entities/snowpark_entity.py +29 -0
  109. snowflake/cli/api/entities/streamlit_entity.py +12 -0
  110. snowflake/cli/api/entities/utils.py +357 -0
  111. snowflake/cli/api/exceptions.py +31 -5
  112. snowflake/cli/api/feature_flags.py +0 -1
  113. snowflake/cli/api/identifiers.py +41 -9
  114. snowflake/cli/api/project/definition.py +37 -6
  115. snowflake/cli/api/project/definition_conversion.py +194 -0
  116. snowflake/cli/api/project/definition_manager.py +12 -1
  117. snowflake/cli/api/project/project_verification.py +3 -3
  118. snowflake/cli/api/project/schemas/entities/{application_entity.py → application_entity_model.py} +21 -9
  119. snowflake/cli/api/project/schemas/entities/{application_package_entity.py → application_package_entity_model.py} +43 -15
  120. snowflake/cli/api/project/schemas/entities/common.py +80 -6
  121. snowflake/cli/api/project/schemas/entities/entities.py +38 -8
  122. snowflake/cli/api/project/schemas/entities/snowpark_entity.py +176 -0
  123. snowflake/cli/api/project/schemas/entities/streamlit_entity_model.py +73 -0
  124. snowflake/cli/api/project/schemas/identifier_model.py +10 -1
  125. snowflake/cli/api/project/schemas/native_app/application.py +8 -9
  126. snowflake/cli/api/project/schemas/native_app/package.py +7 -1
  127. snowflake/cli/api/project/schemas/project_definition.py +98 -27
  128. snowflake/cli/api/project/schemas/updatable_model.py +11 -3
  129. snowflake/cli/api/project/util.py +23 -6
  130. snowflake/cli/api/rendering/jinja.py +14 -8
  131. snowflake/cli/api/rendering/project_definition_templates.py +1 -1
  132. snowflake/cli/api/rendering/sql_templates.py +43 -11
  133. snowflake/cli/api/secure_path.py +16 -18
  134. snowflake/cli/api/secure_utils.py +90 -1
  135. snowflake/cli/api/sql_execution.py +48 -19
  136. snowflake/cli/api/utils/definition_rendering.py +18 -8
  137. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0rc1.dist-info}/METADATA +13 -13
  138. snowflake_cli_labs-3.0.0rc1.dist-info/RECORD +236 -0
  139. snowflake_cli_labs-3.0.0rc1.dist-info/entry_points.txt +2 -0
  140. snowflake/cli/api/commands/project_initialisation.py +0 -65
  141. snowflake/cli/app/build_and_push.sh +0 -8
  142. snowflake/cli/plugins/nativeapp/codegen/setup/native_app_setup_processor.py +0 -172
  143. snowflake/cli/plugins/nativeapp/manager.py +0 -823
  144. snowflake/cli/plugins/object_stage_deprecated/__init__.py +0 -15
  145. snowflake/cli/plugins/object_stage_deprecated/commands.py +0 -122
  146. snowflake/cli/plugins/object_stage_deprecated/plugin_spec.py +0 -32
  147. snowflake/cli/plugins/snowpark/commands.py +0 -548
  148. snowflake/cli/plugins/snowpark/common.py +0 -307
  149. snowflake/cli/plugins/snowpark/manager.py +0 -109
  150. snowflake/cli/plugins/snowpark/plugin_spec.py +0 -30
  151. snowflake/cli/plugins/snowpark/snowpark_package_paths.py +0 -65
  152. snowflake/cli/plugins/spcs/jobs/commands.py +0 -78
  153. snowflake/cli/plugins/spcs/jobs/manager.py +0 -53
  154. snowflake/cli/plugins/streamlit/plugin_spec.py +0 -30
  155. snowflake/cli/plugins/workspace/commands.py +0 -35
  156. snowflake/cli/templates/default_snowpark/.gitignore +0 -4
  157. snowflake/cli/templates/default_snowpark/app/__init__.py +0 -0
  158. snowflake/cli/templates/default_snowpark/app/common.py +0 -2
  159. snowflake/cli/templates/default_snowpark/app/functions.py +0 -15
  160. snowflake/cli/templates/default_snowpark/app/procedures.py +0 -22
  161. snowflake/cli/templates/default_snowpark/requirements.txt +0 -1
  162. snowflake/cli/templates/default_snowpark/snowflake.yml +0 -23
  163. snowflake/cli/templates/default_streamlit/.gitignore +0 -4
  164. snowflake/cli/templates/default_streamlit/common/hello.py +0 -2
  165. snowflake/cli/templates/default_streamlit/environment.yml +0 -6
  166. snowflake/cli/templates/default_streamlit/pages/my_page.py +0 -3
  167. snowflake/cli/templates/default_streamlit/snowflake.yml +0 -10
  168. snowflake/cli/templates/default_streamlit/streamlit_app.py +0 -4
  169. snowflake_cli_labs-2.8.0rc1.dist-info/RECORD +0 -240
  170. snowflake_cli_labs-2.8.0rc1.dist-info/entry_points.txt +0 -2
  171. /snowflake/cli/{app → _app}/__init__.py +0 -0
  172. /snowflake/cli/{app → _app}/api_impl/__init__.py +0 -0
  173. /snowflake/cli/{app → _app}/api_impl/plugin/__init__.py +0 -0
  174. /snowflake/cli/{app → _app}/api_impl/plugin/plugin_config_provider_impl.py +0 -0
  175. /snowflake/cli/{app → _app}/commands_registration/__init__.py +0 -0
  176. /snowflake/cli/{app → _app}/commands_registration/threadsafe.py +0 -0
  177. /snowflake/cli/{app → _app}/constants.py +0 -0
  178. /snowflake/cli/{app → _app}/dev/__init__.py +0 -0
  179. /snowflake/cli/{app → _app}/dev/commands_structure.py +0 -0
  180. /snowflake/cli/{app → _app}/dev/docs/__init__.py +0 -0
  181. /snowflake/cli/{app → _app}/dev/docs/project_definition_generate_json_schema.py +0 -0
  182. /snowflake/cli/{app → _app}/dev/docs/template_utils.py +0 -0
  183. /snowflake/cli/{app → _app}/dev/docs/templates/definition_description.rst.jinja2 +0 -0
  184. /snowflake/cli/{app → _app}/dev/docs/templates/overview.rst.jinja2 +0 -0
  185. /snowflake/cli/{app → _app}/dev/pycharm_remote_debug.py +0 -0
  186. /snowflake/cli/{app → _app}/loggers.py +0 -0
  187. /snowflake/cli/{plugins → _plugins}/__init__.py +0 -0
  188. /snowflake/cli/{plugins → _plugins}/connection/__init__.py +0 -0
  189. /snowflake/cli/{plugins → _plugins}/cortex/__init__.py +0 -0
  190. /snowflake/cli/{plugins → _plugins}/cortex/types.py +0 -0
  191. /snowflake/cli/{plugins → _plugins}/git/__init__.py +0 -0
  192. /snowflake/cli/{plugins → _plugins}/init/__init__.py +0 -0
  193. /snowflake/cli/{plugins → _plugins}/nativeapp/__init__.py +0 -0
  194. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/__init__.py +0 -0
  195. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/sandbox.py +0 -0
  196. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -0
  197. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/models.py +0 -0
  198. /snowflake/cli/{plugins → _plugins}/nativeapp/constants.py +0 -0
  199. /snowflake/cli/{plugins → _plugins}/nativeapp/feature_flags.py +0 -0
  200. /snowflake/cli/{plugins → _plugins}/nativeapp/policy.py +0 -0
  201. /snowflake/cli/{plugins → _plugins}/nativeapp/utils.py +0 -0
  202. /snowflake/cli/{plugins → _plugins}/nativeapp/version/__init__.py +0 -0
  203. /snowflake/cli/{plugins → _plugins}/notebook/__init__.py +0 -0
  204. /snowflake/cli/{plugins → _plugins}/notebook/exceptions.py +0 -0
  205. /snowflake/cli/{plugins → _plugins}/object/__init__.py +0 -0
  206. /snowflake/cli/{plugins → _plugins}/object/common.py +0 -0
  207. /snowflake/cli/{plugins → _plugins}/snowpark/__init__.py +0 -0
  208. /snowflake/cli/{plugins → _plugins}/snowpark/package/__init__.py +0 -0
  209. /snowflake/cli/{plugins → _plugins}/snowpark/package/utils.py +0 -0
  210. /snowflake/cli/{plugins → _plugins}/spcs/common.py +0 -0
  211. /snowflake/cli/{plugins → _plugins}/spcs/compute_pool/__init__.py +0 -0
  212. /snowflake/cli/{plugins → _plugins}/spcs/image_registry/__init__.py +0 -0
  213. /snowflake/cli/{plugins → _plugins}/spcs/image_registry/manager.py +0 -0
  214. /snowflake/cli/{plugins → _plugins}/spcs/image_repository/__init__.py +0 -0
  215. /snowflake/cli/{plugins/spcs/jobs → _plugins/spcs/services}/__init__.py +0 -0
  216. /snowflake/cli/{plugins/spcs/services → _plugins/sql}/__init__.py +0 -0
  217. /snowflake/cli/{plugins → _plugins}/sql/snowsql_templating.py +0 -0
  218. /snowflake/cli/{plugins/sql → _plugins/stage}/__init__.py +0 -0
  219. /snowflake/cli/{plugins → _plugins}/stage/md5.py +0 -0
  220. /snowflake/cli/{plugins/stage → _plugins/streamlit}/__init__.py +0 -0
  221. /snowflake/cli/{plugins/streamlit → _plugins/workspace}/__init__.py +0 -0
  222. /snowflake/cli/{plugins/workspace → api/project/schemas/entities}/__init__.py +0 -0
  223. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0rc1.dist-info}/WHEEL +0 -0
  224. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0rc1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,194 @@
1
+ import logging
2
+ from pathlib import Path
3
+ from typing import Any, Dict, Literal, Optional
4
+
5
+ from click import ClickException
6
+ from snowflake.cli._plugins.snowpark.common import is_name_a_templated_one
7
+ from snowflake.cli.api.constants import (
8
+ DEFAULT_ENV_FILE,
9
+ DEFAULT_PAGES_DIR,
10
+ PROJECT_TEMPLATE_VARIABLE_OPENING,
11
+ SNOWPARK_SHARED_MIXIN,
12
+ )
13
+ from snowflake.cli.api.project.schemas.project_definition import (
14
+ ProjectDefinition,
15
+ ProjectDefinitionV2,
16
+ )
17
+ from snowflake.cli.api.project.schemas.snowpark.callable import (
18
+ FunctionSchema,
19
+ ProcedureSchema,
20
+ )
21
+ from snowflake.cli.api.project.schemas.snowpark.snowpark import Snowpark
22
+ from snowflake.cli.api.project.schemas.streamlit.streamlit import Streamlit
23
+
24
+ log = logging.getLogger(__name__)
25
+
26
+
27
+ def convert_project_definition_to_v2(
28
+ pd: ProjectDefinition, accept_templates: bool = False
29
+ ) -> ProjectDefinitionV2:
30
+ _check_if_project_definition_meets_requirements(pd, accept_templates)
31
+
32
+ snowpark_data = convert_snowpark_to_v2_data(pd.snowpark) if pd.snowpark else {}
33
+ streamlit_data = convert_streamlit_to_v2_data(pd.streamlit) if pd.streamlit else {}
34
+ envs = convert_envs_to_v2(pd)
35
+
36
+ data = {
37
+ "definition_version": "2",
38
+ "entities": get_list_of_all_entities(
39
+ snowpark_data.get("entities", {}), streamlit_data.get("entities", {})
40
+ ),
41
+ "mixins": snowpark_data.get("mixins", None),
42
+ "env": envs,
43
+ }
44
+
45
+ return ProjectDefinitionV2(**data)
46
+
47
+
48
+ def convert_snowpark_to_v2_data(snowpark: Snowpark) -> Dict[str, Any]:
49
+ artifact_mapping = {"src": snowpark.src}
50
+ if snowpark.project_name:
51
+ artifact_mapping["dest"] = snowpark.project_name
52
+
53
+ data: dict = {
54
+ "mixins": {
55
+ SNOWPARK_SHARED_MIXIN: {
56
+ "stage": snowpark.stage_name,
57
+ "artifacts": [artifact_mapping],
58
+ }
59
+ },
60
+ "entities": {},
61
+ }
62
+
63
+ for index, entity in enumerate([*snowpark.procedures, *snowpark.functions]):
64
+ identifier = {"name": entity.name}
65
+ if entity.database is not None:
66
+ identifier["database"] = entity.database
67
+ if entity.schema_name is not None:
68
+ identifier["schema"] = entity.schema_name
69
+
70
+ entity_name = (
71
+ f"snowpark_entity_{index}"
72
+ if is_name_a_templated_one(entity.name)
73
+ else entity.name
74
+ )
75
+
76
+ if entity_name in data["entities"]:
77
+ raise ClickException(
78
+ f"Entity with name {entity_name} seems to be duplicated. Please rename it and try again."
79
+ )
80
+
81
+ v2_entity = {
82
+ "type": "function" if isinstance(entity, FunctionSchema) else "procedure",
83
+ "stage": snowpark.stage_name,
84
+ "handler": entity.handler,
85
+ "returns": entity.returns,
86
+ "signature": entity.signature,
87
+ "runtime": entity.runtime,
88
+ "external_access_integrations": entity.external_access_integrations,
89
+ "secrets": entity.secrets,
90
+ "imports": entity.imports,
91
+ "identifier": identifier,
92
+ "meta": {"use_mixins": [SNOWPARK_SHARED_MIXIN]},
93
+ }
94
+ if isinstance(entity, ProcedureSchema):
95
+ v2_entity["execute_as_caller"] = entity.execute_as_caller
96
+
97
+ data["entities"][entity_name] = v2_entity
98
+
99
+ return data
100
+
101
+
102
+ def convert_streamlit_to_v2_data(streamlit: Streamlit):
103
+ # Process env file and pages dir
104
+ environment_file = _process_streamlit_files(streamlit.env_file, "environment")
105
+ pages_dir = _process_streamlit_files(streamlit.pages_dir, "pages")
106
+
107
+ # Build V2 definition
108
+ artifacts = [
109
+ streamlit.main_file,
110
+ environment_file,
111
+ pages_dir,
112
+ ]
113
+ artifacts = [a for a in artifacts if a is not None]
114
+
115
+ if streamlit.additional_source_files:
116
+ artifacts.extend(streamlit.additional_source_files)
117
+
118
+ identifier = {"name": streamlit.name}
119
+ if streamlit.schema_name:
120
+ identifier["schema"] = streamlit.schema_name
121
+ if streamlit.database:
122
+ identifier["database"] = streamlit.database
123
+
124
+ streamlit_name = (
125
+ "streamlit_entity_1"
126
+ if is_name_a_templated_one(streamlit.name)
127
+ else streamlit.name
128
+ )
129
+
130
+ data = {
131
+ "entities": {
132
+ streamlit_name: {
133
+ "type": "streamlit",
134
+ "identifier": identifier,
135
+ "title": streamlit.title,
136
+ "query_warehouse": streamlit.query_warehouse,
137
+ "main_file": str(streamlit.main_file),
138
+ "pages_dir": str(streamlit.pages_dir),
139
+ "stage": streamlit.stage,
140
+ "artifacts": artifacts,
141
+ }
142
+ }
143
+ }
144
+ return data
145
+
146
+
147
+ def convert_envs_to_v2(pd: ProjectDefinition):
148
+ if hasattr(pd, "env") and pd.env:
149
+ data = {k: v for k, v in pd.env.items()}
150
+ return data
151
+ return None
152
+
153
+
154
+ def _check_if_project_definition_meets_requirements(
155
+ pd: ProjectDefinition, accept_templates: bool
156
+ ):
157
+ if pd.meets_version_requirement("2"):
158
+ raise ClickException("Project definition is already at version 2.")
159
+
160
+ if PROJECT_TEMPLATE_VARIABLE_OPENING in str(pd):
161
+ if not accept_templates:
162
+ raise ClickException(
163
+ "Project definition contains templates. They may not be migrated correctly, and require manual migration."
164
+ "You can try again with --accept-templates option, to attempt automatic migration."
165
+ )
166
+ log.warning(
167
+ "Your V1 definition contains templates. We cannot guarantee the correctness of the migration."
168
+ )
169
+ if pd.native_app:
170
+ raise ClickException(
171
+ "Your project file contains a native app definition. Conversion of Native apps is not yet supported"
172
+ )
173
+
174
+
175
+ def _process_streamlit_files(
176
+ file_name: Optional[str], file_type: Literal["pages", "environment"]
177
+ ):
178
+ default = DEFAULT_PAGES_DIR if file_type == "pages" else DEFAULT_ENV_FILE
179
+
180
+ if file_name and not Path(file_name).exists():
181
+ raise ClickException(f"Provided file {file_name} does not exist")
182
+ elif file_name is None and Path(default).exists():
183
+ file_name = default
184
+ return file_name
185
+
186
+
187
+ def get_list_of_all_entities(
188
+ snowpark_entities: Dict[str, Any], streamlit_entities: Dict[str, Any]
189
+ ):
190
+ if snowpark_entities.keys() & streamlit_entities.keys():
191
+ raise ClickException(
192
+ "In your project, streamlit and snowpark entities share the same name. Please rename them and try again."
193
+ )
194
+ return snowpark_entities | streamlit_entities
@@ -20,7 +20,10 @@ from pathlib import Path
20
20
  from typing import List, Optional
21
21
 
22
22
  from snowflake.cli.api.project.definition import ProjectProperties, load_project
23
- from snowflake.cli.api.project.schemas.project_definition import ProjectDefinitionV1
23
+ from snowflake.cli.api.project.schemas.project_definition import (
24
+ ProjectDefinition,
25
+ ProjectDefinitionV1,
26
+ )
24
27
  from snowflake.cli.api.utils.types import Context
25
28
 
26
29
 
@@ -125,10 +128,18 @@ class DefinitionManager:
125
128
  def _project_properties(self) -> ProjectProperties:
126
129
  return load_project(self._project_config_paths, self._context_overrides)
127
130
 
131
+ @functools.cached_property
132
+ def _raw_project_data(self) -> ProjectProperties:
133
+ return load_project(self._project_config_paths, {}, False)
134
+
128
135
  @functools.cached_property
129
136
  def project_definition(self) -> ProjectDefinitionV1:
130
137
  return self._project_properties.project_definition
131
138
 
139
+ @functools.cached_property
140
+ def unrendered_project_definition(self) -> ProjectDefinition:
141
+ return self._raw_project_data.project_definition
142
+
132
143
  @functools.cached_property
133
144
  def template_context(self) -> Context:
134
145
  return self._project_properties.project_context
@@ -11,13 +11,13 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
-
15
- from snowflake.cli.api.cli_global_context import cli_context
14
+ from snowflake.cli.api.cli_global_context import get_cli_context
16
15
  from snowflake.cli.api.exceptions import NoProjectDefinitionError
17
16
 
18
17
 
19
18
  def assert_project_type(project_type: str):
19
+ cli_context = get_cli_context()
20
20
  if not getattr(cli_context.project_definition, project_type, None):
21
21
  raise NoProjectDefinitionError(
22
- project_type=project_type, project_file=cli_context.project_root
22
+ project_type=project_type, project_root=cli_context.project_root
23
23
  )
@@ -16,25 +16,24 @@ from __future__ import annotations
16
16
 
17
17
  from typing import Literal, Optional
18
18
 
19
- from pydantic import Field
20
- from snowflake.cli.api.project.schemas.entities.application_package_entity import (
21
- ApplicationPackageEntity,
19
+ from pydantic import Field, field_validator
20
+ from snowflake.cli.api.project.schemas.entities.application_package_entity_model import (
21
+ ApplicationPackageEntityModel,
22
22
  )
23
23
  from snowflake.cli.api.project.schemas.entities.common import (
24
- EntityBase,
24
+ EntityModelBase,
25
25
  TargetField,
26
26
  )
27
+ from snowflake.cli.api.project.schemas.identifier_model import Identifier
27
28
  from snowflake.cli.api.project.schemas.updatable_model import (
28
29
  DiscriminatorField,
29
30
  )
31
+ from snowflake.cli.api.project.util import append_test_resource_suffix
30
32
 
31
33
 
32
- class ApplicationEntity(EntityBase):
34
+ class ApplicationEntityModel(EntityModelBase):
33
35
  type: Literal["application"] = DiscriminatorField() # noqa A003
34
- name: str = Field(
35
- title="Name of the application created when this entity is deployed"
36
- )
37
- from_: TargetField[ApplicationPackageEntity] = Field(
36
+ from_: TargetField[ApplicationPackageEntityModel] = Field(
38
37
  alias="from",
39
38
  title="An application package this entity should be created from",
40
39
  )
@@ -42,3 +41,16 @@ class ApplicationEntity(EntityBase):
42
41
  title="Whether to enable debug mode when using a named stage to create an application object",
43
42
  default=None,
44
43
  )
44
+
45
+ @field_validator("identifier")
46
+ @classmethod
47
+ def append_test_resource_suffix_to_identifier(
48
+ cls, input_value: Identifier | str
49
+ ) -> Identifier | str:
50
+ identifier = (
51
+ input_value.name if isinstance(input_value, Identifier) else input_value
52
+ )
53
+ with_suffix = append_test_resource_suffix(identifier)
54
+ if isinstance(input_value, Identifier):
55
+ return input_value.model_copy(update=dict(name=with_suffix))
56
+ return with_suffix
@@ -14,40 +14,38 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from pathlib import Path
18
17
  from typing import List, Literal, Optional, Union
19
18
 
20
- from pydantic import Field
19
+ from pydantic import Field, field_validator
21
20
  from snowflake.cli.api.project.schemas.entities.common import (
22
- EntityBase,
21
+ EntityModelBase,
23
22
  )
23
+ from snowflake.cli.api.project.schemas.identifier_model import Identifier
24
24
  from snowflake.cli.api.project.schemas.native_app.package import DistributionOptions
25
25
  from snowflake.cli.api.project.schemas.native_app.path_mapping import PathMapping
26
26
  from snowflake.cli.api.project.schemas.updatable_model import (
27
27
  DiscriminatorField,
28
28
  IdentifierField,
29
29
  )
30
+ from snowflake.cli.api.project.util import append_test_resource_suffix
30
31
 
31
32
 
32
- class ApplicationPackageEntity(EntityBase):
33
+ class ApplicationPackageEntityModel(EntityModelBase):
33
34
  type: Literal["application package"] = DiscriminatorField() # noqa: A003
34
- name: str = Field(
35
- title="Name of the application package created when this entity is deployed"
36
- )
37
- artifacts: List[Union[PathMapping, Path]] = Field(
35
+ artifacts: List[Union[PathMapping, str]] = Field(
38
36
  title="List of paths or file source/destination pairs to add to the deploy root",
39
37
  )
40
- bundle_root: Optional[Path] = Field(
38
+ bundle_root: Optional[str] = Field(
41
39
  title="Folder at the root of your project where artifacts necessary to perform the bundle step are stored.",
42
- default=Path("output/bundle/"),
40
+ default="output/bundle/",
43
41
  )
44
- deploy_root: Optional[Path] = Field(
42
+ deploy_root: Optional[str] = Field(
45
43
  title="Folder at the root of your project where the build step copies the artifacts",
46
- default=Path("output/deploy/"),
44
+ default="output/deploy/",
47
45
  )
48
- generated_root: Optional[Path] = Field(
46
+ generated_root: Optional[str] = Field(
49
47
  title="Subdirectory of the deploy root where files generated by the Snowflake CLI will be written.",
50
- default=Path("__generated/"),
48
+ default="__generated/",
51
49
  )
52
50
  stage: Optional[str] = IdentifierField(
53
51
  title="Identifier of the stage that stores the application artifacts.",
@@ -61,6 +59,36 @@ class ApplicationPackageEntity(EntityBase):
61
59
  title="Distribution of the application package created by the Snowflake CLI",
62
60
  default="internal",
63
61
  )
64
- manifest: Path = Field(
62
+ manifest: str = Field(
65
63
  title="Path to manifest.yml",
66
64
  )
65
+
66
+ @field_validator("identifier")
67
+ @classmethod
68
+ def append_test_resource_suffix_to_identifier(
69
+ cls, input_value: Identifier | str
70
+ ) -> Identifier | str:
71
+ identifier = (
72
+ input_value.name if isinstance(input_value, Identifier) else input_value
73
+ )
74
+ with_suffix = append_test_resource_suffix(identifier)
75
+ if isinstance(input_value, Identifier):
76
+ return input_value.model_copy(update=dict(name=with_suffix))
77
+ return with_suffix
78
+
79
+ @field_validator("artifacts")
80
+ @classmethod
81
+ def transform_artifacts(
82
+ cls, orig_artifacts: List[Union[PathMapping, str]]
83
+ ) -> List[PathMapping]:
84
+ transformed_artifacts = []
85
+ if orig_artifacts is None:
86
+ return transformed_artifacts
87
+
88
+ for artifact in orig_artifacts:
89
+ if isinstance(artifact, PathMapping):
90
+ transformed_artifacts.append(artifact)
91
+ else:
92
+ transformed_artifacts.append(PathMapping(src=artifact))
93
+
94
+ return transformed_artifacts
@@ -15,18 +15,25 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  from abc import ABC
18
- from typing import Generic, List, Optional, TypeVar
18
+ from typing import Generic, List, Optional, TypeVar, Union
19
19
 
20
- from pydantic import Field
21
- from snowflake.cli.api.project.schemas.native_app.application import (
22
- PostDeployHook,
23
- )
20
+ from pydantic import Field, PrivateAttr, field_validator
21
+ from snowflake.cli.api.identifiers import FQN
22
+ from snowflake.cli.api.project.schemas.identifier_model import Identifier
24
23
  from snowflake.cli.api.project.schemas.updatable_model import (
25
24
  IdentifierField,
26
25
  UpdatableModel,
27
26
  )
28
27
 
29
28
 
29
+ class SqlScriptHookType(UpdatableModel):
30
+ sql_script: str = Field(title="SQL file path relative to the project root")
31
+
32
+
33
+ # Currently sql_script is the only supported hook type. Change to a Union once other hook types are added
34
+ PostDeployHook = SqlScriptHookType
35
+
36
+
30
37
  class MetaField(UpdatableModel):
31
38
  warehouse: Optional[str] = IdentifierField(
32
39
  title="Warehouse used to run the scripts", default=None
@@ -39,6 +46,19 @@ class MetaField(UpdatableModel):
39
46
  title="Actions that will be executed after the application object is created/upgraded",
40
47
  default=None,
41
48
  )
49
+ use_mixins: Optional[List[str]] = Field(
50
+ title="Name of the mixin used to fill the entity fields",
51
+ default=None,
52
+ )
53
+
54
+ @field_validator("use_mixins", mode="before")
55
+ @classmethod
56
+ def ensure_use_mixins_is_a_list(
57
+ cls, mixins: Optional[str | List[str]]
58
+ ) -> Optional[List[str]]:
59
+ if isinstance(mixins, str):
60
+ return [mixins]
61
+ return mixins
42
62
 
43
63
 
44
64
  class DefaultsField(UpdatableModel):
@@ -53,12 +73,38 @@ class DefaultsField(UpdatableModel):
53
73
  )
54
74
 
55
75
 
56
- class EntityBase(ABC, UpdatableModel):
76
+ class EntityModelBase(ABC, UpdatableModel):
57
77
  @classmethod
58
78
  def get_type(cls) -> str:
59
79
  return cls.model_fields["type"].annotation.__args__[0]
60
80
 
61
81
  meta: Optional[MetaField] = Field(title="Meta fields", default=None)
82
+ identifier: Optional[Union[Identifier | str]] = Field(
83
+ title="Entity identifier", default=None
84
+ )
85
+ # Set by parent model in post validation. To reference it use `entity_id`.
86
+ _entity_id: str = PrivateAttr(default=None)
87
+
88
+ @property
89
+ def entity_id(self):
90
+ return self._entity_id
91
+
92
+ def set_entity_id(self, value: str):
93
+ self._entity_id = value
94
+
95
+ def validate_identifier(self):
96
+ """Helper that's used by ProjectDefinition validator."""
97
+ if not self._entity_id and not self.identifier:
98
+ raise ValueError("Missing entity identifier")
99
+
100
+ @property
101
+ def fqn(self) -> FQN:
102
+ if isinstance(self.identifier, str):
103
+ return FQN.from_string(self.identifier)
104
+ if isinstance(self.identifier, Identifier):
105
+ return FQN.from_identifier_model_v2(self.identifier)
106
+ if self.entity_id:
107
+ return FQN.from_string(self.entity_id)
62
108
 
63
109
 
64
110
  TargetType = TypeVar("TargetType")
@@ -76,3 +122,31 @@ class TargetField(UpdatableModel, Generic[TargetType]):
76
122
  them in __pydantic_generic_metadata__
77
123
  """
78
124
  return self.__pydantic_generic_metadata__["args"][0]
125
+
126
+
127
+ from typing import Dict, List, Optional
128
+
129
+ from pydantic import Field
130
+
131
+
132
+ class ExternalAccessBaseModel:
133
+ external_access_integrations: Optional[List[str]] = Field(
134
+ title="Names of external access integrations needed for this entity to access external networks",
135
+ default=[],
136
+ )
137
+ secrets: Optional[Dict[str, str]] = Field(
138
+ title="Assigns the names of secrets to variables so that you can use the variables to reference the secrets",
139
+ default={},
140
+ )
141
+
142
+ def get_external_access_integrations_sql(self) -> str | None:
143
+ if not self.external_access_integrations:
144
+ return None
145
+ external_access_integration_name = ", ".join(self.external_access_integrations)
146
+ return f"external_access_integrations=({external_access_integration_name})"
147
+
148
+ def get_secrets_sql(self) -> str | None:
149
+ if not self.secrets:
150
+ return None
151
+ secrets = ", ".join(f"'{key}'={value}" for key, value in self.secrets.items())
152
+ return f"secrets=({secrets})"
@@ -14,17 +14,47 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Union, get_args
17
+ from typing import Dict, List, Union, get_args
18
18
 
19
- from snowflake.cli.api.project.schemas.entities.application_entity import (
20
- ApplicationEntity,
21
- )
22
- from snowflake.cli.api.project.schemas.entities.application_package_entity import (
19
+ from snowflake.cli.api.entities.application_entity import ApplicationEntity
20
+ from snowflake.cli.api.entities.application_package_entity import (
23
21
  ApplicationPackageEntity,
24
22
  )
23
+ from snowflake.cli.api.entities.snowpark_entity import FunctionEntity, ProcedureEntity
24
+ from snowflake.cli.api.entities.streamlit_entity import StreamlitEntity
25
+ from snowflake.cli.api.project.schemas.entities.application_entity_model import (
26
+ ApplicationEntityModel,
27
+ )
28
+ from snowflake.cli.api.project.schemas.entities.application_package_entity_model import (
29
+ ApplicationPackageEntityModel,
30
+ )
31
+ from snowflake.cli.api.project.schemas.entities.snowpark_entity import (
32
+ FunctionEntityModel,
33
+ ProcedureEntityModel,
34
+ )
35
+ from snowflake.cli.api.project.schemas.entities.streamlit_entity_model import (
36
+ StreamlitEntityModel,
37
+ )
25
38
 
26
- Entity = Union[ApplicationEntity, ApplicationPackageEntity]
39
+ Entity = Union[
40
+ ApplicationEntity,
41
+ ApplicationPackageEntity,
42
+ StreamlitEntity,
43
+ ProcedureEntity,
44
+ FunctionEntity,
45
+ ]
46
+ EntityModel = Union[
47
+ ApplicationEntityModel,
48
+ ApplicationPackageEntityModel,
49
+ StreamlitEntityModel,
50
+ FunctionEntityModel,
51
+ ProcedureEntityModel,
52
+ ]
27
53
 
28
- ALL_ENTITIES = [*get_args(Entity)]
54
+ ALL_ENTITIES: List[Entity] = [*get_args(Entity)]
55
+ ALL_ENTITY_MODELS: List[EntityModel] = [*get_args(EntityModel)]
29
56
 
30
- v2_entity_types_map = {e.get_type(): e for e in ALL_ENTITIES}
57
+ v2_entity_model_types_map = {e.get_type(): e for e in ALL_ENTITY_MODELS}
58
+ v2_entity_model_to_entity_map: Dict[EntityModel, Entity] = {
59
+ e.get_entity_model_type(): e for e in ALL_ENTITIES
60
+ }