snowflake-cli 3.3.0__py3-none-any.whl → 3.5.0__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 (112) hide show
  1. snowflake/cli/__about__.py +1 -1
  2. snowflake/cli/_app/__main__.py +2 -2
  3. snowflake/cli/_app/cli_app.py +220 -197
  4. snowflake/cli/_app/commands_registration/builtin_plugins.py +5 -1
  5. snowflake/cli/_app/commands_registration/command_plugins_loader.py +3 -1
  6. snowflake/cli/_app/commands_registration/commands_registration_with_callbacks.py +4 -30
  7. snowflake/cli/_app/printing.py +2 -2
  8. snowflake/cli/_plugins/connection/commands.py +2 -4
  9. snowflake/cli/_plugins/cortex/commands.py +2 -4
  10. snowflake/cli/_plugins/git/manager.py +1 -1
  11. snowflake/cli/_plugins/helpers/commands.py +3 -4
  12. snowflake/cli/_plugins/nativeapp/artifacts.py +6 -624
  13. snowflake/cli/_plugins/nativeapp/bundle_context.py +1 -1
  14. snowflake/cli/_plugins/nativeapp/codegen/artifact_processor.py +1 -1
  15. snowflake/cli/_plugins/nativeapp/codegen/compiler.py +1 -3
  16. snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +2 -2
  17. snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +2 -2
  18. snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +2 -2
  19. snowflake/cli/_plugins/nativeapp/commands.py +21 -19
  20. snowflake/cli/_plugins/nativeapp/entities/application.py +16 -19
  21. snowflake/cli/_plugins/nativeapp/entities/application_package.py +142 -55
  22. snowflake/cli/_plugins/nativeapp/release_channel/commands.py +37 -3
  23. snowflake/cli/_plugins/nativeapp/release_directive/commands.py +80 -2
  24. snowflake/cli/_plugins/nativeapp/sf_sql_facade.py +224 -44
  25. snowflake/cli/_plugins/nativeapp/v2_conversions/compat.py +2 -2
  26. snowflake/cli/_plugins/nativeapp/version/commands.py +1 -1
  27. snowflake/cli/_plugins/notebook/commands.py +54 -2
  28. snowflake/cli/_plugins/notebook/exceptions.py +1 -1
  29. snowflake/cli/_plugins/notebook/manager.py +3 -3
  30. snowflake/cli/_plugins/notebook/notebook_entity.py +120 -0
  31. snowflake/cli/_plugins/notebook/notebook_entity_model.py +42 -0
  32. snowflake/cli/_plugins/notebook/notebook_project_paths.py +15 -0
  33. snowflake/cli/_plugins/notebook/types.py +3 -0
  34. snowflake/cli/_plugins/plugin/commands.py +79 -0
  35. snowflake/cli/_plugins/plugin/manager.py +74 -0
  36. snowflake/cli/_plugins/plugin/plugin_spec.py +30 -0
  37. snowflake/cli/_plugins/project/__init__.py +0 -0
  38. snowflake/cli/_plugins/project/commands.py +157 -0
  39. snowflake/cli/_plugins/project/feature_flags.py +22 -0
  40. snowflake/cli/_plugins/project/manager.py +76 -0
  41. snowflake/cli/_plugins/project/plugin_spec.py +30 -0
  42. snowflake/cli/_plugins/project/project_entity_model.py +40 -0
  43. snowflake/cli/_plugins/snowpark/commands.py +49 -30
  44. snowflake/cli/_plugins/snowpark/common.py +47 -2
  45. snowflake/cli/_plugins/snowpark/snowpark_entity.py +38 -25
  46. snowflake/cli/_plugins/snowpark/snowpark_entity_model.py +18 -30
  47. snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +156 -23
  48. snowflake/cli/_plugins/snowpark/zipper.py +33 -1
  49. snowflake/cli/_plugins/spcs/compute_pool/commands.py +53 -5
  50. snowflake/cli/_plugins/spcs/compute_pool/compute_pool_entity.py +8 -0
  51. snowflake/cli/_plugins/spcs/compute_pool/compute_pool_entity_model.py +37 -0
  52. snowflake/cli/_plugins/spcs/compute_pool/manager.py +45 -0
  53. snowflake/cli/_plugins/spcs/image_repository/commands.py +29 -0
  54. snowflake/cli/_plugins/spcs/image_repository/image_repository_entity.py +8 -0
  55. snowflake/cli/_plugins/spcs/image_repository/image_repository_entity_model.py +8 -0
  56. snowflake/cli/_plugins/spcs/image_repository/manager.py +1 -1
  57. snowflake/cli/_plugins/spcs/services/commands.py +51 -1
  58. snowflake/cli/_plugins/spcs/services/manager.py +114 -0
  59. snowflake/cli/_plugins/spcs/services/service_entity.py +6 -0
  60. snowflake/cli/_plugins/spcs/services/service_entity_model.py +45 -0
  61. snowflake/cli/_plugins/spcs/services/service_project_paths.py +15 -0
  62. snowflake/cli/_plugins/stage/commands.py +2 -1
  63. snowflake/cli/_plugins/stage/diff.py +60 -39
  64. snowflake/cli/_plugins/stage/manager.py +26 -13
  65. snowflake/cli/_plugins/stage/utils.py +1 -1
  66. snowflake/cli/_plugins/streamlit/commands.py +18 -24
  67. snowflake/cli/_plugins/streamlit/manager.py +37 -27
  68. snowflake/cli/_plugins/streamlit/streamlit_entity.py +20 -41
  69. snowflake/cli/_plugins/streamlit/streamlit_entity_model.py +14 -24
  70. snowflake/cli/_plugins/streamlit/streamlit_project_paths.py +30 -0
  71. snowflake/cli/_plugins/workspace/commands.py +3 -3
  72. snowflake/cli/_plugins/workspace/manager.py +1 -1
  73. snowflake/cli/api/artifacts/bundle_map.py +500 -0
  74. snowflake/cli/api/artifacts/common.py +78 -0
  75. snowflake/cli/api/artifacts/upload.py +51 -0
  76. snowflake/cli/api/artifacts/utils.py +82 -0
  77. snowflake/cli/api/cli_global_context.py +14 -1
  78. snowflake/cli/api/commands/flags.py +34 -13
  79. snowflake/cli/api/commands/snow_typer.py +12 -0
  80. snowflake/cli/api/commands/utils.py +30 -2
  81. snowflake/cli/api/config.py +15 -10
  82. snowflake/cli/api/constants.py +1 -0
  83. snowflake/cli/api/entities/common.py +14 -32
  84. snowflake/cli/api/entities/resolver.py +160 -0
  85. snowflake/cli/api/entities/utils.py +56 -15
  86. snowflake/cli/api/errno.py +3 -0
  87. snowflake/cli/api/exceptions.py +8 -1
  88. snowflake/cli/api/feature_flags.py +1 -1
  89. snowflake/cli/api/plugins/plugin_config.py +43 -4
  90. snowflake/cli/api/project/definition_conversion.py +3 -2
  91. snowflake/cli/api/project/definition_helper.py +31 -0
  92. snowflake/cli/api/project/project_paths.py +28 -0
  93. snowflake/cli/api/project/schemas/entities/common.py +130 -1
  94. snowflake/cli/api/project/schemas/entities/entities.py +30 -0
  95. snowflake/cli/api/project/schemas/project_definition.py +27 -0
  96. snowflake/cli/api/project/schemas/updatable_model.py +2 -2
  97. snowflake/cli/api/project/schemas/v1/native_app/native_app.py +5 -7
  98. snowflake/cli/api/secure_path.py +6 -0
  99. snowflake/cli/api/sql_execution.py +5 -1
  100. snowflake/cli/api/stage_path.py +7 -2
  101. snowflake/cli/api/utils/graph.py +3 -0
  102. snowflake/cli/api/utils/path_utils.py +24 -0
  103. {snowflake_cli-3.3.0.dist-info → snowflake_cli-3.5.0.dist-info}/METADATA +12 -13
  104. {snowflake_cli-3.3.0.dist-info → snowflake_cli-3.5.0.dist-info}/RECORD +109 -85
  105. snowflake/cli/_app/api_impl/plugin/plugin_config_provider_impl.py +0 -66
  106. snowflake/cli/api/__init__.py +0 -48
  107. snowflake/cli/api/project/schemas/v1/native_app/path_mapping.py +0 -65
  108. /snowflake/cli/{_app/api_impl → _plugins/plugin}/__init__.py +0 -0
  109. /snowflake/cli/{_app/api_impl/plugin → api/artifacts}/__init__.py +0 -0
  110. {snowflake_cli-3.3.0.dist-info → snowflake_cli-3.5.0.dist-info}/WHEEL +0 -0
  111. {snowflake_cli-3.3.0.dist-info → snowflake_cli-3.5.0.dist-info}/entry_points.txt +0 -0
  112. {snowflake_cli-3.3.0.dist-info → snowflake_cli-3.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -14,4 +14,4 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- VERSION = "3.3.0"
17
+ VERSION = "3.5.0"
@@ -16,11 +16,11 @@ from __future__ import annotations
16
16
 
17
17
  import sys
18
18
 
19
- from snowflake.cli._app.cli_app import app_factory
19
+ from snowflake.cli._app.cli_app import CliAppFactory
20
20
 
21
21
 
22
22
  def main(*args):
23
- app = app_factory()
23
+ app = CliAppFactory().create_or_get_app()
24
24
  app(*args)
25
25
 
26
26
 
@@ -18,17 +18,13 @@ import logging
18
18
  import os
19
19
  import platform
20
20
  import sys
21
- from dataclasses import dataclass
22
21
  from pathlib import Path
23
22
  from typing import Optional
24
23
 
25
24
  import click
26
25
  import typer
27
- from click import Context
26
+ from click import Context as ClickContext
28
27
  from snowflake.cli import __about__
29
- from snowflake.cli._app.api_impl.plugin.plugin_config_provider_impl import (
30
- PluginConfigProviderImpl,
31
- )
32
28
  from snowflake.cli._app.commands_registration.commands_registration_with_callbacks import (
33
29
  CommandsRegistrationWithCallbacks,
34
30
  )
@@ -43,8 +39,7 @@ from snowflake.cli._app.version_check import (
43
39
  get_new_version_msg,
44
40
  show_new_version_banner_callback,
45
41
  )
46
- from snowflake.cli.api import Api, api_provider
47
- from snowflake.cli.api.config import config_init
42
+ from snowflake.cli.api.config import config_init, get_feature_flags_section
48
43
  from snowflake.cli.api.output.formats import OutputFormat
49
44
  from snowflake.cli.api.output.types import CollectionResult
50
45
  from snowflake.cli.api.secure_path import SecurePath
@@ -52,25 +47,6 @@ from snowflake.connector.config_manager import CONFIG_MANAGER
52
47
 
53
48
  log = logging.getLogger(__name__)
54
49
 
55
- _api = Api(plugin_config_provider=PluginConfigProviderImpl())
56
- api_provider.register_api(_api)
57
-
58
- _commands_registration = CommandsRegistrationWithCallbacks(_api.plugin_config_provider)
59
-
60
-
61
- @dataclass
62
- class AppContextHolder:
63
- # needed to access the context from tests
64
- app_context: Optional[Context] = None
65
-
66
-
67
- app_context_holder = AppContextHolder()
68
-
69
-
70
- def _exit_with_cleanup():
71
- _commands_registration.reset_running_instance_registration_state()
72
- raise typer.Exit()
73
-
74
50
 
75
51
  def _do_not_execute_on_completion(callback):
76
52
  def enriched_callback(value):
@@ -81,175 +57,222 @@ def _do_not_execute_on_completion(callback):
81
57
  return enriched_callback
82
58
 
83
59
 
84
- def _commands_registration_callback(value: bool):
85
- if value:
86
- _commands_registration.register_commands_if_ready_and_not_registered_yet()
87
- # required to make the tests working
88
- # because a single test can execute multiple commands using always the same "app" instance
89
- _commands_registration.reset_running_instance_registration_state()
90
- app_context_holder.app_context = click.get_current_context()
91
-
92
-
93
- @_commands_registration.before
94
- def _config_init_callback(configuration_file: Optional[Path]):
95
- config_init(configuration_file)
96
-
97
-
98
- @_commands_registration.before
99
- def _disable_external_command_plugins_callback(value: bool):
100
- if value:
101
- _commands_registration.disable_external_command_plugins()
102
-
103
-
104
- @_do_not_execute_on_completion
105
- @_commands_registration.after
106
- def _docs_callback(value: bool):
107
- if value:
108
- ctx = click.get_current_context()
109
- generate_docs(SecurePath("gen_docs"), ctx.command)
110
- _exit_with_cleanup()
111
-
112
-
113
- @_do_not_execute_on_completion
114
- @_commands_registration.after
115
- def _commands_structure_callback(value: bool):
116
- if value:
117
- ctx = click.get_current_context()
118
- generate_commands_structure(ctx.command).print_node()
119
- _exit_with_cleanup()
120
-
121
-
122
- @_do_not_execute_on_completion
123
- def _version_callback(value: bool):
124
- if value:
125
- print_result(MessageResult(f"Snowflake CLI version: {__about__.VERSION}"))
126
- _exit_with_cleanup()
127
-
128
-
129
- from snowflake.cli.api.config import get_feature_flags_section
130
-
131
-
132
- @_do_not_execute_on_completion
133
- def _info_callback(value: bool):
134
- if value:
135
- result = CollectionResult(
136
- [
137
- {"key": "version", "value": __about__.VERSION},
138
- {
139
- "key": "default_config_file_path",
140
- "value": str(CONFIG_MANAGER.file_path),
141
- },
142
- {"key": "python_version", "value": sys.version},
143
- {"key": "system_info", "value": platform.platform()},
144
- {"key": "feature_flags", "value": get_feature_flags_section()},
145
- {"key": "SNOWFLAKE_HOME", "value": os.getenv("SNOWFLAKE_HOME")},
146
- ],
147
- )
148
- print_result(result, output_format=OutputFormat.JSON)
149
- _exit_with_cleanup()
150
-
151
-
152
- def app_factory() -> SnowCliMainTyper:
153
- app = SnowCliMainTyper()
154
- new_version_msg = get_new_version_msg()
155
-
156
- @app.callback(
157
- invoke_without_command=True,
158
- epilog=new_version_msg,
159
- result_callback=show_new_version_banner_callback(new_version_msg),
160
- help=f"Snowflake CLI tool for developers [v{__about__.VERSION}]",
161
- )
162
- def default(
163
- ctx: typer.Context,
164
- version: bool = typer.Option(
165
- None,
166
- "--version",
167
- help="Shows version of the Snowflake CLI",
168
- callback=_version_callback,
169
- is_eager=True,
170
- ),
171
- docs: bool = typer.Option(
172
- None,
173
- "--docs",
174
- hidden=True,
175
- help="Generates Snowflake CLI documentation",
176
- callback=_docs_callback,
177
- is_eager=True,
178
- ),
179
- structure: bool = typer.Option(
180
- None,
181
- "--structure",
182
- hidden=True,
183
- help="Prints Snowflake CLI structure of commands",
184
- callback=_commands_structure_callback,
185
- is_eager=True,
186
- ),
187
- info: bool = typer.Option(
188
- None,
189
- "--info",
190
- help="Shows information about the Snowflake CLI",
191
- callback=_info_callback,
192
- ),
193
- configuration_file: Path = typer.Option(
194
- None,
195
- "--config-file",
196
- help="Specifies Snowflake CLI configuration file that should be used",
197
- exists=True,
198
- dir_okay=False,
199
- is_eager=True,
200
- callback=_config_init_callback,
201
- ),
202
- pycharm_debug_library_path: str = typer.Option(
203
- None,
204
- "--pycharm-debug-library-path",
205
- hidden=True,
206
- ),
207
- pycharm_debug_server_host: str = typer.Option(
208
- "localhost",
209
- "--pycharm-debug-server-host",
210
- hidden=True,
211
- ),
212
- pycharm_debug_server_port: int = typer.Option(
213
- 12345,
214
- "--pycharm-debug-server-port",
215
- hidden=True,
216
- ),
217
- disable_external_command_plugins: bool = typer.Option(
218
- None,
219
- "--disable-external-command-plugins",
220
- help="Disable external command plugins",
221
- callback=_disable_external_command_plugins_callback,
222
- is_eager=True,
223
- hidden=True,
224
- ),
225
- # THIS OPTION SHOULD BE THE LAST OPTION IN THE LIST!
226
- # ---
227
- # This is a hidden artificial option used only to guarantee execution of commands registration
228
- # and make this guaranty not dependent on other callbacks.
229
- # Commands registration is invoked as soon as all callbacks
230
- # decorated with "_commands_registration.before" are executed
231
- # but if there are no such callbacks (at the result of possible future changes)
232
- # then we need to invoke commands registration manually.
233
- #
234
- # This option is also responsible for resetting registration state for test purposes.
235
- commands_registration: bool = typer.Option(
236
- True,
237
- "--commands-registration",
238
- help="Commands registration",
239
- hidden=True,
240
- is_eager=True,
241
- callback=_commands_registration_callback,
242
- ),
243
- ) -> None:
244
- """
245
- Snowflake CLI tool for developers.
246
- """
247
- if not ctx.invoked_subcommand:
248
- typer.echo(ctx.get_help())
249
- setup_pycharm_remote_debugger_if_provided(
250
- pycharm_debug_library_path=pycharm_debug_library_path,
251
- pycharm_debug_server_host=pycharm_debug_server_host,
252
- pycharm_debug_server_port=pycharm_debug_server_port,
60
+ class CliAppFactory:
61
+ def __init__(self):
62
+ self._commands_registration = CommandsRegistrationWithCallbacks()
63
+ self._app: Optional[SnowCliMainTyper] = None
64
+ self._click_context: Optional[ClickContext] = None
65
+
66
+ def _exit_with_cleanup(self):
67
+ self._commands_registration.reset_running_instance_registration_state()
68
+ raise typer.Exit()
69
+
70
+ def _commands_registration_callback(self):
71
+ def callback(value: bool):
72
+ self._click_context = click.get_current_context()
73
+ if value:
74
+ self._commands_registration.register_commands_from_plugins()
75
+ # required to make the tests working
76
+ # because a single test can execute multiple commands using always the same "app" instance
77
+ self._commands_registration.reset_running_instance_registration_state()
78
+
79
+ return callback
80
+
81
+ @staticmethod
82
+ def _config_init_callback():
83
+ def callback(configuration_file: Optional[Path]):
84
+ config_init(configuration_file)
85
+
86
+ return callback
87
+
88
+ def _disable_external_command_plugins_callback(self):
89
+ def callback(value: bool):
90
+ if value:
91
+ self._commands_registration.disable_external_command_plugins()
92
+
93
+ return callback
94
+
95
+ def _docs_callback(self):
96
+ @_do_not_execute_on_completion
97
+ @self._commands_registration.after
98
+ def callback(value: bool):
99
+ if value:
100
+ ctx = click.get_current_context()
101
+ generate_docs(SecurePath("gen_docs"), ctx.command)
102
+ self._exit_with_cleanup()
103
+
104
+ return callback
105
+
106
+ def _help_callback(self):
107
+ @_do_not_execute_on_completion
108
+ @self._commands_registration.after
109
+ def callback(value: bool):
110
+ if value:
111
+ ctx = click.get_current_context()
112
+ typer.echo(ctx.get_help())
113
+ self._exit_with_cleanup()
114
+
115
+ return callback
116
+
117
+ def _commands_structure_callback(self):
118
+ @_do_not_execute_on_completion
119
+ @self._commands_registration.after
120
+ def callback(value: bool):
121
+ if value:
122
+ ctx = click.get_current_context()
123
+ generate_commands_structure(ctx.command).print_node()
124
+ self._exit_with_cleanup()
125
+
126
+ return callback
127
+
128
+ def _version_callback(self):
129
+ @_do_not_execute_on_completion
130
+ def callback(value: bool):
131
+ if value:
132
+ print_result(
133
+ MessageResult(f"Snowflake CLI version: {__about__.VERSION}")
134
+ )
135
+ self._exit_with_cleanup()
136
+
137
+ return callback
138
+
139
+ def _info_callback(self):
140
+ @_do_not_execute_on_completion
141
+ def callback(value: bool):
142
+ if value:
143
+ result = CollectionResult(
144
+ [
145
+ {"key": "version", "value": __about__.VERSION},
146
+ {
147
+ "key": "default_config_file_path",
148
+ "value": str(CONFIG_MANAGER.file_path),
149
+ },
150
+ {"key": "python_version", "value": sys.version},
151
+ {"key": "system_info", "value": platform.platform()},
152
+ {"key": "feature_flags", "value": get_feature_flags_section()},
153
+ {"key": "SNOWFLAKE_HOME", "value": os.getenv("SNOWFLAKE_HOME")},
154
+ ],
155
+ )
156
+ print_result(result, output_format=OutputFormat.JSON)
157
+ self._exit_with_cleanup()
158
+
159
+ return callback
160
+
161
+ def create_or_get_app(self) -> SnowCliMainTyper:
162
+ if self._app:
163
+ return self._app
164
+
165
+ app = SnowCliMainTyper()
166
+ new_version_msg = get_new_version_msg()
167
+
168
+ @app.callback(
169
+ invoke_without_command=True,
170
+ epilog=new_version_msg,
171
+ result_callback=show_new_version_banner_callback(new_version_msg),
172
+ add_help_option=False, # custom_help option added below
173
+ help=f"Snowflake CLI tool for developers [v{__about__.VERSION}]",
253
174
  )
254
-
255
- return app
175
+ def default(
176
+ ctx: typer.Context,
177
+ # We need a custom help option with _help_callback called after command registration
178
+ # to have all commands visible in the help.
179
+ # This is required since click 8.1.8, when the default help option
180
+ # has started to being executed before our eager options, including command registration.
181
+ custom_help: bool = typer.Option(
182
+ None,
183
+ "--help",
184
+ "-h",
185
+ help="Show this message and exit.",
186
+ callback=self._help_callback,
187
+ is_eager=True,
188
+ ),
189
+ version: bool = typer.Option(
190
+ None,
191
+ "--version",
192
+ help="Shows version of the Snowflake CLI",
193
+ callback=self._version_callback(),
194
+ is_eager=True,
195
+ ),
196
+ docs: bool = typer.Option(
197
+ None,
198
+ "--docs",
199
+ hidden=True,
200
+ help="Generates Snowflake CLI documentation",
201
+ callback=self._docs_callback(),
202
+ is_eager=True,
203
+ ),
204
+ structure: bool = typer.Option(
205
+ None,
206
+ "--structure",
207
+ hidden=True,
208
+ help="Prints Snowflake CLI structure of commands",
209
+ callback=self._commands_structure_callback(),
210
+ is_eager=True,
211
+ ),
212
+ info: bool = typer.Option(
213
+ None,
214
+ "--info",
215
+ help="Shows information about the Snowflake CLI",
216
+ callback=self._info_callback(),
217
+ ),
218
+ configuration_file: Path = typer.Option(
219
+ None,
220
+ "--config-file",
221
+ help="Specifies Snowflake CLI configuration file that should be used",
222
+ exists=True,
223
+ dir_okay=False,
224
+ is_eager=True,
225
+ callback=self._config_init_callback(),
226
+ ),
227
+ pycharm_debug_library_path: str = typer.Option(
228
+ None,
229
+ "--pycharm-debug-library-path",
230
+ hidden=True,
231
+ ),
232
+ pycharm_debug_server_host: str = typer.Option(
233
+ "localhost",
234
+ "--pycharm-debug-server-host",
235
+ hidden=True,
236
+ ),
237
+ pycharm_debug_server_port: int = typer.Option(
238
+ 12345,
239
+ "--pycharm-debug-server-port",
240
+ hidden=True,
241
+ ),
242
+ disable_external_command_plugins: bool = typer.Option(
243
+ None,
244
+ "--disable-external-command-plugins",
245
+ help="Disable external command plugins",
246
+ callback=self._disable_external_command_plugins_callback(),
247
+ is_eager=True,
248
+ hidden=True,
249
+ ),
250
+ # THIS OPTION SHOULD BE THE LAST OPTION IN THE LIST!
251
+ # ---
252
+ # This is a hidden artificial option used only to guarantee execution of commands registration.
253
+ # This option is also responsible for resetting registration state for test purposes.
254
+ commands_registration: bool = typer.Option(
255
+ True,
256
+ "--commands-registration",
257
+ help="Commands registration",
258
+ hidden=True,
259
+ is_eager=True,
260
+ callback=self._commands_registration_callback(),
261
+ ),
262
+ ) -> None:
263
+ """
264
+ Snowflake CLI tool for developers.
265
+ """
266
+ if not ctx.invoked_subcommand:
267
+ typer.echo(ctx.get_help())
268
+ setup_pycharm_remote_debugger_if_provided(
269
+ pycharm_debug_library_path=pycharm_debug_library_path,
270
+ pycharm_debug_server_host=pycharm_debug_server_host,
271
+ pycharm_debug_server_port=pycharm_debug_server_port,
272
+ )
273
+
274
+ self._app = app
275
+ return app
276
+
277
+ def get_click_context(self):
278
+ return self._click_context
@@ -20,6 +20,8 @@ from snowflake.cli._plugins.init import plugin_spec as init_plugin_spec
20
20
  from snowflake.cli._plugins.nativeapp import plugin_spec as nativeapp_plugin_spec
21
21
  from snowflake.cli._plugins.notebook import plugin_spec as notebook_plugin_spec
22
22
  from snowflake.cli._plugins.object import plugin_spec as object_plugin_spec
23
+ from snowflake.cli._plugins.plugin import plugin_spec as plugin_plugin_spec
24
+ from snowflake.cli._plugins.project import plugin_spec as project_plugin_spec
23
25
  from snowflake.cli._plugins.snowpark import plugin_spec as snowpark_plugin_spec
24
26
  from snowflake.cli._plugins.spcs import plugin_spec as spcs_plugin_spec
25
27
  from snowflake.cli._plugins.sql import plugin_spec as sql_plugin_spec
@@ -34,8 +36,9 @@ def get_builtin_plugin_name_to_plugin_spec():
34
36
  "connection": connection_plugin_spec,
35
37
  "helpers": migrate_plugin_spec,
36
38
  "spcs": spcs_plugin_spec,
37
- "nativeapp": nativeapp_plugin_spec,
39
+ "app": nativeapp_plugin_spec,
38
40
  "object": object_plugin_spec,
41
+ "project": project_plugin_spec,
39
42
  "snowpark": snowpark_plugin_spec,
40
43
  "stage": stage_plugin_spec,
41
44
  "sql": sql_plugin_spec,
@@ -45,6 +48,7 @@ def get_builtin_plugin_name_to_plugin_spec():
45
48
  "cortex": cortex_plugin_spec,
46
49
  "init": init_plugin_spec,
47
50
  "workspace": workspace_plugin_spec,
51
+ "plugin": plugin_plugin_spec,
48
52
  }
49
53
 
50
54
  return plugin_specs
@@ -47,7 +47,9 @@ class CommandPluginsLoader:
47
47
  self._loaded_command_paths: Dict[CommandPath, LoadedCommandPlugin] = {}
48
48
 
49
49
  def register_builtin_plugins(self) -> None:
50
- for plugin_name, plugin in get_builtin_plugin_name_to_plugin_spec().items():
50
+ for plugin_name, plugin in sorted(
51
+ get_builtin_plugin_name_to_plugin_spec().items()
52
+ ):
51
53
  try:
52
54
  self._plugin_manager.register(plugin=plugin, name=plugin_name)
53
55
  except Exception as ex:
@@ -21,7 +21,6 @@ from snowflake.cli._app.commands_registration.command_plugins_loader import (
21
21
  load_builtin_and_external_command_plugins,
22
22
  load_only_builtin_command_plugins,
23
23
  )
24
- from snowflake.cli._app.commands_registration.threadsafe import ThreadsafeCounter
25
24
  from snowflake.cli._app.commands_registration.typer_registration import (
26
25
  register_commands_from_plugins,
27
26
  )
@@ -34,29 +33,15 @@ class CommandRegistrationConfig:
34
33
 
35
34
 
36
35
  class CommandsRegistrationWithCallbacks:
37
- def __init__(self, plugin_config_provider: PluginConfigProvider):
38
- self._plugin_config_provider = plugin_config_provider
39
- self._counter_of_callbacks_required_before_registration: ThreadsafeCounter = (
40
- ThreadsafeCounter(0)
41
- )
42
- self._counter_of_callbacks_invoked_before_registration: ThreadsafeCounter = (
43
- ThreadsafeCounter(0)
44
- )
36
+ def __init__(self):
37
+ self._plugin_config_manager = PluginConfigProvider()
45
38
  self._callbacks_after_registration: List[Callable[[], None]] = []
46
39
  self._commands_registration_config: CommandRegistrationConfig = (
47
40
  CommandRegistrationConfig(enable_external_command_plugins=True)
48
41
  )
49
42
  self._commands_already_registered: bool = False
50
43
 
51
- def register_commands_if_ready_and_not_registered_yet(self):
52
- all_required_callbacks_executed = (
53
- self._counter_of_callbacks_required_before_registration.value
54
- == self._counter_of_callbacks_invoked_before_registration.value
55
- )
56
- if all_required_callbacks_executed and not self._commands_already_registered:
57
- self._register_commands_from_plugins()
58
-
59
- def _register_commands_from_plugins(self) -> None:
44
+ def register_commands_from_plugins(self) -> None:
60
45
  if self._commands_registration_config.enable_external_command_plugins:
61
46
  self._register_builtin_and_enabled_external_plugin_commands()
62
47
  else:
@@ -73,7 +58,7 @@ class CommandsRegistrationWithCallbacks:
73
58
 
74
59
  def _register_builtin_and_enabled_external_plugin_commands(self):
75
60
  enabled_external_plugins = (
76
- self._plugin_config_provider.get_enabled_plugin_names()
61
+ self._plugin_config_manager.get_enabled_plugin_names()
77
62
  )
78
63
  loaded_command_plugins = load_builtin_and_external_command_plugins(
79
64
  enabled_external_plugins
@@ -83,15 +68,6 @@ class CommandsRegistrationWithCallbacks:
83
68
  def disable_external_command_plugins(self):
84
69
  self._commands_registration_config.enable_external_command_plugins = False
85
70
 
86
- def before(self, callback):
87
- def enriched_callback(value):
88
- self._counter_of_callbacks_invoked_before_registration.increment()
89
- callback(value)
90
- self.register_commands_if_ready_and_not_registered_yet()
91
-
92
- self._counter_of_callbacks_required_before_registration.increment()
93
- return enriched_callback
94
-
95
71
  def after(self, callback):
96
72
  def delayed_callback(value):
97
73
  self._callbacks_after_registration.append(lambda: callback(value))
@@ -99,7 +75,5 @@ class CommandsRegistrationWithCallbacks:
99
75
  return delayed_callback
100
76
 
101
77
  def reset_running_instance_registration_state(self):
102
- self._commands_already_registered = False
103
- self._counter_of_callbacks_invoked_before_registration.set(0)
104
78
  self._callbacks_after_registration.clear()
105
79
  self._commands_registration_config.enable_external_command_plugins = True
@@ -16,7 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import json
18
18
  import sys
19
- from datetime import datetime
19
+ from datetime import date, datetime
20
20
  from json import JSONEncoder
21
21
  from pathlib import Path
22
22
  from textwrap import indent
@@ -57,7 +57,7 @@ class CustomJSONEncoder(JSONEncoder):
57
57
  return o.result
58
58
  if isinstance(o, (CollectionResult, MultipleResults)):
59
59
  return list(o.result)
60
- if isinstance(o, datetime):
60
+ if isinstance(o, (date, datetime)):
61
61
  return o.isoformat()
62
62
  if isinstance(o, Path):
63
63
  return str(o)
@@ -287,9 +287,7 @@ def add(
287
287
  ConnectionConfig(**connection_options),
288
288
  )
289
289
  if set_as_default:
290
- set_config_value(
291
- section=None, key="default_connection_name", value=connection_name
292
- )
290
+ set_config_value(path=["default_connection_name"], value=connection_name)
293
291
 
294
292
  return MessageResult(
295
293
  f"Wrote new connection {connection_name} to {connections_file}"
@@ -357,7 +355,7 @@ def set_default(
357
355
  ):
358
356
  """Changes default connection to provided value."""
359
357
  get_connection_dict(connection_name=name)
360
- set_config_value(section=None, key="default_connection_name", value=name)
358
+ set_config_value(path=["default_connection_name"], value=name)
361
359
  return MessageResult(f"Default connection set to: {name}")
362
360
 
363
361
 
@@ -96,16 +96,14 @@ def search(
96
96
  "Cortex Search uses Snowflake Python API that currently does not support your Python version"
97
97
  )
98
98
 
99
- from snowflake.core import Root
100
-
101
99
  if not columns:
102
100
  columns = []
103
101
 
104
102
  conn = get_cli_context().connection
103
+ root = get_cli_context().snow_api_root
105
104
 
106
105
  search_service = (
107
- Root(conn)
108
- .databases[conn.database]
106
+ root.databases[conn.database]
109
107
  .schemas[conn.schema]
110
108
  .cortex_search_services[service]
111
109
  )
@@ -116,7 +116,7 @@ class GitManager(StageManager):
116
116
  return f"{'/'.join(path_parts[ONLY_STAGE])}/"
117
117
 
118
118
  @staticmethod
119
- def _stage_path_part_factory(stage_path: str) -> StagePathParts:
119
+ def stage_path_parts_from_str(stage_path: str) -> StagePathParts:
120
120
  stage_path = StageManager.get_standard_stage_prefix(stage_path)
121
121
  if stage_path.startswith(USER_STAGE_PREFIX):
122
122
  return UserStagePathParts(stage_path)