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
@@ -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,19 @@ 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
@@ -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
+ }
@@ -0,0 +1,176 @@
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
+ from pathlib import Path
18
+ from typing import List, Literal, Optional, Union
19
+
20
+ from pydantic import Field, field_validator
21
+ from snowflake.cli.api.identifiers import FQN
22
+ from snowflake.cli.api.project.schemas.entities.common import (
23
+ EntityModelBase,
24
+ ExternalAccessBaseModel,
25
+ )
26
+ from snowflake.cli.api.project.schemas.snowpark.argument import Argument
27
+ from snowflake.cli.api.project.schemas.updatable_model import (
28
+ DiscriminatorField,
29
+ UpdatableModel,
30
+ )
31
+
32
+
33
+ class PathMapping(UpdatableModel):
34
+ class Config:
35
+ frozen = True
36
+
37
+ src: Path = Field(title="Source path (relative to project root)", default=None)
38
+
39
+ dest: Optional[str] = Field(
40
+ title="Destination path on stage",
41
+ description="Paths are relative to stage root; paths ending with a slash indicate that the destination is a directory which source files should be copied into.",
42
+ default=None,
43
+ )
44
+
45
+
46
+ class SnowparkEntityModel(EntityModelBase, ExternalAccessBaseModel):
47
+ handler: str = Field(
48
+ title="Function’s or procedure’s implementation of the object inside source module",
49
+ examples=["functions.hello_function"],
50
+ )
51
+ returns: str = Field(
52
+ title="Type of the result"
53
+ ) # TODO: again, consider Literal/Enum
54
+ signature: Union[str, List[Argument]] = Field(
55
+ title="The signature parameter describes consecutive arguments passed to the object"
56
+ )
57
+ runtime: Optional[Union[str, float]] = Field(
58
+ title="Python version to use when executing ", default=None
59
+ )
60
+ imports: Optional[List[str]] = Field(
61
+ title="Stage and path to previously uploaded files you want to import",
62
+ default=[],
63
+ )
64
+ stage: str = Field(title="Stage in which artifacts will be stored")
65
+ artifacts: List[Union[PathMapping, str]] = Field(title="List of required sources")
66
+
67
+ @field_validator("artifacts")
68
+ @classmethod
69
+ def _convert_artifacts(cls, artifacts: Union[dict, str]):
70
+ _artifacts = []
71
+ for artefact in artifacts:
72
+ if isinstance(artefact, PathMapping):
73
+ _artifacts.append(artefact)
74
+ else:
75
+ _artifacts.append(PathMapping(src=artefact))
76
+ return _artifacts
77
+
78
+ @field_validator("runtime")
79
+ @classmethod
80
+ def convert_runtime(cls, runtime_input: Union[str, float]) -> str:
81
+ if isinstance(runtime_input, float):
82
+ return str(runtime_input)
83
+ return runtime_input
84
+
85
+ @field_validator("artifacts")
86
+ @classmethod
87
+ def validate_artifacts(cls, artifacts: List[Path]) -> List[Path]:
88
+ for artefact in artifacts:
89
+ if "*" in str(artefact):
90
+ raise ValueError("Glob patterns not supported for Snowpark artifacts.")
91
+ return artifacts
92
+
93
+ @property
94
+ def udf_sproc_identifier(self) -> UdfSprocIdentifier:
95
+ return UdfSprocIdentifier.from_definition(self)
96
+
97
+
98
+ class ProcedureEntityModel(SnowparkEntityModel):
99
+ type: Literal["procedure"] = DiscriminatorField() # noqa: A003
100
+ execute_as_caller: Optional[bool] = Field(
101
+ title="Determine whether the procedure is executed with the privileges of "
102
+ "the owner (you) or with the privileges of the caller",
103
+ default=False,
104
+ )
105
+
106
+
107
+ class FunctionEntityModel(SnowparkEntityModel):
108
+ type: Literal["function"] = DiscriminatorField() # noqa: A003
109
+
110
+
111
+ class UdfSprocIdentifier:
112
+ def __init__(self, identifier: FQN, arg_names, arg_types, arg_defaults):
113
+ self._identifier = identifier
114
+ self._arg_names = arg_names
115
+ self._arg_types = arg_types
116
+ self._arg_defaults = arg_defaults
117
+
118
+ def _identifier_from_signature(self, sig: List[str], for_sql: bool = False):
119
+ signature = self._comma_join(sig)
120
+ id_ = self._identifier.sql_identifier if for_sql else self._identifier
121
+ return f"{id_}({signature})"
122
+
123
+ @staticmethod
124
+ def _comma_join(*args):
125
+ return ", ".join(*args)
126
+
127
+ @property
128
+ def identifier_with_arg_names(self):
129
+ return self._identifier_from_signature(self._arg_names)
130
+
131
+ @property
132
+ def identifier_with_arg_types(self):
133
+ return self._identifier_from_signature(self._arg_types)
134
+
135
+ @property
136
+ def identifier_with_arg_names_types(self):
137
+ sig = [f"{n} {t}" for n, t in zip(self._arg_names, self._arg_types)]
138
+ return self._identifier_from_signature(sig)
139
+
140
+ @property
141
+ def identifier_with_arg_names_types_defaults(self):
142
+ return self._identifier_from_signature(self._full_signature())
143
+
144
+ def _is_signature_type_a_string(self, sig_type: str) -> bool:
145
+ return sig_type.lower() in ["string", "varchar"]
146
+
147
+ def _full_signature(self):
148
+ sig = []
149
+ for name, _type, _default in zip(
150
+ self._arg_names, self._arg_types, self._arg_defaults
151
+ ):
152
+ s = f"{name} {_type}"
153
+ if _default:
154
+ if self._is_signature_type_a_string(_type):
155
+ _default = f"'{_default}'"
156
+ s += f" default {_default}"
157
+ sig.append(s)
158
+ return sig
159
+
160
+ @property
161
+ def identifier_for_sql(self):
162
+ return self._identifier_from_signature(self._full_signature(), for_sql=True)
163
+
164
+ @classmethod
165
+ def from_definition(cls, udf_sproc: SnowparkEntityModel):
166
+ names = []
167
+ types = []
168
+ defaults = []
169
+ if udf_sproc.signature and udf_sproc.signature != "null":
170
+ for arg in udf_sproc.signature:
171
+ names.append(arg.name) # type:ignore
172
+ types.append(arg.arg_type) # type:ignore
173
+ defaults.append(arg.default) # type:ignore
174
+
175
+ identifier = udf_sproc.fqn.using_context()
176
+ return cls(identifier, names, types, defaults)
@@ -0,0 +1,73 @@
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
+ from __future__ import annotations
15
+
16
+ from pathlib import Path
17
+ from typing import List, Literal, Optional
18
+
19
+ from pydantic import Field, model_validator
20
+ from snowflake.cli.api.project.schemas.entities.common import (
21
+ EntityModelBase,
22
+ ExternalAccessBaseModel,
23
+ )
24
+ from snowflake.cli.api.project.schemas.updatable_model import (
25
+ DiscriminatorField,
26
+ )
27
+
28
+
29
+ class StreamlitEntityModel(EntityModelBase, ExternalAccessBaseModel):
30
+ type: Literal["streamlit"] = DiscriminatorField() # noqa: A003
31
+ title: Optional[str] = Field(
32
+ title="Human-readable title for the Streamlit dashboard", default=None
33
+ )
34
+ query_warehouse: str = Field(
35
+ title="Snowflake warehouse to host the app", default=None
36
+ )
37
+ main_file: Optional[str] = Field(
38
+ title="Entrypoint file of the Streamlit app", default="streamlit_app.py"
39
+ )
40
+ pages_dir: Optional[str] = Field(title="Streamlit pages", default=None)
41
+ stage: Optional[str] = Field(
42
+ title="Stage in which the app’s artifacts will be stored", default="streamlit"
43
+ )
44
+ # Possibly can be PathMapping
45
+ artifacts: Optional[List[Path]] = Field(
46
+ title="List of files which should be deployed. Each file needs to exist locally. "
47
+ "Main file needs to be included in the artifacts.",
48
+ default=None,
49
+ )
50
+
51
+ @model_validator(mode="after")
52
+ def main_file_must_be_in_artifacts(self):
53
+ if not self.artifacts:
54
+ return self
55
+
56
+ if Path(self.main_file) not in self.artifacts:
57
+ raise ValueError(
58
+ f"Specified main file {self.main_file} is not included in artifacts."
59
+ )
60
+ return self
61
+
62
+ @model_validator(mode="after")
63
+ def artifacts_must_exists(self):
64
+ if not self.artifacts:
65
+ return self
66
+
67
+ for artifact in self.artifacts:
68
+ if not artifact.exists():
69
+ raise ValueError(
70
+ f"Specified artifact {artifact} does not exist locally."
71
+ )
72
+
73
+ return self
@@ -17,7 +17,16 @@ from __future__ import annotations
17
17
  from typing import Optional, cast
18
18
 
19
19
  from pydantic import Field
20
- from snowflake.cli.api.project.schemas.updatable_model import IdentifierField
20
+ from snowflake.cli.api.project.schemas.updatable_model import (
21
+ IdentifierField,
22
+ UpdatableModel,
23
+ )
24
+
25
+
26
+ class Identifier(UpdatableModel):
27
+ name: str = Field(title="Entity name")
28
+ schema_: str = Field(title="Entity schema", alias="schema", default=None)
29
+ database: str = Field(title="Entity database", default=None)
21
30
 
22
31
 
23
32
  class ObjectIdentifierBaseModel:
@@ -16,19 +16,13 @@ from __future__ import annotations
16
16
 
17
17
  from typing import List, Optional
18
18
 
19
- from pydantic import Field
19
+ from pydantic import Field, field_validator
20
+ from snowflake.cli.api.project.schemas.entities.common import PostDeployHook
20
21
  from snowflake.cli.api.project.schemas.updatable_model import (
21
22
  IdentifierField,
22
23
  UpdatableModel,
23
24
  )
24
-
25
-
26
- class SqlScriptHookType(UpdatableModel):
27
- sql_script: str = Field(title="SQL file path relative to the project root")
28
-
29
-
30
- # Currently sql_script is the only supported hook type. Change to a Union once other hook types are added
31
- PostDeployHook = SqlScriptHookType
25
+ from snowflake.cli.api.project.util import append_test_resource_suffix
32
26
 
33
27
 
34
28
  class Application(UpdatableModel):
@@ -53,6 +47,11 @@ class Application(UpdatableModel):
53
47
  default=None,
54
48
  )
55
49
 
50
+ @field_validator("name")
51
+ @classmethod
52
+ def append_test_resource_suffix_to_name(cls, input_value: str) -> str:
53
+ return append_test_resource_suffix(input_value)
54
+
56
55
 
57
56
  class ApplicationV11(Application):
58
57
  # Templated defaults only supported in v1.1+
@@ -17,11 +17,12 @@ from __future__ import annotations
17
17
  from typing import List, Literal, Optional
18
18
 
19
19
  from pydantic import Field, field_validator, model_validator
20
- from snowflake.cli.api.project.schemas.native_app.application import PostDeployHook
20
+ from snowflake.cli.api.project.schemas.entities.common import PostDeployHook
21
21
  from snowflake.cli.api.project.schemas.updatable_model import (
22
22
  IdentifierField,
23
23
  UpdatableModel,
24
24
  )
25
+ from snowflake.cli.api.project.util import append_test_resource_suffix
25
26
 
26
27
  DistributionOptions = Literal["internal", "external", "INTERNAL", "EXTERNAL"]
27
28
 
@@ -50,6 +51,11 @@ class Package(UpdatableModel):
50
51
  default=None,
51
52
  )
52
53
 
54
+ @field_validator("name")
55
+ @classmethod
56
+ def append_test_resource_suffix_to_name(cls, input_value: str) -> str:
57
+ return append_test_resource_suffix(input_value)
58
+
53
59
  @field_validator("scripts")
54
60
  @classmethod
55
61
  def validate_scripts(cls, input_list):