snowflake-cli-labs 2.8.0rc0__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 (220) 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/errors.py +16 -1
  113. snowflake/cli/api/project/project_verification.py +3 -3
  114. snowflake/cli/api/project/schemas/entities/{application_entity.py → application_entity_model.py} +21 -9
  115. snowflake/cli/api/project/schemas/entities/{application_package_entity.py → application_package_entity_model.py} +26 -15
  116. snowflake/cli/api/project/schemas/entities/common.py +80 -6
  117. snowflake/cli/api/project/schemas/entities/entities.py +38 -8
  118. snowflake/cli/api/project/schemas/entities/snowpark_entity.py +176 -0
  119. snowflake/cli/api/project/schemas/entities/streamlit_entity_model.py +73 -0
  120. snowflake/cli/api/project/schemas/identifier_model.py +10 -1
  121. snowflake/cli/api/project/schemas/native_app/application.py +8 -9
  122. snowflake/cli/api/project/schemas/native_app/package.py +7 -1
  123. snowflake/cli/api/project/schemas/project_definition.py +97 -23
  124. snowflake/cli/api/project/schemas/updatable_model.py +11 -3
  125. snowflake/cli/api/project/util.py +23 -6
  126. snowflake/cli/api/rendering/jinja.py +28 -8
  127. snowflake/cli/api/rendering/sql_templates.py +41 -12
  128. snowflake/cli/api/secure_path.py +3 -0
  129. snowflake/cli/api/sql_execution.py +35 -19
  130. snowflake/cli/api/utils/definition_rendering.py +14 -2
  131. {snowflake_cli_labs-2.8.0rc0.dist-info → snowflake_cli_labs-3.0.0rc0.dist-info}/METADATA +12 -12
  132. snowflake_cli_labs-3.0.0rc0.dist-info/RECORD +234 -0
  133. snowflake_cli_labs-3.0.0rc0.dist-info/entry_points.txt +2 -0
  134. snowflake/cli/api/commands/project_initialisation.py +0 -65
  135. snowflake/cli/app/build_and_push.sh +0 -8
  136. snowflake/cli/plugins/nativeapp/manager.py +0 -819
  137. snowflake/cli/plugins/object_stage_deprecated/__init__.py +0 -15
  138. snowflake/cli/plugins/object_stage_deprecated/commands.py +0 -122
  139. snowflake/cli/plugins/object_stage_deprecated/plugin_spec.py +0 -32
  140. snowflake/cli/plugins/snowpark/commands.py +0 -548
  141. snowflake/cli/plugins/snowpark/common.py +0 -307
  142. snowflake/cli/plugins/snowpark/manager.py +0 -109
  143. snowflake/cli/plugins/snowpark/plugin_spec.py +0 -30
  144. snowflake/cli/plugins/snowpark/snowpark_package_paths.py +0 -65
  145. snowflake/cli/plugins/spcs/jobs/commands.py +0 -78
  146. snowflake/cli/plugins/spcs/jobs/manager.py +0 -53
  147. snowflake/cli/plugins/streamlit/commands.py +0 -186
  148. snowflake/cli/plugins/streamlit/plugin_spec.py +0 -30
  149. snowflake/cli/plugins/workspace/commands.py +0 -35
  150. snowflake/cli/templates/default_snowpark/.gitignore +0 -4
  151. snowflake/cli/templates/default_snowpark/app/__init__.py +0 -0
  152. snowflake/cli/templates/default_snowpark/app/common.py +0 -2
  153. snowflake/cli/templates/default_snowpark/app/functions.py +0 -15
  154. snowflake/cli/templates/default_snowpark/app/procedures.py +0 -22
  155. snowflake/cli/templates/default_snowpark/requirements.txt +0 -1
  156. snowflake/cli/templates/default_snowpark/snowflake.yml +0 -23
  157. snowflake/cli/templates/default_streamlit/.gitignore +0 -4
  158. snowflake/cli/templates/default_streamlit/common/hello.py +0 -2
  159. snowflake/cli/templates/default_streamlit/environment.yml +0 -6
  160. snowflake/cli/templates/default_streamlit/pages/my_page.py +0 -3
  161. snowflake/cli/templates/default_streamlit/snowflake.yml +0 -10
  162. snowflake/cli/templates/default_streamlit/streamlit_app.py +0 -4
  163. snowflake_cli_labs-2.8.0rc0.dist-info/RECORD +0 -240
  164. snowflake_cli_labs-2.8.0rc0.dist-info/entry_points.txt +0 -2
  165. /snowflake/cli/{app → _app}/__init__.py +0 -0
  166. /snowflake/cli/{app → _app}/api_impl/__init__.py +0 -0
  167. /snowflake/cli/{app → _app}/api_impl/plugin/__init__.py +0 -0
  168. /snowflake/cli/{app → _app}/api_impl/plugin/plugin_config_provider_impl.py +0 -0
  169. /snowflake/cli/{app → _app}/commands_registration/__init__.py +0 -0
  170. /snowflake/cli/{app → _app}/commands_registration/threadsafe.py +0 -0
  171. /snowflake/cli/{app → _app}/constants.py +0 -0
  172. /snowflake/cli/{app → _app}/dev/__init__.py +0 -0
  173. /snowflake/cli/{app → _app}/dev/commands_structure.py +0 -0
  174. /snowflake/cli/{app → _app}/dev/docs/__init__.py +0 -0
  175. /snowflake/cli/{app → _app}/dev/docs/project_definition_generate_json_schema.py +0 -0
  176. /snowflake/cli/{app → _app}/dev/docs/template_utils.py +0 -0
  177. /snowflake/cli/{app → _app}/dev/docs/templates/definition_description.rst.jinja2 +0 -0
  178. /snowflake/cli/{app → _app}/dev/docs/templates/overview.rst.jinja2 +0 -0
  179. /snowflake/cli/{app → _app}/dev/pycharm_remote_debug.py +0 -0
  180. /snowflake/cli/{app → _app}/loggers.py +0 -0
  181. /snowflake/cli/{plugins → _plugins}/__init__.py +0 -0
  182. /snowflake/cli/{plugins → _plugins}/connection/__init__.py +0 -0
  183. /snowflake/cli/{plugins → _plugins}/cortex/__init__.py +0 -0
  184. /snowflake/cli/{plugins → _plugins}/cortex/types.py +0 -0
  185. /snowflake/cli/{plugins → _plugins}/git/__init__.py +0 -0
  186. /snowflake/cli/{plugins → _plugins}/init/__init__.py +0 -0
  187. /snowflake/cli/{plugins → _plugins}/nativeapp/__init__.py +0 -0
  188. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/__init__.py +0 -0
  189. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/sandbox.py +0 -0
  190. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/setup/setup_driver.py.source +0 -0
  191. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -0
  192. /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/models.py +0 -0
  193. /snowflake/cli/{plugins → _plugins}/nativeapp/constants.py +0 -0
  194. /snowflake/cli/{plugins → _plugins}/nativeapp/exceptions.py +0 -0
  195. /snowflake/cli/{plugins → _plugins}/nativeapp/feature_flags.py +0 -0
  196. /snowflake/cli/{plugins → _plugins}/nativeapp/policy.py +0 -0
  197. /snowflake/cli/{plugins → _plugins}/nativeapp/utils.py +0 -0
  198. /snowflake/cli/{plugins → _plugins}/nativeapp/version/__init__.py +0 -0
  199. /snowflake/cli/{plugins → _plugins}/notebook/__init__.py +0 -0
  200. /snowflake/cli/{plugins → _plugins}/notebook/exceptions.py +0 -0
  201. /snowflake/cli/{plugins → _plugins}/object/__init__.py +0 -0
  202. /snowflake/cli/{plugins → _plugins}/object/common.py +0 -0
  203. /snowflake/cli/{plugins → _plugins}/snowpark/__init__.py +0 -0
  204. /snowflake/cli/{plugins → _plugins}/snowpark/package/__init__.py +0 -0
  205. /snowflake/cli/{plugins → _plugins}/snowpark/package/utils.py +0 -0
  206. /snowflake/cli/{plugins → _plugins}/spcs/common.py +0 -0
  207. /snowflake/cli/{plugins → _plugins}/spcs/compute_pool/__init__.py +0 -0
  208. /snowflake/cli/{plugins → _plugins}/spcs/image_registry/__init__.py +0 -0
  209. /snowflake/cli/{plugins → _plugins}/spcs/image_registry/manager.py +0 -0
  210. /snowflake/cli/{plugins → _plugins}/spcs/image_repository/__init__.py +0 -0
  211. /snowflake/cli/{plugins/spcs/jobs → _plugins/spcs/services}/__init__.py +0 -0
  212. /snowflake/cli/{plugins/spcs/services → _plugins/sql}/__init__.py +0 -0
  213. /snowflake/cli/{plugins → _plugins}/sql/snowsql_templating.py +0 -0
  214. /snowflake/cli/{plugins/sql → _plugins/stage}/__init__.py +0 -0
  215. /snowflake/cli/{plugins → _plugins}/stage/md5.py +0 -0
  216. /snowflake/cli/{plugins/stage → _plugins/streamlit}/__init__.py +0 -0
  217. /snowflake/cli/{plugins/streamlit → _plugins/workspace}/__init__.py +0 -0
  218. /snowflake/cli/{plugins/workspace → api/project/schemas/entities}/__init__.py +0 -0
  219. {snowflake_cli_labs-2.8.0rc0.dist-info → snowflake_cli_labs-3.0.0rc0.dist-info}/WHEEL +0 -0
  220. {snowflake_cli_labs-2.8.0rc0.dist-info → snowflake_cli_labs-3.0.0rc0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,18 @@
1
+ from typing import List, Optional
2
+
3
+ from click import ClickException
4
+ from snowflake.cli.api.commands.common import Variable
5
+
6
+
7
+ def parse_key_value_variables(variables: Optional[List[str]]) -> List[Variable]:
8
+ """Util for parsing key=value input. Useful for commands accepting multiple input options."""
9
+ result: List[Variable] = []
10
+ if not variables:
11
+ return result
12
+ for p in variables:
13
+ if "=" not in p:
14
+ raise ClickException(f"Invalid variable: '{p}'")
15
+
16
+ key, value = p.split("=", 1)
17
+ result.append(Variable(key.strip(), value.strip()))
18
+ return result
@@ -115,7 +115,7 @@ def config_init(config_file: Optional[Path]):
115
115
  Initializes the app configuration. Config provided via cli flag takes precedence.
116
116
  If config file does not exist we create an empty one.
117
117
  """
118
- from snowflake.cli.app.loggers import create_initial_loggers
118
+ from snowflake.cli._app.loggers import create_initial_loggers
119
119
 
120
120
  if config_file:
121
121
  CONFIG_MANAGER.file_path = config_file
@@ -20,7 +20,10 @@ from typing import Callable, Iterator, Optional
20
20
 
21
21
  from rich import print as rich_print
22
22
  from rich.text import Text
23
- from snowflake.cli.api.cli_global_context import _CliGlobalContextAccess, cli_context
23
+ from snowflake.cli.api.cli_global_context import (
24
+ _CliGlobalContextAccess,
25
+ get_cli_context,
26
+ )
24
27
 
25
28
 
26
29
  class AbstractConsole(ABC):
@@ -39,7 +42,7 @@ class AbstractConsole(ABC):
39
42
 
40
43
  def __init__(self):
41
44
  super().__init__()
42
- self._cli_context = cli_context
45
+ self._cli_context = get_cli_context()
43
46
  self._in_phase = False
44
47
 
45
48
  @property
@@ -0,0 +1,12 @@
1
+ from snowflake.cli.api.entities.common import EntityBase
2
+ from snowflake.cli.api.project.schemas.entities.application_entity_model import (
3
+ ApplicationEntityModel,
4
+ )
5
+
6
+
7
+ class ApplicationEntity(EntityBase[ApplicationEntityModel]):
8
+ """
9
+ A Native App application object, created from an application package.
10
+ """
11
+
12
+ pass
@@ -0,0 +1,260 @@
1
+ from contextlib import contextmanager
2
+ from pathlib import Path
3
+ from textwrap import dedent
4
+ from typing import List, Optional
5
+
6
+ from click import ClickException
7
+ from snowflake.cli._plugins.nativeapp.artifacts import build_bundle
8
+ from snowflake.cli._plugins.nativeapp.bundle_context import BundleContext
9
+ from snowflake.cli._plugins.nativeapp.codegen.compiler import NativeAppCompiler
10
+ from snowflake.cli._plugins.nativeapp.constants import (
11
+ ALLOWED_SPECIAL_COMMENTS,
12
+ COMMENT_COL,
13
+ INTERNAL_DISTRIBUTION,
14
+ NAME_COL,
15
+ SPECIAL_COMMENT,
16
+ )
17
+ from snowflake.cli._plugins.nativeapp.exceptions import (
18
+ ApplicationPackageAlreadyExistsError,
19
+ )
20
+ from snowflake.cli._plugins.workspace.action_context import ActionContext
21
+ from snowflake.cli.api.console.abc import AbstractConsole
22
+ from snowflake.cli.api.entities.common import EntityBase, get_sql_executor
23
+ from snowflake.cli.api.entities.utils import (
24
+ ensure_correct_owner,
25
+ generic_sql_error_handler,
26
+ render_script_templates,
27
+ )
28
+ from snowflake.cli.api.exceptions import SnowflakeSQLExecutionError
29
+ from snowflake.cli.api.project.schemas.entities.application_package_entity_model import (
30
+ ApplicationPackageEntityModel,
31
+ )
32
+ from snowflake.cli.api.rendering.jinja import (
33
+ jinja_render_from_str,
34
+ )
35
+ from snowflake.connector import ProgrammingError
36
+
37
+
38
+ class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
39
+ """
40
+ A Native App application package.
41
+ """
42
+
43
+ def action_bundle(self, ctx: ActionContext):
44
+ model = self._entity_model
45
+ bundle_map = build_bundle(
46
+ ctx.project_root, Path(model.deploy_root), model.artifacts
47
+ )
48
+ bundle_context = BundleContext(
49
+ package_name=model.identifier,
50
+ artifacts=model.artifacts,
51
+ project_root=ctx.project_root,
52
+ bundle_root=Path(model.bundle_root),
53
+ deploy_root=Path(model.deploy_root),
54
+ generated_root=Path(model.generated_root),
55
+ )
56
+ compiler = NativeAppCompiler(bundle_context)
57
+ compiler.compile_artifacts()
58
+ return bundle_map
59
+
60
+ @staticmethod
61
+ def get_existing_app_pkg_info(
62
+ package_name: str,
63
+ package_role: str,
64
+ ) -> Optional[dict]:
65
+ """
66
+ Check for an existing application package by the same name as in project definition, in account.
67
+ It executes a 'show application packages like' query and returns the result as single row, if one exists.
68
+ """
69
+ sql_executor = get_sql_executor()
70
+ with sql_executor.use_role(package_role):
71
+ return sql_executor.show_specific_object(
72
+ "application packages", package_name, name_col=NAME_COL
73
+ )
74
+
75
+ @staticmethod
76
+ def get_app_pkg_distribution_in_snowflake(
77
+ package_name: str,
78
+ package_role: str,
79
+ ) -> str:
80
+ """
81
+ Returns the 'distribution' attribute of a 'describe application package' SQL query, in lowercase.
82
+ """
83
+ sql_executor = get_sql_executor()
84
+ with sql_executor.use_role(package_role):
85
+ try:
86
+ desc_cursor = sql_executor.execute_query(
87
+ f"describe application package {package_name}"
88
+ )
89
+ except ProgrammingError as err:
90
+ generic_sql_error_handler(err)
91
+
92
+ if desc_cursor.rowcount is None or desc_cursor.rowcount == 0:
93
+ raise SnowflakeSQLExecutionError()
94
+ else:
95
+ for row in desc_cursor:
96
+ if row[0].lower() == "distribution":
97
+ return row[1].lower()
98
+ raise ProgrammingError(
99
+ msg=dedent(
100
+ f"""\
101
+ Could not find the 'distribution' attribute for application package {package_name} in the output of SQL query:
102
+ 'describe application package {package_name}'
103
+ """
104
+ )
105
+ )
106
+
107
+ @classmethod
108
+ def verify_project_distribution(
109
+ cls,
110
+ console: AbstractConsole,
111
+ package_name: str,
112
+ package_role: str,
113
+ package_distribution: str,
114
+ expected_distribution: Optional[str] = None,
115
+ ) -> bool:
116
+ """
117
+ Returns true if the 'distribution' attribute of an existing application package in snowflake
118
+ is the same as the the attribute specified in project definition file.
119
+ """
120
+ actual_distribution = (
121
+ expected_distribution
122
+ if expected_distribution
123
+ else cls.get_app_pkg_distribution_in_snowflake(
124
+ package_name=package_name,
125
+ package_role=package_role,
126
+ )
127
+ )
128
+ project_def_distribution = package_distribution.lower()
129
+ if actual_distribution != project_def_distribution:
130
+ console.warning(
131
+ dedent(
132
+ f"""\
133
+ Application package {package_name} in your Snowflake account has distribution property {actual_distribution},
134
+ which does not match the value specified in project definition file: {project_def_distribution}.
135
+ """
136
+ )
137
+ )
138
+ return False
139
+ return True
140
+
141
+ @staticmethod
142
+ @contextmanager
143
+ def use_package_warehouse(
144
+ package_warehouse: Optional[str],
145
+ ):
146
+ if package_warehouse:
147
+ with get_sql_executor().use_warehouse(package_warehouse):
148
+ yield
149
+ else:
150
+ raise ClickException(
151
+ dedent(
152
+ f"""\
153
+ Application package warehouse cannot be empty.
154
+ Please provide a value for it in your connection information or your project definition file.
155
+ """
156
+ )
157
+ )
158
+
159
+ @classmethod
160
+ def apply_package_scripts(
161
+ cls,
162
+ console: AbstractConsole,
163
+ package_scripts: List[str],
164
+ package_warehouse: Optional[str],
165
+ project_root: Path,
166
+ package_role: str,
167
+ package_name: str,
168
+ ) -> None:
169
+ """
170
+ Assuming the application package exists and we are using the correct role,
171
+ applies all package scripts in-order to the application package.
172
+ """
173
+
174
+ if package_scripts:
175
+ console.warning(
176
+ "WARNING: native_app.package.scripts is deprecated. Please migrate to using native_app.package.post_deploy."
177
+ )
178
+
179
+ queued_queries = render_script_templates(
180
+ project_root,
181
+ jinja_render_from_str,
182
+ dict(package_name=package_name),
183
+ package_scripts,
184
+ )
185
+
186
+ # once we're sure all the templates expanded correctly, execute all of them
187
+ with cls.use_package_warehouse(
188
+ package_warehouse=package_warehouse,
189
+ ):
190
+ try:
191
+ for i, queries in enumerate(queued_queries):
192
+ console.step(f"Applying package script: {package_scripts[i]}")
193
+ get_sql_executor().execute_queries(queries)
194
+ except ProgrammingError as err:
195
+ generic_sql_error_handler(
196
+ err, role=package_role, warehouse=package_warehouse
197
+ )
198
+
199
+ @classmethod
200
+ def create_app_package(
201
+ cls,
202
+ console: AbstractConsole,
203
+ package_name: str,
204
+ package_role: str,
205
+ package_distribution: str,
206
+ ) -> None:
207
+ """
208
+ Creates the application package with our up-to-date stage if none exists.
209
+ """
210
+
211
+ # 1. Check for existing existing application package
212
+ show_obj_row = cls.get_existing_app_pkg_info(
213
+ package_name=package_name,
214
+ package_role=package_role,
215
+ )
216
+
217
+ if show_obj_row:
218
+ # 1. Check for the right owner role
219
+ ensure_correct_owner(
220
+ row=show_obj_row, role=package_role, obj_name=package_name
221
+ )
222
+
223
+ # 2. Check distribution of the existing application package
224
+ actual_distribution = cls.get_app_pkg_distribution_in_snowflake(
225
+ package_name=package_name,
226
+ package_role=package_role,
227
+ )
228
+ if not cls.verify_project_distribution(
229
+ console=console,
230
+ package_name=package_name,
231
+ package_role=package_role,
232
+ package_distribution=package_distribution,
233
+ expected_distribution=actual_distribution,
234
+ ):
235
+ console.warning(
236
+ f"Continuing to execute `snow app run` on application package {package_name} with distribution '{actual_distribution}'."
237
+ )
238
+
239
+ # 3. If actual_distribution is external, skip comment check
240
+ if actual_distribution == INTERNAL_DISTRIBUTION:
241
+ row_comment = show_obj_row[COMMENT_COL]
242
+
243
+ if row_comment not in ALLOWED_SPECIAL_COMMENTS:
244
+ raise ApplicationPackageAlreadyExistsError(package_name)
245
+
246
+ return
247
+
248
+ # If no application package pre-exists, create an application package, with the specified distribution in the project definition file.
249
+ sql_executor = get_sql_executor()
250
+ with sql_executor.use_role(package_role):
251
+ console.step(f"Creating new application package {package_name} in account.")
252
+ sql_executor.execute_query(
253
+ dedent(
254
+ f"""\
255
+ create application package {package_name}
256
+ comment = {SPECIAL_COMMENT}
257
+ distribution = {package_distribution}
258
+ """
259
+ )
260
+ )
@@ -0,0 +1,47 @@
1
+ from enum import Enum
2
+ from typing import Generic, Type, TypeVar, get_args
3
+
4
+ from snowflake.cli._plugins.workspace.action_context import ActionContext
5
+ from snowflake.cli.api.sql_execution import SqlExecutor
6
+
7
+
8
+ class EntityActions(str, Enum):
9
+ BUNDLE = "action_bundle"
10
+
11
+
12
+ T = TypeVar("T")
13
+
14
+
15
+ class EntityBase(Generic[T]):
16
+ """
17
+ Base class for the fully-featured entity classes.
18
+ """
19
+
20
+ def __init__(self, entity_model: T):
21
+ self._entity_model = entity_model
22
+
23
+ @classmethod
24
+ def get_entity_model_type(cls) -> Type[T]:
25
+ """
26
+ Returns the generic model class specified in each entity class.
27
+
28
+ For example, calling ApplicationEntity.get_entity_model_type() will return the ApplicationEntityModel class.
29
+ """
30
+ return get_args(cls.__orig_bases__[0])[0] # type: ignore[attr-defined]
31
+
32
+ def supports(self, action: EntityActions) -> bool:
33
+ """
34
+ Checks whether this entity supports the given action. An entity is considered to support an action if it implements a method with the action name.
35
+ """
36
+ return callable(getattr(self, action, None))
37
+
38
+ def perform(self, action: EntityActions, action_ctx: ActionContext):
39
+ """
40
+ Performs the requested action.
41
+ """
42
+ return getattr(self, action)(action_ctx)
43
+
44
+
45
+ def get_sql_executor() -> SqlExecutor:
46
+ """Returns an SQL Executor that uses the connection from the current CLI context"""
47
+ return SqlExecutor()
@@ -0,0 +1,29 @@
1
+ from typing import Generic, TypeVar
2
+
3
+ from snowflake.cli.api.entities.common import EntityBase
4
+ from snowflake.cli.api.project.schemas.entities.snowpark_entity import (
5
+ FunctionEntityModel,
6
+ ProcedureEntityModel,
7
+ )
8
+
9
+ T = TypeVar("T")
10
+
11
+
12
+ class SnowparkEntity(EntityBase[Generic[T]]):
13
+ pass
14
+
15
+
16
+ class FunctionEntity(SnowparkEntity[FunctionEntityModel]):
17
+ """
18
+ A single UDF
19
+ """
20
+
21
+ pass
22
+
23
+
24
+ class ProcedureEntity(SnowparkEntity[ProcedureEntityModel]):
25
+ """
26
+ A stored procedure
27
+ """
28
+
29
+ pass
@@ -0,0 +1,12 @@
1
+ from snowflake.cli.api.entities.common import EntityBase
2
+ from snowflake.cli.api.project.schemas.entities.streamlit_entity_model import (
3
+ StreamlitEntityModel,
4
+ )
5
+
6
+
7
+ class StreamlitEntity(EntityBase[StreamlitEntityModel]):
8
+ """
9
+ A Streamlit app.
10
+ """
11
+
12
+ pass