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