snowflake-cli-labs 2.8.0rc1__py3-none-any.whl → 3.0.0rc0__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 (219) 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 +6 -6
  16. snowflake/cli/{app → _app}/telemetry.py +4 -5
  17. snowflake/cli/{plugins → _plugins}/connection/commands.py +22 -5
  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 +6 -5
  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 +16 -18
  33. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/setup/native_app_setup_processor.py +24 -28
  34. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/extension_function_utils.py +4 -4
  35. snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/python_processor.py +20 -24
  36. snowflake/cli/{plugins → _plugins}/nativeapp/commands.py +171 -42
  37. snowflake/cli/{plugins → _plugins}/nativeapp/common_flags.py +1 -1
  38. snowflake/cli/{plugins → _plugins}/nativeapp/init.py +1 -1
  39. snowflake/cli/_plugins/nativeapp/manager.py +601 -0
  40. snowflake/cli/{plugins/connection → _plugins/nativeapp}/plugin_spec.py +1 -1
  41. snowflake/cli/{plugins → _plugins}/nativeapp/project_model.py +34 -11
  42. snowflake/cli/{plugins → _plugins}/nativeapp/run_processor.py +25 -23
  43. snowflake/cli/{plugins → _plugins}/nativeapp/teardown_processor.py +8 -8
  44. snowflake/cli/{plugins → _plugins}/nativeapp/v2_conversions/v2_to_v1_decorator.py +47 -28
  45. snowflake/cli/{plugins → _plugins}/nativeapp/version/commands.py +15 -12
  46. snowflake/cli/{plugins → _plugins}/nativeapp/version/version_processor.py +22 -20
  47. snowflake/cli/{plugins → _plugins}/notebook/commands.py +8 -6
  48. snowflake/cli/{plugins → _plugins}/notebook/manager.py +14 -14
  49. snowflake/cli/{plugins → _plugins}/notebook/plugin_spec.py +1 -1
  50. snowflake/cli/{plugins → _plugins}/notebook/types.py +0 -1
  51. snowflake/cli/{plugins → _plugins}/object/command_aliases.py +6 -5
  52. snowflake/cli/{plugins → _plugins}/object/commands.py +16 -10
  53. snowflake/cli/{plugins → _plugins}/object/manager.py +7 -6
  54. snowflake/cli/{plugins → _plugins}/object/plugin_spec.py +1 -1
  55. snowflake/cli/_plugins/snowpark/commands.py +510 -0
  56. snowflake/cli/_plugins/snowpark/common.py +252 -0
  57. snowflake/cli/{plugins → _plugins}/snowpark/models.py +0 -7
  58. snowflake/cli/{plugins → _plugins}/snowpark/package/anaconda_packages.py +1 -1
  59. snowflake/cli/{plugins → _plugins}/snowpark/package/commands.py +13 -74
  60. snowflake/cli/{plugins → _plugins}/snowpark/package/manager.py +4 -3
  61. snowflake/cli/{plugins → _plugins}/snowpark/package_utils.py +5 -5
  62. snowflake/cli/{plugins/nativeapp → _plugins/snowpark}/plugin_spec.py +1 -1
  63. snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +109 -0
  64. snowflake/cli/{plugins → _plugins}/snowpark/snowpark_shared.py +0 -36
  65. snowflake/cli/{plugins → _plugins}/snowpark/zipper.py +16 -8
  66. snowflake/cli/{plugins → _plugins}/spcs/__init__.py +5 -7
  67. snowflake/cli/{plugins → _plugins}/spcs/compute_pool/commands.py +29 -28
  68. snowflake/cli/{plugins → _plugins}/spcs/compute_pool/manager.py +3 -3
  69. snowflake/cli/{plugins → _plugins}/spcs/image_registry/commands.py +3 -3
  70. snowflake/cli/{plugins → _plugins}/spcs/image_repository/commands.py +25 -19
  71. snowflake/cli/{plugins → _plugins}/spcs/image_repository/manager.py +1 -1
  72. snowflake/cli/{plugins → _plugins}/spcs/plugin_spec.py +1 -1
  73. snowflake/cli/{plugins → _plugins}/spcs/services/commands.py +66 -32
  74. snowflake/cli/{plugins → _plugins}/spcs/services/manager.py +43 -5
  75. snowflake/cli/{plugins → _plugins}/sql/commands.py +19 -15
  76. snowflake/cli/{plugins → _plugins}/sql/manager.py +1 -1
  77. snowflake/cli/{plugins → _plugins}/sql/plugin_spec.py +1 -1
  78. snowflake/cli/{plugins → _plugins}/stage/commands.py +20 -17
  79. snowflake/cli/{plugins → _plugins}/stage/diff.py +1 -47
  80. snowflake/cli/{plugins → _plugins}/stage/manager.py +8 -6
  81. snowflake/cli/{plugins → _plugins}/stage/plugin_spec.py +1 -1
  82. snowflake/cli/_plugins/stage/utils.py +54 -0
  83. snowflake/cli/_plugins/streamlit/commands.py +242 -0
  84. snowflake/cli/{plugins → _plugins}/streamlit/manager.py +47 -70
  85. snowflake/cli/_plugins/streamlit/plugin_spec.py +30 -0
  86. snowflake/cli/_plugins/workspace/action_context.py +11 -0
  87. snowflake/cli/_plugins/workspace/commands.py +113 -0
  88. snowflake/cli/_plugins/workspace/manager.py +57 -0
  89. snowflake/cli/{plugins → _plugins}/workspace/plugin_spec.py +1 -1
  90. snowflake/cli/api/cli_global_context.py +34 -7
  91. snowflake/cli/api/commands/common.py +25 -0
  92. snowflake/cli/api/commands/decorators.py +4 -3
  93. snowflake/cli/api/commands/experimental_behaviour.py +2 -3
  94. snowflake/cli/api/commands/flags.py +73 -174
  95. snowflake/cli/api/commands/overrideable_parameter.py +143 -0
  96. snowflake/cli/api/commands/snow_typer.py +5 -4
  97. snowflake/cli/api/commands/typer_pre_execute.py +3 -3
  98. snowflake/cli/api/commands/utils.py +18 -0
  99. snowflake/cli/api/config.py +1 -1
  100. snowflake/cli/api/console/abc.py +5 -2
  101. snowflake/cli/api/entities/application_entity.py +12 -0
  102. snowflake/cli/api/entities/application_package_entity.py +260 -0
  103. snowflake/cli/api/entities/common.py +47 -0
  104. snowflake/cli/api/entities/snowpark_entity.py +29 -0
  105. snowflake/cli/api/entities/streamlit_entity.py +12 -0
  106. snowflake/cli/api/entities/utils.py +321 -0
  107. snowflake/cli/api/exceptions.py +19 -3
  108. snowflake/cli/api/feature_flags.py +2 -1
  109. snowflake/cli/api/identifiers.py +41 -9
  110. snowflake/cli/api/project/definition.py +13 -5
  111. snowflake/cli/api/project/definition_manager.py +12 -1
  112. snowflake/cli/api/project/project_verification.py +3 -3
  113. snowflake/cli/api/project/schemas/entities/{application_entity.py → application_entity_model.py} +21 -9
  114. snowflake/cli/api/project/schemas/entities/{application_package_entity.py → application_package_entity_model.py} +26 -15
  115. snowflake/cli/api/project/schemas/entities/common.py +80 -6
  116. snowflake/cli/api/project/schemas/entities/entities.py +38 -8
  117. snowflake/cli/api/project/schemas/entities/snowpark_entity.py +176 -0
  118. snowflake/cli/api/project/schemas/entities/streamlit_entity_model.py +73 -0
  119. snowflake/cli/api/project/schemas/identifier_model.py +10 -1
  120. snowflake/cli/api/project/schemas/native_app/application.py +8 -9
  121. snowflake/cli/api/project/schemas/native_app/package.py +7 -1
  122. snowflake/cli/api/project/schemas/project_definition.py +97 -23
  123. snowflake/cli/api/project/schemas/updatable_model.py +11 -3
  124. snowflake/cli/api/project/util.py +23 -6
  125. snowflake/cli/api/rendering/jinja.py +28 -8
  126. snowflake/cli/api/rendering/sql_templates.py +41 -12
  127. snowflake/cli/api/secure_path.py +3 -0
  128. snowflake/cli/api/sql_execution.py +35 -19
  129. snowflake/cli/api/utils/definition_rendering.py +14 -2
  130. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0rc0.dist-info}/METADATA +12 -12
  131. snowflake_cli_labs-3.0.0rc0.dist-info/RECORD +234 -0
  132. snowflake_cli_labs-3.0.0rc0.dist-info/entry_points.txt +2 -0
  133. snowflake/cli/api/commands/project_initialisation.py +0 -65
  134. snowflake/cli/app/build_and_push.sh +0 -8
  135. snowflake/cli/plugins/nativeapp/manager.py +0 -823
  136. snowflake/cli/plugins/object_stage_deprecated/__init__.py +0 -15
  137. snowflake/cli/plugins/object_stage_deprecated/commands.py +0 -122
  138. snowflake/cli/plugins/object_stage_deprecated/plugin_spec.py +0 -32
  139. snowflake/cli/plugins/snowpark/commands.py +0 -548
  140. snowflake/cli/plugins/snowpark/common.py +0 -307
  141. snowflake/cli/plugins/snowpark/manager.py +0 -109
  142. snowflake/cli/plugins/snowpark/plugin_spec.py +0 -30
  143. snowflake/cli/plugins/snowpark/snowpark_package_paths.py +0 -65
  144. snowflake/cli/plugins/spcs/jobs/commands.py +0 -78
  145. snowflake/cli/plugins/spcs/jobs/manager.py +0 -53
  146. snowflake/cli/plugins/streamlit/commands.py +0 -186
  147. snowflake/cli/plugins/streamlit/plugin_spec.py +0 -30
  148. snowflake/cli/plugins/workspace/commands.py +0 -35
  149. snowflake/cli/templates/default_snowpark/.gitignore +0 -4
  150. snowflake/cli/templates/default_snowpark/app/__init__.py +0 -0
  151. snowflake/cli/templates/default_snowpark/app/common.py +0 -2
  152. snowflake/cli/templates/default_snowpark/app/functions.py +0 -15
  153. snowflake/cli/templates/default_snowpark/app/procedures.py +0 -22
  154. snowflake/cli/templates/default_snowpark/requirements.txt +0 -1
  155. snowflake/cli/templates/default_snowpark/snowflake.yml +0 -23
  156. snowflake/cli/templates/default_streamlit/.gitignore +0 -4
  157. snowflake/cli/templates/default_streamlit/common/hello.py +0 -2
  158. snowflake/cli/templates/default_streamlit/environment.yml +0 -6
  159. snowflake/cli/templates/default_streamlit/pages/my_page.py +0 -3
  160. snowflake/cli/templates/default_streamlit/snowflake.yml +0 -10
  161. snowflake/cli/templates/default_streamlit/streamlit_app.py +0 -4
  162. snowflake_cli_labs-2.8.0rc1.dist-info/RECORD +0 -240
  163. snowflake_cli_labs-2.8.0rc1.dist-info/entry_points.txt +0 -2
  164. /snowflake/cli/{app → _app}/__init__.py +0 -0
  165. /snowflake/cli/{app → _app}/api_impl/__init__.py +0 -0
  166. /snowflake/cli/{app → _app}/api_impl/plugin/__init__.py +0 -0
  167. /snowflake/cli/{app → _app}/api_impl/plugin/plugin_config_provider_impl.py +0 -0
  168. /snowflake/cli/{app → _app}/commands_registration/__init__.py +0 -0
  169. /snowflake/cli/{app → _app}/commands_registration/threadsafe.py +0 -0
  170. /snowflake/cli/{app → _app}/constants.py +0 -0
  171. /snowflake/cli/{app → _app}/dev/__init__.py +0 -0
  172. /snowflake/cli/{app → _app}/dev/commands_structure.py +0 -0
  173. /snowflake/cli/{app → _app}/dev/docs/__init__.py +0 -0
  174. /snowflake/cli/{app → _app}/dev/docs/project_definition_generate_json_schema.py +0 -0
  175. /snowflake/cli/{app → _app}/dev/docs/template_utils.py +0 -0
  176. /snowflake/cli/{app → _app}/dev/docs/templates/definition_description.rst.jinja2 +0 -0
  177. /snowflake/cli/{app → _app}/dev/docs/templates/overview.rst.jinja2 +0 -0
  178. /snowflake/cli/{app → _app}/dev/pycharm_remote_debug.py +0 -0
  179. /snowflake/cli/{app → _app}/loggers.py +0 -0
  180. /snowflake/cli/{plugins → _plugins}/__init__.py +0 -0
  181. /snowflake/cli/{plugins → _plugins}/connection/__init__.py +0 -0
  182. /snowflake/cli/{plugins → _plugins}/cortex/__init__.py +0 -0
  183. /snowflake/cli/{plugins → _plugins}/cortex/types.py +0 -0
  184. /snowflake/cli/{plugins → _plugins}/git/__init__.py +0 -0
  185. /snowflake/cli/{plugins → _plugins}/init/__init__.py +0 -0
  186. /snowflake/cli/{plugins → _plugins}/nativeapp/__init__.py +0 -0
  187. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/__init__.py +0 -0
  188. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/sandbox.py +0 -0
  189. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/setup/setup_driver.py.source +0 -0
  190. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -0
  191. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/models.py +0 -0
  192. /snowflake/cli/{plugins → _plugins}/nativeapp/constants.py +0 -0
  193. /snowflake/cli/{plugins → _plugins}/nativeapp/exceptions.py +0 -0
  194. /snowflake/cli/{plugins → _plugins}/nativeapp/feature_flags.py +0 -0
  195. /snowflake/cli/{plugins → _plugins}/nativeapp/policy.py +0 -0
  196. /snowflake/cli/{plugins → _plugins}/nativeapp/utils.py +0 -0
  197. /snowflake/cli/{plugins → _plugins}/nativeapp/version/__init__.py +0 -0
  198. /snowflake/cli/{plugins → _plugins}/notebook/__init__.py +0 -0
  199. /snowflake/cli/{plugins → _plugins}/notebook/exceptions.py +0 -0
  200. /snowflake/cli/{plugins → _plugins}/object/__init__.py +0 -0
  201. /snowflake/cli/{plugins → _plugins}/object/common.py +0 -0
  202. /snowflake/cli/{plugins → _plugins}/snowpark/__init__.py +0 -0
  203. /snowflake/cli/{plugins → _plugins}/snowpark/package/__init__.py +0 -0
  204. /snowflake/cli/{plugins → _plugins}/snowpark/package/utils.py +0 -0
  205. /snowflake/cli/{plugins → _plugins}/spcs/common.py +0 -0
  206. /snowflake/cli/{plugins → _plugins}/spcs/compute_pool/__init__.py +0 -0
  207. /snowflake/cli/{plugins → _plugins}/spcs/image_registry/__init__.py +0 -0
  208. /snowflake/cli/{plugins → _plugins}/spcs/image_registry/manager.py +0 -0
  209. /snowflake/cli/{plugins → _plugins}/spcs/image_repository/__init__.py +0 -0
  210. /snowflake/cli/{plugins/spcs/jobs → _plugins/spcs/services}/__init__.py +0 -0
  211. /snowflake/cli/{plugins/spcs/services → _plugins/sql}/__init__.py +0 -0
  212. /snowflake/cli/{plugins → _plugins}/sql/snowsql_templating.py +0 -0
  213. /snowflake/cli/{plugins/sql → _plugins/stage}/__init__.py +0 -0
  214. /snowflake/cli/{plugins → _plugins}/stage/md5.py +0 -0
  215. /snowflake/cli/{plugins/stage → _plugins/streamlit}/__init__.py +0 -0
  216. /snowflake/cli/{plugins/streamlit → _plugins/workspace}/__init__.py +0 -0
  217. /snowflake/cli/{plugins/workspace → api/project/schemas/entities}/__init__.py +0 -0
  218. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0rc0.dist-info}/WHEEL +0 -0
  219. {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0rc0.dist-info}/licenses/LICENSE +0 -0
@@ -15,22 +15,25 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import logging
18
- import os
19
18
  from pathlib import Path
20
19
  from typing import List, Optional
21
20
 
21
+ from snowflake.cli._plugins.connection.util import (
22
+ MissingConnectionAccountError,
23
+ MissingConnectionRegionError,
24
+ make_snowsight_url,
25
+ )
26
+ from snowflake.cli._plugins.stage.manager import StageManager
22
27
  from snowflake.cli.api.commands.experimental_behaviour import (
23
28
  experimental_behaviour_enabled,
24
29
  )
30
+ from snowflake.cli.api.console import cli_console
25
31
  from snowflake.cli.api.feature_flags import FeatureFlag
26
32
  from snowflake.cli.api.identifiers import FQN
27
- from snowflake.cli.api.sql_execution import SqlExecutionMixin
28
- from snowflake.cli.plugins.connection.util import (
29
- MissingConnectionAccountError,
30
- MissingConnectionRegionError,
31
- make_snowsight_url,
33
+ from snowflake.cli.api.project.schemas.entities.streamlit_entity_model import (
34
+ StreamlitEntityModel,
32
35
  )
33
- from snowflake.cli.plugins.stage.manager import StageManager
36
+ from snowflake.cli.api.sql_execution import SqlExecutionMixin
34
37
  from snowflake.connector.cursor import SnowflakeCursor
35
38
  from snowflake.connector.errors import ProgrammingError
36
39
 
@@ -46,39 +49,31 @@ class StreamlitManager(SqlExecutionMixin):
46
49
  def _put_streamlit_files(
47
50
  self,
48
51
  root_location: str,
49
- main_file: Path,
50
- environment_file: Optional[Path],
51
- pages_dir: Optional[Path],
52
- additional_source_files: Optional[List[Path]],
52
+ artifacts: Optional[List[Path]] = None,
53
53
  ):
54
+ cli_console.step(f"Deploying files to {root_location}")
55
+ if not artifacts:
56
+ return
54
57
  stage_manager = StageManager()
55
-
56
- stage_manager.put(main_file, root_location, 4, True)
57
-
58
- if environment_file and environment_file.exists():
59
- stage_manager.put(environment_file, root_location, 4, True)
60
-
61
- if pages_dir and pages_dir.exists():
62
- stage_manager.put(pages_dir / "*.py", f"{root_location}/pages", 4, True)
63
-
64
- if additional_source_files:
65
- for file in additional_source_files:
66
- if os.sep in str(file):
67
- destination = f"{root_location}/{str(file.parent)}"
68
- else:
69
- destination = root_location
70
- stage_manager.put(file, destination, 4, True)
58
+ for file in artifacts:
59
+ if file.is_dir():
60
+ stage_manager.put(
61
+ f"{file.joinpath('*')}", f"{root_location}/{file}", 4, True
62
+ )
63
+ elif len(file.parts) > 1:
64
+ stage_manager.put(file, f"{root_location}/{file.parent}", 4, True)
65
+ else:
66
+ stage_manager.put(file, root_location, 4, True)
71
67
 
72
68
  def _create_streamlit(
73
69
  self,
74
- streamlit_id: FQN,
75
- main_file: Path,
70
+ streamlit: StreamlitEntityModel,
76
71
  replace: Optional[bool] = None,
77
72
  experimental: Optional[bool] = None,
78
- query_warehouse: Optional[str] = None,
79
73
  from_stage_name: Optional[str] = None,
80
- title: Optional[str] = None,
81
74
  ):
75
+ streamlit_id = streamlit.fqn.using_connection(self._conn)
76
+ cli_console.step(f"Creating {streamlit_id} Streamlit")
82
77
  query = []
83
78
  if replace:
84
79
  query.append(f"CREATE OR REPLACE STREAMLIT {streamlit_id.sql_identifier}")
@@ -96,28 +91,24 @@ class StreamlitManager(SqlExecutionMixin):
96
91
  if from_stage_name:
97
92
  query.append(f"ROOT_LOCATION = '{from_stage_name}'")
98
93
 
99
- query.append(f"MAIN_FILE = '{main_file.name}'")
94
+ query.append(f"MAIN_FILE = '{streamlit.main_file}'")
100
95
 
101
- if query_warehouse:
102
- query.append(f"QUERY_WAREHOUSE = {query_warehouse}")
103
- if title:
104
- query.append(f"TITLE = '{title}'")
96
+ if streamlit.query_warehouse:
97
+ query.append(f"QUERY_WAREHOUSE = {streamlit.query_warehouse}")
98
+ if streamlit.title:
99
+ query.append(f"TITLE = '{streamlit.title}'")
100
+
101
+ if streamlit.external_access_integrations:
102
+ query.append(streamlit.get_external_access_integrations_sql())
103
+
104
+ if streamlit.secrets:
105
+ query.append(streamlit.get_secrets_sql())
105
106
 
106
107
  self._execute_query("\n".join(query))
107
108
 
108
- def deploy(
109
- self,
110
- streamlit_id: FQN,
111
- main_file: Path,
112
- environment_file: Optional[Path] = None,
113
- pages_dir: Optional[Path] = None,
114
- stage_name: Optional[str] = None,
115
- query_warehouse: Optional[str] = None,
116
- replace: Optional[bool] = False,
117
- additional_source_files: Optional[List[Path]] = None,
118
- title: Optional[str] = None,
119
- **options,
120
- ):
109
+ def deploy(self, streamlit: StreamlitEntityModel, replace: bool = False):
110
+ streamlit_id = streamlit.fqn.using_connection(self._conn)
111
+
121
112
  # for backwards compatibility - quoted stage path might be case-sensitive
122
113
  # https://docs.snowflake.com/en/sql-reference/identifiers-syntax#double-quoted-identifiers
123
114
  streamlit_name_for_root_location = streamlit_id.name
@@ -134,12 +125,9 @@ class StreamlitManager(SqlExecutionMixin):
134
125
  # TODO: Support from_stage
135
126
  # from_stage_stmt = f"FROM_STAGE = '{stage_name}'" if stage_name else ""
136
127
  self._create_streamlit(
137
- streamlit_id,
138
- main_file,
128
+ streamlit=streamlit,
139
129
  replace=replace,
140
- query_warehouse=query_warehouse,
141
130
  experimental=True,
142
- title=title,
143
131
  )
144
132
  try:
145
133
  if use_versioned_stage:
@@ -169,10 +157,7 @@ class StreamlitManager(SqlExecutionMixin):
169
157
 
170
158
  self._put_streamlit_files(
171
159
  root_location,
172
- main_file,
173
- environment_file,
174
- pages_dir,
175
- additional_source_files,
160
+ streamlit.artifacts,
176
161
  )
177
162
  else:
178
163
  """
@@ -182,31 +167,23 @@ class StreamlitManager(SqlExecutionMixin):
182
167
  """
183
168
  stage_manager = StageManager()
184
169
 
185
- stage_name = stage_name or "streamlit"
170
+ stage_name = streamlit.stage or "streamlit"
186
171
  stage_name = FQN.from_string(stage_name).using_connection(self._conn)
187
172
 
188
- stage_manager.create(stage_name=stage_name)
173
+ cli_console.step(f"Creating {stage_name} stage")
174
+ stage_manager.create(fqn=stage_name)
189
175
 
190
176
  root_location = stage_manager.get_standard_stage_prefix(
191
177
  f"{stage_name}/{streamlit_name_for_root_location}"
192
178
  )
193
179
 
194
- self._put_streamlit_files(
195
- root_location,
196
- main_file,
197
- environment_file,
198
- pages_dir,
199
- additional_source_files,
200
- )
180
+ self._put_streamlit_files(root_location, streamlit.artifacts)
201
181
 
202
182
  self._create_streamlit(
203
- streamlit_id,
204
- main_file,
183
+ streamlit=streamlit,
205
184
  replace=replace,
206
- query_warehouse=query_warehouse,
207
185
  from_stage_name=root_location,
208
186
  experimental=False,
209
- title=title,
210
187
  )
211
188
 
212
189
  return self.get_url(streamlit_name=streamlit_id)
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2024 Snowflake Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from snowflake.cli._plugins.streamlit import commands
16
+ from snowflake.cli.api.plugins.command import (
17
+ SNOWCLI_ROOT_COMMAND_PATH,
18
+ CommandSpec,
19
+ CommandType,
20
+ plugin_hook_impl,
21
+ )
22
+
23
+
24
+ @plugin_hook_impl
25
+ def command_spec():
26
+ return CommandSpec(
27
+ parent_command_path=SNOWCLI_ROOT_COMMAND_PATH,
28
+ command_type=CommandType.COMMAND_GROUP,
29
+ typer_instance=commands.app.create_instance(),
30
+ )
@@ -0,0 +1,11 @@
1
+ from dataclasses import dataclass
2
+ from pathlib import Path
3
+
4
+
5
+ @dataclass
6
+ class ActionContext:
7
+ """
8
+ An object that is passed to each action when called by WorkspaceManager
9
+ """
10
+
11
+ project_root: Path
@@ -0,0 +1,113 @@
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
+
19
+ import typer
20
+ import yaml
21
+ from click import ClickException
22
+ from snowflake.cli._plugins.nativeapp.artifacts import BundleMap
23
+ from snowflake.cli._plugins.snowpark.commands import migrate_v1_snowpark_to_v2
24
+ from snowflake.cli._plugins.streamlit.commands import migrate_v1_streamlit_to_v2
25
+ from snowflake.cli._plugins.workspace.manager import WorkspaceManager
26
+ from snowflake.cli.api.cli_global_context import get_cli_context
27
+ from snowflake.cli.api.commands.decorators import with_project_definition
28
+ from snowflake.cli.api.commands.snow_typer import SnowTyper
29
+ from snowflake.cli.api.entities.common import EntityActions
30
+ from snowflake.cli.api.output.types import MessageResult
31
+ from snowflake.cli.api.project.definition_manager import DefinitionManager
32
+ from snowflake.cli.api.secure_path import SecurePath
33
+
34
+ ws = SnowTyper(
35
+ name="ws",
36
+ help="Deploy and interact with snowflake.yml-based entities.",
37
+ )
38
+ log = logging.getLogger(__name__)
39
+
40
+
41
+ @ws.command()
42
+ def migrate(
43
+ accept_templates: bool = typer.Option(
44
+ False, "-t", "--accept-templates", help="Allows the migration of templates."
45
+ ),
46
+ **options,
47
+ ):
48
+ """Migrates the Snowpark and Streamlit project definition files form V1 to V2."""
49
+ pd = DefinitionManager().unrendered_project_definition
50
+
51
+ if pd.meets_version_requirement("2"):
52
+ return MessageResult("Project definition is already at version 2.")
53
+
54
+ if "<% ctx." in str(pd):
55
+ if not accept_templates:
56
+ raise ClickException(
57
+ "Project definition contains templates. They may not be migrated correctly, and require manual migration."
58
+ "You can try again with --accept-templates option, to attempt automatic migration."
59
+ )
60
+ log.warning(
61
+ "Your V1 definition contains templates. We cannot guarantee the correctness of the migration."
62
+ )
63
+
64
+ if pd.streamlit:
65
+ pd_v2 = migrate_v1_streamlit_to_v2(pd)
66
+ elif pd.snowpark:
67
+ pd_v2 = migrate_v1_snowpark_to_v2(pd)
68
+ else:
69
+ raise ValueError(
70
+ "Only Snowpark and Streamlit entities are supported for migration."
71
+ )
72
+
73
+ SecurePath("snowflake.yml").rename("snowflake_V1.yml")
74
+ with open("snowflake.yml", "w") as file:
75
+ yaml.dump(
76
+ pd_v2.model_dump(
77
+ exclude_unset=True, exclude_none=True, mode="json", by_alias=True
78
+ ),
79
+ file,
80
+ )
81
+ return MessageResult("Project definition migrated to version 2.")
82
+
83
+
84
+ @ws.command(requires_connection=True, hidden=True)
85
+ @with_project_definition()
86
+ def validate(
87
+ **options,
88
+ ):
89
+ """Validates the project definition file."""
90
+ # If we get to this point, @with_project_definition() has already validated the PDF schema
91
+ return MessageResult("Project definition is valid.")
92
+
93
+
94
+ @ws.command(requires_connection=True, hidden=True)
95
+ @with_project_definition()
96
+ def bundle(
97
+ entity_id: str = typer.Option(
98
+ help=f"""The ID of the entity you want to bundle.""",
99
+ ),
100
+ **options,
101
+ ):
102
+ """
103
+ Prepares a local folder with the configured artifacts of the specified entity.
104
+ """
105
+
106
+ cli_context = get_cli_context()
107
+ ws = WorkspaceManager(
108
+ project_definition=cli_context.project_definition,
109
+ project_root=cli_context.project_root,
110
+ )
111
+
112
+ bundle_map: BundleMap = ws.perform_action(entity_id, EntityActions.BUNDLE)
113
+ return MessageResult(f"Bundle generated at {bundle_map.deploy_root()}")
@@ -0,0 +1,57 @@
1
+ from pathlib import Path
2
+ from typing import Dict
3
+
4
+ from snowflake.cli._plugins.workspace.action_context import ActionContext
5
+ from snowflake.cli.api.entities.common import EntityActions
6
+ from snowflake.cli.api.exceptions import InvalidProjectDefinitionVersionError
7
+ from snowflake.cli.api.project.schemas.entities.entities import (
8
+ Entity,
9
+ v2_entity_model_to_entity_map,
10
+ )
11
+ from snowflake.cli.api.project.schemas.project_definition import (
12
+ DefinitionV20,
13
+ ProjectDefinition,
14
+ )
15
+
16
+
17
+ class WorkspaceManager:
18
+ """
19
+ Instantiates entity instances from entity models, providing higher-order functionality on entity compositions.
20
+ """
21
+
22
+ def __init__(self, project_definition: ProjectDefinition, project_root: Path):
23
+ if not project_definition.meets_version_requirement("2"):
24
+ raise InvalidProjectDefinitionVersionError(
25
+ "2.x", project_definition.definition_version
26
+ )
27
+ self._entities_cache: Dict[str, Entity] = {}
28
+ self._project_definition: DefinitionV20 = project_definition
29
+ self._project_root = project_root
30
+
31
+ def get_entity(self, entity_id: str):
32
+ """
33
+ Returns an entity instance with the given ID. If exists, reuses the previously returned instance, or instantiates a new one otherwise.
34
+ """
35
+ if entity_id in self._entities_cache:
36
+ return self._entities_cache[entity_id]
37
+ entity_model = self._project_definition.entities.get(entity_id, None)
38
+ if entity_model is None:
39
+ raise ValueError(f"No such entity ID: {entity_id}")
40
+ entity_model_cls = entity_model.__class__
41
+ entity_cls = v2_entity_model_to_entity_map[entity_model_cls]
42
+ self._entities_cache[entity_id] = entity_cls(entity_model)
43
+ return self._entities_cache[entity_id]
44
+
45
+ def perform_action(self, entity_id: str, action: EntityActions):
46
+ """
47
+ Instantiates an entity of the given ID and calls the given action on it.
48
+ """
49
+ entity = self.get_entity(entity_id)
50
+ if entity.supports(action):
51
+ action_ctx = ActionContext(project_root=self.project_root())
52
+ return entity.perform(action, action_ctx)
53
+ else:
54
+ raise ValueError(f'This entity type does not support "{action.value}"')
55
+
56
+ def project_root(self) -> Path:
57
+ return self._project_root
@@ -12,13 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from snowflake.cli._plugins.workspace import commands
15
16
  from snowflake.cli.api.plugins.command import (
16
17
  SNOWCLI_ROOT_COMMAND_PATH,
17
18
  CommandSpec,
18
19
  CommandType,
19
20
  plugin_hook_impl,
20
21
  )
21
- from snowflake.cli.plugins.workspace import commands
22
22
 
23
23
 
24
24
  @plugin_hook_impl
@@ -15,13 +15,17 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import re
18
+ import warnings
18
19
  from pathlib import Path
19
- from typing import Callable, Optional
20
+ from typing import TYPE_CHECKING, Callable, Optional
20
21
 
21
22
  from snowflake.cli.api.exceptions import InvalidSchemaError
22
23
  from snowflake.cli.api.output.formats import OutputFormat
23
- from snowflake.cli.api.project.schemas.project_definition import ProjectDefinition
24
24
  from snowflake.connector import SnowflakeConnection
25
+ from snowflake.connector.compat import IS_WINDOWS
26
+
27
+ if TYPE_CHECKING:
28
+ from snowflake.cli.api.project.schemas.project_definition import ProjectDefinition
25
29
 
26
30
  schema_pattern = re.compile(r".+\..+")
27
31
 
@@ -213,7 +217,16 @@ class _ConnectionContext:
213
217
  }
214
218
 
215
219
  def _build_connection(self):
216
- from snowflake.cli.app.snow_connector import connect_to_snowflake
220
+ from snowflake.cli._app.snow_connector import connect_to_snowflake
221
+
222
+ # Ignore warnings about bad owner or permissions on Windows
223
+ # Telemetry omit our warning filter from config.py
224
+ if IS_WINDOWS:
225
+ warnings.filterwarnings(
226
+ action="ignore",
227
+ message="Bad owner or permissions.*",
228
+ module="snowflake.connector.config_manager",
229
+ )
217
230
 
218
231
  return connect_to_snowflake(
219
232
  temporary_connection=self.temporary_connection,
@@ -367,8 +380,8 @@ class _CliGlobalContextAccess:
367
380
  return self._manager.project_definition
368
381
 
369
382
  @property
370
- def project_root(self):
371
- return self._manager.project_root
383
+ def project_root(self) -> Path:
384
+ return Path(self._manager.project_root)
372
385
 
373
386
  @property
374
387
  def template_context(self) -> dict:
@@ -386,5 +399,19 @@ class _CliGlobalContextAccess:
386
399
  return self._manager.output_format == OutputFormat.JSON
387
400
 
388
401
 
389
- cli_context_manager: _CliGlobalContextManager = _CliGlobalContextManager()
390
- cli_context: _CliGlobalContextAccess = _CliGlobalContextAccess(cli_context_manager)
402
+ _CLI_CONTEXT_MANAGER: _CliGlobalContextManager | None = None
403
+ _CLI_CONTEXT: _CliGlobalContextAccess | None = None
404
+
405
+
406
+ def get_cli_context_manager() -> _CliGlobalContextManager:
407
+ global _CLI_CONTEXT_MANAGER
408
+ if _CLI_CONTEXT_MANAGER is None:
409
+ _CLI_CONTEXT_MANAGER = _CliGlobalContextManager()
410
+ return _CLI_CONTEXT_MANAGER
411
+
412
+
413
+ def get_cli_context() -> _CliGlobalContextAccess:
414
+ global _CLI_CONTEXT
415
+ if _CLI_CONTEXT is None:
416
+ _CLI_CONTEXT = _CliGlobalContextAccess(get_cli_context_manager())
417
+ return _CLI_CONTEXT
@@ -0,0 +1,25 @@
1
+ from dataclasses import dataclass
2
+ from enum import Enum
3
+
4
+
5
+ class OnErrorType(Enum):
6
+ """
7
+ Command option values for what to do when an error occurs.
8
+ """
9
+
10
+ BREAK = "break"
11
+ CONTINUE = "continue"
12
+
13
+
14
+ @dataclass
15
+ class Variable:
16
+ """
17
+ Key-value pair dataclass, returned after parsing "key=value" command options.
18
+ """
19
+
20
+ key: str
21
+ value: str
22
+
23
+ def __init__(self, key: str, value: str):
24
+ self.key = key
25
+ self.value = value
@@ -19,7 +19,7 @@ from functools import wraps
19
19
  from inspect import Signature
20
20
  from typing import Callable, Dict, List, Optional, get_type_hints
21
21
 
22
- from snowflake.cli.api.cli_global_context import cli_context
22
+ from snowflake.cli.api.cli_global_context import get_cli_context
23
23
  from snowflake.cli.api.commands.flags import (
24
24
  AccountOption,
25
25
  AuthenticatorOption,
@@ -125,8 +125,9 @@ def with_experimental_behaviour(
125
125
 
126
126
 
127
127
  def _execute_before_command_using_global_options(**options):
128
- from snowflake.cli.app.loggers import create_loggers
128
+ from snowflake.cli._app.loggers import create_loggers
129
129
 
130
+ cli_context = get_cli_context()
130
131
  create_loggers(cli_context.verbose, cli_context.enable_tracebacks)
131
132
 
132
133
 
@@ -342,7 +343,7 @@ GLOBAL_OPTIONS = [
342
343
 
343
344
 
344
345
  def with_output(func):
345
- from snowflake.cli.app.printing import print_result
346
+ from snowflake.cli._app.printing import print_result
346
347
 
347
348
  @wraps(func)
348
349
  def wrapper(*args, **kwargs):
@@ -11,9 +11,8 @@
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
 
17
16
 
18
17
  def experimental_behaviour_enabled() -> bool:
19
- return cli_context.experimental
18
+ return get_cli_context().experimental