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
@@ -21,8 +21,20 @@ from typing import List, Optional
21
21
  import click
22
22
  import typer
23
23
  from click import UsageError
24
- from snowflake.cli.api.cli_global_context import cli_context
25
- from snowflake.cli.api.commands.flags import readable_file_option
24
+ from snowflake.cli._plugins.cortex.constants import DEFAULT_MODEL
25
+ from snowflake.cli._plugins.cortex.manager import CortexManager
26
+ from snowflake.cli._plugins.cortex.types import (
27
+ Language,
28
+ Model,
29
+ Question,
30
+ SourceDocument,
31
+ Text,
32
+ )
33
+ from snowflake.cli.api.cli_global_context import get_cli_context
34
+ from snowflake.cli.api.commands.overrideable_parameter import (
35
+ OverrideableArgument,
36
+ OverrideableOption,
37
+ )
26
38
  from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
27
39
  from snowflake.cli.api.constants import PYTHON_3_12
28
40
  from snowflake.cli.api.output.types import (
@@ -31,15 +43,6 @@ from snowflake.cli.api.output.types import (
31
43
  MessageResult,
32
44
  )
33
45
  from snowflake.cli.api.secure_path import SecurePath
34
- from snowflake.cli.plugins.cortex.constants import DEFAULT_MODEL
35
- from snowflake.cli.plugins.cortex.manager import CortexManager
36
- from snowflake.cli.plugins.cortex.types import (
37
- Language,
38
- Model,
39
- Question,
40
- SourceDocument,
41
- Text,
42
- )
43
46
 
44
47
  app = SnowTyperFactory(
45
48
  name="cortex",
@@ -48,6 +51,25 @@ app = SnowTyperFactory(
48
51
 
49
52
  SEARCH_COMMAND_ENABLED = sys.version_info < PYTHON_3_12
50
53
 
54
+ SOURCE_EXCLUSIVE_OPTION_NAMES = ["text", "file", "source_document_text"]
55
+
56
+ # Creates a Typer option and verifies if the mutually exclusive options are set in the command.
57
+ ExclusiveReadableFileOption = OverrideableOption(
58
+ None,
59
+ "--file",
60
+ mutually_exclusive=SOURCE_EXCLUSIVE_OPTION_NAMES,
61
+ exists=True,
62
+ file_okay=True,
63
+ dir_okay=False,
64
+ readable=True,
65
+ show_default=False,
66
+ )
67
+
68
+ # Creates a Typer argument and verifies if the mutually exclusive options are set in the command.
69
+ ExclusiveTextSourceArgument = OverrideableArgument(
70
+ mutually_exclusive=SOURCE_EXCLUSIVE_OPTION_NAMES,
71
+ )
72
+
51
73
 
52
74
  @app.command(
53
75
  requires_connection=True,
@@ -79,7 +101,7 @@ def search(
79
101
  if not columns:
80
102
  columns = []
81
103
 
82
- conn = cli_context.connection
104
+ conn = get_cli_context().connection
83
105
 
84
106
  search_service = (
85
107
  Root(conn)
@@ -100,8 +122,8 @@ def search(
100
122
  requires_connection=True,
101
123
  )
102
124
  def complete(
103
- text: Optional[str] = typer.Argument(
104
- None,
125
+ text: Optional[str] = ExclusiveTextSourceArgument(
126
+ default=None,
105
127
  help="Prompt to be used to generate a completion. Cannot be combined with --file option.",
106
128
  show_default=False,
107
129
  ),
@@ -110,9 +132,8 @@ def complete(
110
132
  "--model",
111
133
  help="String specifying the model to be used.",
112
134
  ),
113
- file: Optional[Path] = readable_file_option(
114
- param_name="--file",
115
- help_str="JSON file containing conversation history to be used to generate a completion. Cannot be combined with TEXT argument.",
135
+ file: Optional[Path] = ExclusiveReadableFileOption(
136
+ help="JSON file containing conversation history to be used to generate a completion. Cannot be combined with TEXT argument.",
116
137
  ),
117
138
  **options,
118
139
  ) -> CommandResult:
@@ -124,8 +145,6 @@ def complete(
124
145
 
125
146
  manager = CortexManager()
126
147
 
127
- if text and file:
128
- raise UsageError("--file option cannot be used together with TEXT argument.")
129
148
  if text:
130
149
  result_text = manager.complete_for_prompt(
131
150
  text=Text(text),
@@ -152,14 +171,13 @@ def extract_answer(
152
171
  help="String containing the question to be answered.",
153
172
  show_default=False,
154
173
  ),
155
- source_document_text: Optional[str] = typer.Argument(
156
- None,
174
+ source_document_text: Optional[str] = ExclusiveTextSourceArgument(
175
+ default=None,
157
176
  help="String containing the plain-text or JSON document that contains the answer to the question. Cannot be combined with --file option.",
158
177
  show_default=False,
159
178
  ),
160
- file: Optional[Path] = readable_file_option(
161
- param_name="--file",
162
- help_str="File containing the plain-text or JSON document that contains the answer to the question. Cannot be combined with SOURCE_DOCUMENT_TEXT argument.",
179
+ file: Optional[Path] = ExclusiveReadableFileOption(
180
+ help="File containing the plain-text or JSON document that contains the answer to the question. Cannot be combined with SOURCE_DOCUMENT_TEXT argument.",
163
181
  ),
164
182
  **options,
165
183
  ) -> CommandResult:
@@ -170,10 +188,6 @@ def extract_answer(
170
188
 
171
189
  manager = CortexManager()
172
190
 
173
- if source_document_text and file:
174
- raise UsageError(
175
- "--file option cannot be used together with SOURCE_DOCUMENT_TEXT argument."
176
- )
177
191
  if source_document_text:
178
192
  result_text = manager.extract_answer_from_source_document(
179
193
  source_document=SourceDocument(source_document_text),
@@ -197,14 +211,13 @@ def extract_answer(
197
211
  requires_connection=True,
198
212
  )
199
213
  def sentiment(
200
- text: Optional[str] = typer.Argument(
201
- None,
214
+ text: Optional[str] = ExclusiveTextSourceArgument(
215
+ default=None,
202
216
  help="String containing the text for which a sentiment score should be calculated. Cannot be combined with --file option.",
203
217
  show_default=False,
204
218
  ),
205
- file: Optional[Path] = readable_file_option(
206
- param_name="--file",
207
- help_str="File containing the text for which a sentiment score should be calculated. Cannot be combined with TEXT argument.",
219
+ file: Optional[Path] = ExclusiveReadableFileOption(
220
+ help="File containing the text for which a sentiment score should be calculated. Cannot be combined with TEXT argument.",
208
221
  ),
209
222
  **options,
210
223
  ) -> CommandResult:
@@ -216,8 +229,6 @@ def sentiment(
216
229
 
217
230
  manager = CortexManager()
218
231
 
219
- if text and file:
220
- raise UsageError("--file option cannot be used together with TEXT argument.")
221
232
  if text:
222
233
  result_text = manager.calculate_sentiment_for_text(
223
234
  text=Text(text),
@@ -237,14 +248,13 @@ def sentiment(
237
248
  requires_connection=True,
238
249
  )
239
250
  def summarize(
240
- text: Optional[str] = typer.Argument(
241
- None,
251
+ text: Optional[str] = ExclusiveTextSourceArgument(
252
+ default=None,
242
253
  help="String containing the English text from which a summary should be generated. Cannot be combined with --file option.",
243
254
  show_default=False,
244
255
  ),
245
- file: Optional[Path] = readable_file_option(
246
- param_name="--file",
247
- help_str="File containing the English text from which a summary should be generated. Cannot be combined with TEXT argument.",
256
+ file: Optional[Path] = ExclusiveReadableFileOption(
257
+ help="File containing the English text from which a summary should be generated. Cannot be combined with TEXT argument.",
248
258
  ),
249
259
  **options,
250
260
  ) -> CommandResult:
@@ -254,8 +264,6 @@ def summarize(
254
264
 
255
265
  manager = CortexManager()
256
266
 
257
- if text and file:
258
- raise UsageError("--file option cannot be used together with TEXT argument.")
259
267
  if text:
260
268
  result_text = manager.summarize_text(
261
269
  text=Text(text),
@@ -275,8 +283,8 @@ def summarize(
275
283
  requires_connection=True,
276
284
  )
277
285
  def translate(
278
- text: Optional[str] = typer.Argument(
279
- None,
286
+ text: Optional[str] = ExclusiveTextSourceArgument(
287
+ default=None,
280
288
  help="String containing the text to be translated. Cannot be combined with --file option.",
281
289
  show_default=False,
282
290
  ),
@@ -292,9 +300,8 @@ def translate(
292
300
  help="String specifying the language code into which the text should be translated. See Snowflake Cortex documentation for a list of supported language codes.",
293
301
  show_default=False,
294
302
  ),
295
- file: Optional[Path] = readable_file_option(
296
- param_name="--file",
297
- help_str="File containing the text to be translated. Cannot be combined with TEXT argument.",
303
+ file: Optional[Path] = ExclusiveReadableFileOption(
304
+ help="File containing the text to be translated. Cannot be combined with TEXT argument.",
298
305
  ),
299
306
  **options,
300
307
  ) -> CommandResult:
@@ -307,8 +314,6 @@ def translate(
307
314
  source_language = None if from_language is None else Language(from_language)
308
315
  target_language = Language(to_language)
309
316
 
310
- if text and file:
311
- raise UsageError("--file option cannot be used together with TEXT argument.")
312
317
  if text:
313
318
  result_text = manager.translate_text(
314
319
  text=Text(text),
@@ -12,6 +12,6 @@
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.cortex.types import Model
15
+ from snowflake.cli._plugins.cortex.types import Model
16
16
 
17
17
  DEFAULT_MODEL: Model = Model("snowflake-arctic")
@@ -19,17 +19,17 @@ import logging
19
19
  from typing import Callable, Optional
20
20
 
21
21
  from click import ClickException
22
- from snowflake.cli.api.constants import DEFAULT_SIZE_LIMIT_MB
23
- from snowflake.cli.api.exceptions import SnowflakeSQLExecutionError
24
- from snowflake.cli.api.secure_path import SecurePath
25
- from snowflake.cli.api.sql_execution import SqlExecutionMixin
26
- from snowflake.cli.plugins.cortex.types import (
22
+ from snowflake.cli._plugins.cortex.types import (
27
23
  Language,
28
24
  Model,
29
25
  Question,
30
26
  SourceDocument,
31
27
  Text,
32
28
  )
29
+ from snowflake.cli.api.constants import DEFAULT_SIZE_LIMIT_MB
30
+ from snowflake.cli.api.exceptions import SnowflakeSQLExecutionError
31
+ from snowflake.cli.api.secure_path import SecurePath
32
+ from snowflake.cli.api.sql_execution import SqlExecutionMixin
33
33
  from snowflake.connector import ProgrammingError
34
34
  from snowflake.connector.cursor import DictCursor
35
35
 
@@ -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.cortex 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.cortex import commands
22
22
 
23
23
 
24
24
  @plugin_hook_impl
@@ -22,6 +22,13 @@ from typing import List, Optional
22
22
 
23
23
  import typer
24
24
  from click import ClickException
25
+ from snowflake.cli._plugins.git.manager import GitManager
26
+ from snowflake.cli._plugins.object.command_aliases import (
27
+ add_object_command_aliases,
28
+ scope_option,
29
+ )
30
+ from snowflake.cli._plugins.object.manager import ObjectManager
31
+ from snowflake.cli.api.commands.common import OnErrorType
25
32
  from snowflake.cli.api.commands.flags import (
26
33
  ExecuteVariablesOption,
27
34
  OnErrorOption,
@@ -34,13 +41,6 @@ from snowflake.cli.api.console.console import cli_console
34
41
  from snowflake.cli.api.constants import ObjectType
35
42
  from snowflake.cli.api.output.types import CollectionResult, CommandResult, QueryResult
36
43
  from snowflake.cli.api.utils.path_utils import is_stage_path
37
- from snowflake.cli.plugins.git.manager import GitManager
38
- from snowflake.cli.plugins.object.command_aliases import (
39
- add_object_command_aliases,
40
- scope_option,
41
- )
42
- from snowflake.cli.plugins.object.manager import ObjectManager
43
- from snowflake.cli.plugins.stage.manager import OnErrorType
44
44
 
45
45
  app = SnowTyperFactory(
46
46
  name="git",
@@ -71,6 +71,7 @@ RepoPathArgument = typer.Argument(
71
71
  " For example: @my_repo/branches/main/"
72
72
  ),
73
73
  callback=_repo_path_argument_callback,
74
+ show_default=False,
74
75
  )
75
76
  add_object_command_aliases(
76
77
  app=app,
@@ -82,10 +83,12 @@ add_object_command_aliases(
82
83
  scope_option=scope_option(help_example="`list --in database my_db`"),
83
84
  )
84
85
 
86
+ from snowflake.cli.api.identifiers import FQN
85
87
 
86
- def _assure_repository_does_not_exist(om: ObjectManager, repository_name: str) -> None:
88
+
89
+ def _assure_repository_does_not_exist(om: ObjectManager, repository_name: FQN) -> None:
87
90
  if om.object_exists(
88
- object_type=ObjectType.GIT_REPOSITORY.value.cli_name, name=repository_name
91
+ object_type=ObjectType.GIT_REPOSITORY.value.cli_name, fqn=repository_name
89
92
  ):
90
93
  raise ClickException(f"Repository '{repository_name}' already exists")
91
94
 
@@ -97,12 +100,14 @@ def _validate_origin_url(url: str) -> None:
97
100
 
98
101
  @app.command("setup", requires_connection=True)
99
102
  def setup(
100
- repository_name: str = RepoNameArgument,
103
+ repository_name: FQN = RepoNameArgument,
101
104
  **options,
102
105
  ) -> CommandResult:
103
106
  """
104
107
  Sets up a git repository object.
105
108
 
109
+ ## Usage notes
110
+
106
111
  You will be prompted for:
107
112
 
108
113
  * url - address of repository to be used for git clone operation
@@ -127,8 +132,9 @@ def setup(
127
132
  secret_name = typer.prompt(
128
133
  "Secret identifier (will be created if not exists)", default=secret_name
129
134
  )
135
+ secret_fqn = FQN.from_string(secret_name)
130
136
  if om.object_exists(
131
- object_type=ObjectType.SECRET.value.cli_name, name=secret_name
137
+ object_type=ObjectType.SECRET.value.cli_name, fqn=secret_fqn
132
138
  ):
133
139
  cli_console.step(f"Using existing secret '{secret_name}'")
134
140
  else:
@@ -142,18 +148,19 @@ def setup(
142
148
  "API integration identifier (will be created if not exists)",
143
149
  default=api_integration,
144
150
  )
151
+ api_integration_fqn = FQN.from_string(api_integration)
145
152
 
146
153
  if should_create_secret:
147
154
  manager.create_password_secret(
148
- name=secret_name, username=secret_username, password=secret_password
155
+ name=secret_fqn, username=secret_username, password=secret_password
149
156
  )
150
157
  cli_console.step(f"Secret '{secret_name}' successfully created.")
151
158
 
152
159
  if not om.object_exists(
153
- object_type=ObjectType.INTEGRATION.value.cli_name, name=api_integration
160
+ object_type=ObjectType.INTEGRATION.value.cli_name, fqn=api_integration_fqn
154
161
  ):
155
162
  manager.create_api_integration(
156
- name=api_integration,
163
+ name=api_integration_fqn,
157
164
  api_provider="git_https_api",
158
165
  allowed_prefix=url,
159
166
  secret=secret_name,
@@ -177,7 +184,7 @@ def setup(
177
184
  requires_connection=True,
178
185
  )
179
186
  def list_branches(
180
- repository_name: str = RepoNameArgument,
187
+ repository_name: FQN = RepoNameArgument,
181
188
  like=like_option(
182
189
  help_example='`list-branches --like "%_test"` lists all branches that end with "_test"'
183
190
  ),
@@ -186,7 +193,9 @@ def list_branches(
186
193
  """
187
194
  List all branches in the repository.
188
195
  """
189
- return QueryResult(GitManager().show_branches(repo_name=repository_name, like=like))
196
+ return QueryResult(
197
+ GitManager().show_branches(repo_name=repository_name.identifier, like=like)
198
+ )
190
199
 
191
200
 
192
201
  @app.command(
@@ -194,7 +203,7 @@ def list_branches(
194
203
  requires_connection=True,
195
204
  )
196
205
  def list_tags(
197
- repository_name: str = RepoNameArgument,
206
+ repository_name: FQN = RepoNameArgument,
198
207
  like=like_option(
199
208
  help_example='`list-tags --like "v2.0%"` lists all tags that start with "v2.0"'
200
209
  ),
@@ -203,7 +212,9 @@ def list_tags(
203
212
  """
204
213
  List all tags in the repository.
205
214
  """
206
- return QueryResult(GitManager().show_tags(repo_name=repository_name, like=like))
215
+ return QueryResult(
216
+ GitManager().show_tags(repo_name=repository_name.identifier, like=like)
217
+ )
207
218
 
208
219
 
209
220
  @app.command(
@@ -228,13 +239,13 @@ def list_files(
228
239
  requires_connection=True,
229
240
  )
230
241
  def fetch(
231
- repository_name: str = RepoNameArgument,
242
+ repository_name: FQN = RepoNameArgument,
232
243
  **options,
233
244
  ) -> CommandResult:
234
245
  """
235
246
  Fetch changes from origin to Snowflake repository.
236
247
  """
237
- return QueryResult(GitManager().fetch(repo_name=repository_name))
248
+ return QueryResult(GitManager().fetch(fqn=repository_name))
238
249
 
239
250
 
240
251
  @app.command(
@@ -245,6 +256,7 @@ def copy(
245
256
  repository_path: str = RepoPathArgument,
246
257
  destination_path: str = typer.Argument(
247
258
  help="Target path for copy operation. Should be a path to a directory on remote stage or local file system.",
259
+ show_default=False,
248
260
  ),
249
261
  parallel: int = typer.Option(
250
262
  4,
@@ -18,12 +18,13 @@ from pathlib import Path
18
18
  from textwrap import dedent
19
19
  from typing import List
20
20
 
21
- from snowflake.cli.plugins.stage.manager import (
21
+ from snowflake.cli._plugins.stage.manager import (
22
22
  USER_STAGE_PREFIX,
23
23
  StageManager,
24
24
  StagePathParts,
25
25
  UserStagePathParts,
26
26
  )
27
+ from snowflake.cli.api.identifiers import FQN
27
28
  from snowflake.connector.cursor import SnowflakeCursor
28
29
 
29
30
 
@@ -63,15 +64,15 @@ class GitManager(StageManager):
63
64
  def show_tags(self, repo_name: str, like: str) -> SnowflakeCursor:
64
65
  return self._execute_query(f"show git tags like '{like}' in {repo_name}")
65
66
 
66
- def fetch(self, repo_name: str) -> SnowflakeCursor:
67
- return self._execute_query(f"alter git repository {repo_name} fetch")
67
+ def fetch(self, fqn: FQN) -> SnowflakeCursor:
68
+ return self._execute_query(f"alter git repository {fqn} fetch")
68
69
 
69
70
  def create(
70
- self, repo_name: str, api_integration: str, url: str, secret: str
71
+ self, repo_name: FQN, api_integration: str, url: str, secret: str
71
72
  ) -> SnowflakeCursor:
72
73
  query = dedent(
73
74
  f"""
74
- create git repository {repo_name}
75
+ create git repository {repo_name.sql_identifier}
75
76
  api_integration = {api_integration}
76
77
  origin = '{url}'
77
78
  """
@@ -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.git 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.git import commands
22
22
 
23
23
 
24
24
  @plugin_hook_impl
@@ -23,10 +23,10 @@ from click import ClickException
23
23
  from snowflake.cli.__about__ import VERSION
24
24
  from snowflake.cli.api.commands.flags import (
25
25
  NoInteractiveOption,
26
- parse_key_value_variables,
27
26
  variables_option,
28
27
  )
29
28
  from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
29
+ from snowflake.cli.api.commands.utils import parse_key_value_variables
30
30
  from snowflake.cli.api.constants import DEFAULT_SIZE_LIMIT_MB
31
31
  from snowflake.cli.api.exceptions import InvalidTemplate
32
32
  from snowflake.cli.api.output.types import (
@@ -68,7 +68,8 @@ TemplateOption = typer.Option(
68
68
  show_default=False,
69
69
  )
70
70
  SourceOption = typer.Option(
71
- default=DEFAULT_SOURCE,
71
+ DEFAULT_SOURCE,
72
+ "--template-source",
72
73
  help=f"local path to template directory or URL to git repository with templates.",
73
74
  )
74
75
  VariablesOption = variables_option(
@@ -106,7 +107,7 @@ def _fetch_remote_template(
106
107
  from git import rmtree as git_rmtree
107
108
 
108
109
  # TODO: during nativeapp refactor get rid of this dependency
109
- from snowflake.cli.plugins.nativeapp.utils import shallow_git_clone
110
+ from snowflake.cli._plugins.nativeapp.utils import shallow_git_clone
110
111
 
111
112
  log.info("Downloading remote template from %s", url)
112
113
  try:
@@ -132,13 +133,13 @@ def _fetch_remote_template(
132
133
  return template_root
133
134
 
134
135
 
135
- def _read_template_metadata(template_root: SecurePath) -> Template:
136
+ def _read_template_metadata(template_root: SecurePath, args_error_msg: str) -> Template:
136
137
  """Parse template.yml file."""
137
138
  template_metadata_path = template_root / TEMPLATE_METADATA_FILE_NAME
138
139
  log.debug("Reading template metadata from %s", template_metadata_path.path)
139
140
  if not template_metadata_path.exists():
140
141
  raise InvalidTemplate(
141
- f"Template does not have {TEMPLATE_METADATA_FILE_NAME} file."
142
+ f"File {TEMPLATE_METADATA_FILE_NAME} not found. {args_error_msg}"
142
143
  )
143
144
  with template_metadata_path.open(read_file_limit_mb=DEFAULT_SIZE_LIMIT_MB) as fd:
144
145
  yaml_contents = yaml.safe_load(fd) or {}
@@ -203,6 +204,7 @@ def init(
203
204
  is_remote = any(
204
205
  template_source.startswith(prefix) for prefix in ["git@", "http://", "https://"] # type: ignore
205
206
  )
207
+ args_error_msg = f"Check whether {TemplateOption.param_decls[0]} and {SourceOption.param_decls[0]} arguments are correct."
206
208
 
207
209
  # copy/download template into tmpdir, so it is going to be removed in case command ends with an error
208
210
  with SecurePath.temporary_directory() as tmpdir:
@@ -217,7 +219,9 @@ def init(
217
219
  destination=tmpdir,
218
220
  )
219
221
 
220
- template_metadata = _read_template_metadata(template_root)
222
+ template_metadata = _read_template_metadata(
223
+ template_root, args_error_msg=args_error_msg
224
+ )
221
225
  if template_metadata.minimum_cli_version:
222
226
  _validate_cli_version(template_metadata.minimum_cli_version)
223
227
 
@@ -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.init 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.init import commands
22
22
 
23
23
 
24
24
  @plugin_hook_impl
@@ -199,6 +199,12 @@ class _ArtifactPathMap:
199
199
  """
200
200
  return self.__src_to_dest.keys()
201
201
 
202
+ def is_empty(self) -> bool:
203
+ """
204
+ Returns True if this map has no source-destination mappings.
205
+ """
206
+ return len(self.__src_dest_pairs) == 0
207
+
202
208
  def __iter__(self) -> Iterator[Tuple[Path, Path]]:
203
209
  """
204
210
  Returns all (source, destination) pairs known to this map, in insertion order.
@@ -240,6 +246,9 @@ class BundleMap:
240
246
  self._deploy_root: Path = resolve_without_follow(deploy_root)
241
247
  self._artifact_map = _ArtifactPathMap(project_root=self._project_root)
242
248
 
249
+ def is_empty(self) -> bool:
250
+ return self._artifact_map.is_empty()
251
+
243
252
  def deploy_root(self) -> Path:
244
253
  return self._deploy_root
245
254
 
@@ -658,6 +667,11 @@ def build_bundle(
658
667
  for artifact in artifacts:
659
668
  bundle_map.add(artifact)
660
669
 
670
+ if bundle_map.is_empty():
671
+ raise ArtifactError(
672
+ "No artifacts mapping found in project definition, nothing to do."
673
+ )
674
+
661
675
  for (absolute_src, absolute_dest) in bundle_map.all_mappings(
662
676
  absolute=True, expand_directories=False
663
677
  ):
@@ -0,0 +1,31 @@
1
+ # Copyright (c) 2024 Snowflake Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from dataclasses import dataclass
16
+ from pathlib import Path
17
+ from typing import (
18
+ List,
19
+ )
20
+
21
+ from snowflake.cli.api.project.schemas.native_app.path_mapping import PathMapping
22
+
23
+
24
+ @dataclass
25
+ class BundleContext:
26
+ package_name: str
27
+ artifacts: List[PathMapping]
28
+ project_root: Path
29
+ bundle_root: Path
30
+ deploy_root: Path
31
+ generated_root: Path
@@ -19,11 +19,11 @@ from pathlib import Path
19
19
  from typing import Optional
20
20
 
21
21
  from click import ClickException
22
+ from snowflake.cli._plugins.nativeapp.bundle_context import BundleContext
22
23
  from snowflake.cli.api.project.schemas.native_app.path_mapping import (
23
24
  PathMapping,
24
25
  ProcessorMapping,
25
26
  )
26
- from snowflake.cli.plugins.nativeapp.project_model import NativeAppProjectModel
27
27
 
28
28
 
29
29
  class UnsupportedArtifactProcessorError(ClickException):
@@ -74,9 +74,9 @@ class ProjectFileContextManager:
74
74
  class ArtifactProcessor(ABC):
75
75
  def __init__(
76
76
  self,
77
- na_project: NativeAppProjectModel,
77
+ bundle_ctx: BundleContext,
78
78
  ) -> None:
79
- self._na_project = na_project
79
+ self._bundle_ctx = bundle_ctx
80
80
 
81
81
  @abstractmethod
82
82
  def process(