snowflake-cli-labs 2.8.0rc1__py3-none-any.whl → 3.0.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.
- snowflake/cli/__about__.py +1 -1
- snowflake/cli/{app → _app}/__main__.py +1 -1
- snowflake/cli/{app → _app}/cli_app.py +22 -13
- snowflake/cli/{app → _app}/commands_registration/builtin_plugins.py +15 -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/secret.py +9 -0
- snowflake/cli/{app → _app}/snow_connector.py +127 -61
- snowflake/cli/{app → _app}/telemetry.py +38 -7
- snowflake/cli/_app/version_check.py +74 -0
- snowflake/cli/{plugins → _plugins}/connection/commands.py +34 -11
- 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 +79 -26
- snowflake/cli/{plugins → _plugins}/git/manager.py +72 -17
- snowflake/cli/{plugins → _plugins}/git/plugin_spec.py +1 -1
- snowflake/cli/_plugins/helpers/commands.py +90 -0
- snowflake/cli/{plugins/notebook → _plugins/helpers}/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 +24 -9
- snowflake/cli/_plugins/nativeapp/bundle_context.py +31 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/artifact_processor.py +4 -4
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/compiler.py +37 -18
- snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +249 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/setup/setup_driver.py.source +5 -2
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/extension_function_utils.py +5 -5
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/models.py +1 -1
- snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/python_processor.py +29 -34
- snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +114 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/commands.py +252 -132
- snowflake/cli/{plugins → _plugins}/nativeapp/common_flags.py +1 -1
- snowflake/cli/_plugins/nativeapp/entities/application.py +878 -0
- snowflake/cli/_plugins/nativeapp/entities/application_package.py +1392 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/exceptions.py +3 -12
- snowflake/cli/_plugins/nativeapp/manager.py +415 -0
- snowflake/cli/{plugins/connection → _plugins/nativeapp}/plugin_spec.py +1 -1
- snowflake/cli/{plugins → _plugins}/nativeapp/policy.py +3 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/project_model.py +36 -20
- snowflake/cli/_plugins/nativeapp/run_processor.py +184 -0
- snowflake/cli/_plugins/nativeapp/same_account_install_method.py +70 -0
- snowflake/cli/_plugins/nativeapp/teardown_processor.py +70 -0
- snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +262 -0
- snowflake/cli/{plugins → _plugins}/nativeapp/version/commands.py +20 -49
- snowflake/cli/_plugins/nativeapp/version/version_processor.py +98 -0
- snowflake/cli/{plugins → _plugins}/notebook/commands.py +8 -6
- snowflake/cli/{plugins → _plugins}/notebook/manager.py +14 -14
- snowflake/cli/{plugins/nativeapp → _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 +43 -21
- snowflake/cli/{plugins → _plugins}/object/plugin_spec.py +1 -1
- snowflake/cli/_plugins/snowpark/commands.py +450 -0
- snowflake/cli/_plugins/snowpark/common.py +268 -0
- snowflake/cli/{plugins → _plugins}/snowpark/models.py +2 -8
- snowflake/cli/{plugins → _plugins}/snowpark/package/anaconda_packages.py +2 -36
- 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/snowpark/plugin_spec.py +30 -0
- snowflake/cli/_plugins/snowpark/snowpark_entity.py +29 -0
- snowflake/cli/_plugins/snowpark/snowpark_entity_model.py +173 -0
- 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 +20 -17
- 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 +62 -24
- snowflake/cli/{plugins → _plugins}/stage/plugin_spec.py +1 -1
- snowflake/cli/_plugins/stage/utils.py +54 -0
- snowflake/cli/{plugins → _plugins}/streamlit/commands.py +71 -62
- snowflake/cli/{plugins → _plugins}/streamlit/manager.py +68 -70
- snowflake/cli/_plugins/streamlit/plugin_spec.py +30 -0
- snowflake/cli/_plugins/streamlit/streamlit_entity.py +12 -0
- snowflake/cli/_plugins/streamlit/streamlit_entity_model.py +66 -0
- snowflake/cli/_plugins/workspace/action_context.py +18 -0
- snowflake/cli/_plugins/workspace/commands.py +306 -0
- snowflake/cli/_plugins/workspace/manager.py +74 -0
- snowflake/cli/_plugins/workspace/plugin_spec.py +30 -0
- snowflake/cli/api/cli_global_context.py +152 -295
- snowflake/cli/api/commands/common.py +25 -0
- snowflake/cli/api/commands/decorators.py +19 -4
- snowflake/cli/api/commands/experimental_behaviour.py +2 -3
- snowflake/cli/api/commands/flags.py +143 -222
- snowflake/cli/api/commands/overrideable_parameter.py +143 -0
- snowflake/cli/api/commands/snow_typer.py +21 -11
- snowflake/cli/api/commands/utils.py +18 -0
- snowflake/cli/api/config.py +44 -12
- snowflake/cli/api/connections.py +216 -0
- snowflake/cli/api/console/abc.py +8 -3
- snowflake/cli/api/constants.py +11 -0
- snowflake/cli/api/entities/common.py +56 -0
- snowflake/cli/api/entities/utils.py +370 -0
- snowflake/cli/api/errno.py +1 -0
- snowflake/cli/api/exceptions.py +31 -5
- snowflake/cli/api/feature_flags.py +0 -1
- snowflake/cli/api/identifiers.py +45 -9
- snowflake/cli/api/metrics.py +92 -0
- snowflake/cli/api/project/definition.py +48 -6
- snowflake/cli/api/project/definition_conversion.py +400 -0
- snowflake/cli/api/project/definition_manager.py +16 -5
- snowflake/cli/api/project/project_verification.py +3 -3
- snowflake/cli/api/project/schemas/entities/common.py +91 -16
- snowflake/cli/api/project/schemas/entities/entities.py +37 -6
- snowflake/cli/api/project/schemas/project_definition.py +180 -49
- snowflake/cli/api/project/schemas/updatable_model.py +11 -3
- snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{identifier_model.py → v1/identifier_model.py} +3 -1
- snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{native_app → v1/native_app}/application.py +8 -9
- snowflake/cli/api/project/schemas/{native_app → v1/native_app}/native_app.py +4 -4
- snowflake/cli/api/project/schemas/{native_app → v1/native_app}/package.py +7 -1
- snowflake/cli/api/project/schemas/v1/snowpark/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/callable.py +2 -2
- snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/snowpark.py +2 -2
- snowflake/cli/api/project/schemas/v1/streamlit/__init__.py +0 -0
- snowflake/cli/api/project/schemas/{streamlit → v1/streamlit}/streamlit.py +2 -1
- snowflake/cli/api/project/util.py +23 -6
- snowflake/cli/api/rendering/jinja.py +14 -8
- snowflake/cli/api/rendering/project_definition_templates.py +5 -1
- snowflake/cli/api/rendering/sql_templates.py +56 -11
- snowflake/cli/api/rest_api.py +11 -5
- snowflake/cli/api/secure_path.py +16 -18
- snowflake/cli/api/secure_utils.py +90 -1
- snowflake/cli/api/sql_execution.py +47 -27
- snowflake/cli/api/utils/definition_rendering.py +45 -13
- {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/METADATA +20 -18
- snowflake_cli_labs-3.0.0.dist-info/RECORD +242 -0
- snowflake_cli_labs-3.0.0.dist-info/entry_points.txt +2 -0
- snowflake/cli/api/commands/project_initialisation.py +0 -65
- snowflake/cli/api/commands/typer_pre_execute.py +0 -26
- snowflake/cli/api/project/schemas/entities/application_entity.py +0 -44
- snowflake/cli/api/project/schemas/entities/application_package_entity.py +0 -66
- snowflake/cli/app/build_and_push.sh +0 -8
- snowflake/cli/plugins/nativeapp/codegen/setup/native_app_setup_processor.py +0 -172
- snowflake/cli/plugins/nativeapp/init.py +0 -345
- snowflake/cli/plugins/nativeapp/manager.py +0 -823
- snowflake/cli/plugins/nativeapp/run_processor.py +0 -389
- snowflake/cli/plugins/nativeapp/teardown_processor.py +0 -301
- snowflake/cli/plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +0 -135
- snowflake/cli/plugins/nativeapp/version/version_processor.py +0 -362
- 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/__init__.py +0 -13
- snowflake/cli/plugins/streamlit/plugin_spec.py +0 -30
- snowflake/cli/plugins/workspace/__init__.py +0 -13
- snowflake/cli/plugins/workspace/commands.py +0 -35
- snowflake/cli/plugins/workspace/plugin_spec.py +0 -30
- snowflake/cli/templates/default_snowpark/.gitignore +0 -4
- 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/{api/project/schemas/native_app → _app/api_impl}/__init__.py +0 -0
- /snowflake/cli/{api/project/schemas/snowpark → _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/{api/project/schemas/streamlit → _app/dev}/__init__.py +0 -0
- /snowflake/cli/{app → _app}/dev/commands_structure.py +0 -0
- /snowflake/cli/{app/api_impl → _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/{app/api_impl/plugin → _plugins}/__init__.py +0 -0
- /snowflake/cli/{app/dev → _plugins/connection}/__init__.py +0 -0
- /snowflake/cli/{app/dev/docs → _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/connection → _plugins/helpers}/__init__.py +0 -0
- /snowflake/cli/{plugins/cortex → _plugins/init}/__init__.py +0 -0
- /snowflake/cli/{plugins/git → _plugins/nativeapp}/__init__.py +0 -0
- /snowflake/cli/{plugins/init → _plugins/nativeapp/codegen}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/sandbox.py +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/constants.py +0 -0
- /snowflake/cli/{templates/default_snowpark/app → _plugins/nativeapp/entities}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/feature_flags.py +0 -0
- /snowflake/cli/{plugins → _plugins}/nativeapp/utils.py +0 -0
- /snowflake/cli/{plugins/nativeapp → _plugins/nativeapp/version}/__init__.py +0 -0
- /snowflake/cli/{plugins/nativeapp/codegen → _plugins/notebook}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/notebook/exceptions.py +0 -0
- /snowflake/cli/{plugins/nativeapp/version → _plugins/object}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/object/common.py +0 -0
- /snowflake/cli/{plugins/notebook → _plugins/snowpark}/__init__.py +0 -0
- /snowflake/cli/{plugins/object → _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/snowpark → _plugins/spcs/compute_pool}/__init__.py +0 -0
- /snowflake/cli/{plugins/snowpark/package → _plugins/spcs/image_registry}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/spcs/image_registry/manager.py +0 -0
- /snowflake/cli/{plugins/spcs/compute_pool → _plugins/spcs/image_repository}/__init__.py +0 -0
- /snowflake/cli/{plugins/spcs/image_registry → _plugins/spcs/services}/__init__.py +0 -0
- /snowflake/cli/{plugins/spcs/image_repository → _plugins/sql}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/sql/snowsql_templating.py +0 -0
- /snowflake/cli/{plugins/spcs/jobs → _plugins/stage}/__init__.py +0 -0
- /snowflake/cli/{plugins → _plugins}/stage/md5.py +0 -0
- /snowflake/cli/{plugins/spcs/services → _plugins/streamlit}/__init__.py +0 -0
- /snowflake/cli/{plugins/sql → _plugins/workspace}/__init__.py +0 -0
- /snowflake/cli/{plugins/stage → api/project/schemas/entities}/__init__.py +0 -0
- /snowflake/cli/api/project/schemas/{native_app → v1/native_app}/path_mapping.py +0 -0
- /snowflake/cli/api/project/schemas/{snowpark → v1/snowpark}/argument.py +0 -0
- {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,450 @@
|
|
|
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
|
+
from collections import defaultdict
|
|
19
|
+
from typing import Dict, Optional, Set, Tuple
|
|
20
|
+
|
|
21
|
+
import typer
|
|
22
|
+
from click import ClickException, UsageError
|
|
23
|
+
from snowflake.cli._plugins.object.commands import (
|
|
24
|
+
describe as object_describe,
|
|
25
|
+
)
|
|
26
|
+
from snowflake.cli._plugins.object.commands import (
|
|
27
|
+
drop as object_drop,
|
|
28
|
+
)
|
|
29
|
+
from snowflake.cli._plugins.object.commands import (
|
|
30
|
+
list_ as object_list,
|
|
31
|
+
)
|
|
32
|
+
from snowflake.cli._plugins.object.commands import (
|
|
33
|
+
scope_option,
|
|
34
|
+
)
|
|
35
|
+
from snowflake.cli._plugins.object.manager import ObjectManager
|
|
36
|
+
from snowflake.cli._plugins.snowpark import package_utils
|
|
37
|
+
from snowflake.cli._plugins.snowpark.common import (
|
|
38
|
+
EntityToImportPathsMapping,
|
|
39
|
+
SnowparkEntities,
|
|
40
|
+
SnowparkObject,
|
|
41
|
+
SnowparkObjectManager,
|
|
42
|
+
StageToArtefactMapping,
|
|
43
|
+
)
|
|
44
|
+
from snowflake.cli._plugins.snowpark.package.anaconda_packages import (
|
|
45
|
+
AnacondaPackages,
|
|
46
|
+
AnacondaPackagesManager,
|
|
47
|
+
)
|
|
48
|
+
from snowflake.cli._plugins.snowpark.package.commands import app as package_app
|
|
49
|
+
from snowflake.cli._plugins.snowpark.snowpark_entity_model import (
|
|
50
|
+
FunctionEntityModel,
|
|
51
|
+
ProcedureEntityModel,
|
|
52
|
+
)
|
|
53
|
+
from snowflake.cli._plugins.snowpark.snowpark_project_paths import (
|
|
54
|
+
SnowparkProjectPaths,
|
|
55
|
+
)
|
|
56
|
+
from snowflake.cli._plugins.snowpark.snowpark_shared import (
|
|
57
|
+
AllowSharedLibrariesOption,
|
|
58
|
+
IgnoreAnacondaOption,
|
|
59
|
+
IndexUrlOption,
|
|
60
|
+
SkipVersionCheckOption,
|
|
61
|
+
)
|
|
62
|
+
from snowflake.cli._plugins.snowpark.zipper import zip_dir
|
|
63
|
+
from snowflake.cli._plugins.stage.manager import StageManager
|
|
64
|
+
from snowflake.cli.api.cli_global_context import (
|
|
65
|
+
get_cli_context,
|
|
66
|
+
)
|
|
67
|
+
from snowflake.cli.api.commands.decorators import (
|
|
68
|
+
with_project_definition,
|
|
69
|
+
)
|
|
70
|
+
from snowflake.cli.api.commands.flags import (
|
|
71
|
+
ReplaceOption,
|
|
72
|
+
execution_identifier_argument,
|
|
73
|
+
identifier_argument,
|
|
74
|
+
like_option,
|
|
75
|
+
)
|
|
76
|
+
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
77
|
+
from snowflake.cli.api.console import cli_console
|
|
78
|
+
from snowflake.cli.api.constants import (
|
|
79
|
+
DEFAULT_SIZE_LIMIT_MB,
|
|
80
|
+
)
|
|
81
|
+
from snowflake.cli.api.exceptions import (
|
|
82
|
+
SecretsWithoutExternalAccessIntegrationError,
|
|
83
|
+
)
|
|
84
|
+
from snowflake.cli.api.identifiers import FQN
|
|
85
|
+
from snowflake.cli.api.output.types import (
|
|
86
|
+
CollectionResult,
|
|
87
|
+
CommandResult,
|
|
88
|
+
MessageResult,
|
|
89
|
+
SingleQueryResult,
|
|
90
|
+
)
|
|
91
|
+
from snowflake.cli.api.project.definition_conversion import (
|
|
92
|
+
convert_project_definition_to_v2,
|
|
93
|
+
)
|
|
94
|
+
from snowflake.cli.api.project.schemas.project_definition import (
|
|
95
|
+
ProjectDefinition,
|
|
96
|
+
ProjectDefinitionV2,
|
|
97
|
+
)
|
|
98
|
+
from snowflake.cli.api.secure_path import SecurePath
|
|
99
|
+
from snowflake.connector import DictCursor, ProgrammingError
|
|
100
|
+
from snowflake.connector.cursor import SnowflakeCursor
|
|
101
|
+
|
|
102
|
+
log = logging.getLogger(__name__)
|
|
103
|
+
|
|
104
|
+
app = SnowTyperFactory(
|
|
105
|
+
name="snowpark",
|
|
106
|
+
help="Manages procedures and functions.",
|
|
107
|
+
)
|
|
108
|
+
app.add_typer(package_app)
|
|
109
|
+
|
|
110
|
+
ObjectTypeArgument = typer.Argument(
|
|
111
|
+
help="Type of Snowpark object",
|
|
112
|
+
case_sensitive=False,
|
|
113
|
+
show_default=False,
|
|
114
|
+
)
|
|
115
|
+
IdentifierArgument = identifier_argument(
|
|
116
|
+
"function/procedure",
|
|
117
|
+
example="hello(int, string)",
|
|
118
|
+
)
|
|
119
|
+
LikeOption = like_option(
|
|
120
|
+
help_example='`list function --like "my%"` lists all functions that begin with “my”',
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@app.command("deploy", requires_connection=True, require_warehouse=True)
|
|
125
|
+
@with_project_definition()
|
|
126
|
+
def deploy(
|
|
127
|
+
replace: bool = ReplaceOption(
|
|
128
|
+
help="Replaces procedure or function, even if no detected changes to metadata"
|
|
129
|
+
),
|
|
130
|
+
**options,
|
|
131
|
+
) -> CommandResult:
|
|
132
|
+
"""
|
|
133
|
+
Deploys procedures and functions defined in project. Deploying the project alters all objects defined in it.
|
|
134
|
+
By default, if any of the objects exist already the commands will fail unless `--replace` flag is provided.
|
|
135
|
+
Required artifacts are deployed before creating functions or procedures. Dependencies are deployed once to
|
|
136
|
+
every stage specified in definitions.
|
|
137
|
+
"""
|
|
138
|
+
cli_context = get_cli_context()
|
|
139
|
+
pd = _get_v2_project_definition(cli_context)
|
|
140
|
+
|
|
141
|
+
snowpark_entities = get_snowpark_entities(pd)
|
|
142
|
+
project_paths = SnowparkProjectPaths(
|
|
143
|
+
project_root=cli_context.project_root,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
with cli_console.phase("Performing initial validation"):
|
|
147
|
+
if not snowpark_entities:
|
|
148
|
+
raise ClickException(
|
|
149
|
+
"No procedures or functions were specified in the project definition."
|
|
150
|
+
)
|
|
151
|
+
validate_all_artifacts_exists(
|
|
152
|
+
project_paths=project_paths, snowpark_entities=snowpark_entities
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Validate current state
|
|
156
|
+
with cli_console.phase("Checking remote state"):
|
|
157
|
+
om = ObjectManager()
|
|
158
|
+
_check_if_all_defined_integrations_exists(om, snowpark_entities)
|
|
159
|
+
existing_objects = check_for_existing_objects(om, replace, snowpark_entities)
|
|
160
|
+
|
|
161
|
+
with cli_console.phase("Preparing required stages and artifacts"):
|
|
162
|
+
entities_to_imports_map, stages_to_artifact_map = build_artifacts_mappings(
|
|
163
|
+
project_paths=project_paths,
|
|
164
|
+
snowpark_entities=snowpark_entities,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
create_stages_and_upload_artifacts(stages_to_artifact_map)
|
|
168
|
+
|
|
169
|
+
# Create snowpark entities
|
|
170
|
+
with cli_console.phase("Creating Snowpark entities"):
|
|
171
|
+
snowpark_manager = SnowparkObjectManager()
|
|
172
|
+
snowflake_dependencies = _read_snowflake_requirements_file(
|
|
173
|
+
project_paths.snowflake_requirements
|
|
174
|
+
)
|
|
175
|
+
deploy_status = []
|
|
176
|
+
for entity in snowpark_entities.values():
|
|
177
|
+
operation_result = snowpark_manager.deploy_entity(
|
|
178
|
+
entity=entity,
|
|
179
|
+
existing_objects=existing_objects,
|
|
180
|
+
snowflake_dependencies=snowflake_dependencies,
|
|
181
|
+
entities_to_artifact_map=entities_to_imports_map,
|
|
182
|
+
)
|
|
183
|
+
deploy_status.append(operation_result)
|
|
184
|
+
|
|
185
|
+
return CollectionResult(deploy_status)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def validate_all_artifacts_exists(
|
|
189
|
+
project_paths: SnowparkProjectPaths, snowpark_entities: SnowparkEntities
|
|
190
|
+
):
|
|
191
|
+
for key, entity in snowpark_entities.items():
|
|
192
|
+
for artefact in entity.artifacts:
|
|
193
|
+
path = project_paths.get_artefact_dto(artefact).post_build_path
|
|
194
|
+
if not path.exists():
|
|
195
|
+
raise UsageError(
|
|
196
|
+
f"Artefact {path} required for {entity.type} {key} does not exist."
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def check_for_existing_objects(
|
|
201
|
+
om: ObjectManager, replace: bool, snowpark_entities: SnowparkEntities
|
|
202
|
+
) -> Dict[str, SnowflakeCursor]:
|
|
203
|
+
existing_objects: Dict[str, SnowflakeCursor] = _find_existing_objects(
|
|
204
|
+
snowpark_entities, om
|
|
205
|
+
)
|
|
206
|
+
if existing_objects and not replace:
|
|
207
|
+
existing_entities = [snowpark_entities[e] for e in existing_objects]
|
|
208
|
+
msg = "Following objects already exists. Consider using --replace.\n"
|
|
209
|
+
msg += "\n".join(f"{e.type}: {e.entity_id}" for e in existing_entities)
|
|
210
|
+
raise ClickException(msg)
|
|
211
|
+
return existing_objects
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def build_artifacts_mappings(
|
|
215
|
+
project_paths: SnowparkProjectPaths, snowpark_entities: SnowparkEntities
|
|
216
|
+
) -> Tuple[EntityToImportPathsMapping, StageToArtefactMapping]:
|
|
217
|
+
stages_to_artifact_map: StageToArtefactMapping = defaultdict(set)
|
|
218
|
+
entities_to_imports_map: EntityToImportPathsMapping = defaultdict(set)
|
|
219
|
+
for entity_id, entity in snowpark_entities.items():
|
|
220
|
+
stage = entity.stage
|
|
221
|
+
required_artifacts = set()
|
|
222
|
+
for artefact in entity.artifacts:
|
|
223
|
+
artefact_dto = project_paths.get_artefact_dto(artefact)
|
|
224
|
+
required_artifacts.add(artefact_dto)
|
|
225
|
+
entities_to_imports_map[entity_id].add(artefact_dto.import_path(stage))
|
|
226
|
+
stages_to_artifact_map[stage].update(required_artifacts)
|
|
227
|
+
|
|
228
|
+
if project_paths.dependencies.exists():
|
|
229
|
+
deps_artefact = project_paths.get_dependencies_artefact()
|
|
230
|
+
stages_to_artifact_map[stage].add(deps_artefact)
|
|
231
|
+
entities_to_imports_map[entity_id].add(deps_artefact.import_path(stage))
|
|
232
|
+
return entities_to_imports_map, stages_to_artifact_map
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def create_stages_and_upload_artifacts(stages_to_artifact_map: StageToArtefactMapping):
|
|
236
|
+
stage_manager = StageManager()
|
|
237
|
+
for stage, artifacts in stages_to_artifact_map.items():
|
|
238
|
+
cli_console.step(f"Creating (if not exists) stage: {stage}")
|
|
239
|
+
stage = FQN.from_stage(stage).using_context()
|
|
240
|
+
stage_manager.create(fqn=stage, comment="deployments managed by Snowflake CLI")
|
|
241
|
+
for artefact in artifacts:
|
|
242
|
+
cli_console.step(
|
|
243
|
+
f"Uploading {artefact.post_build_path.name} to {artefact.upload_path(stage)}"
|
|
244
|
+
)
|
|
245
|
+
stage_manager.put(
|
|
246
|
+
local_path=artefact.post_build_path,
|
|
247
|
+
stage_path=artefact.upload_path(stage),
|
|
248
|
+
overwrite=True,
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _find_existing_objects(
|
|
253
|
+
objects: SnowparkEntities,
|
|
254
|
+
om: ObjectManager,
|
|
255
|
+
) -> Dict[str, SnowflakeCursor]:
|
|
256
|
+
existing_objects = {}
|
|
257
|
+
for entity_id, entity in objects.items():
|
|
258
|
+
identifier = entity.udf_sproc_identifier.identifier_with_arg_types
|
|
259
|
+
try:
|
|
260
|
+
current_state = om.describe(
|
|
261
|
+
object_type=entity.type,
|
|
262
|
+
fqn=FQN.from_string(identifier),
|
|
263
|
+
)
|
|
264
|
+
existing_objects[entity_id] = current_state
|
|
265
|
+
except ProgrammingError:
|
|
266
|
+
pass
|
|
267
|
+
return existing_objects
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def _check_if_all_defined_integrations_exists(
|
|
271
|
+
om: ObjectManager,
|
|
272
|
+
snowpark_entities: SnowparkEntities,
|
|
273
|
+
):
|
|
274
|
+
existing_integrations = {
|
|
275
|
+
i["name"].lower()
|
|
276
|
+
for i in om.show(object_type="integration", cursor_class=DictCursor, like=None)
|
|
277
|
+
if i["type"] == "EXTERNAL_ACCESS"
|
|
278
|
+
}
|
|
279
|
+
declared_integration: Set[str] = set()
|
|
280
|
+
for object_definition in snowpark_entities.values():
|
|
281
|
+
external_access_integrations = {
|
|
282
|
+
s.lower() for s in object_definition.external_access_integrations
|
|
283
|
+
}
|
|
284
|
+
secrets = [s.lower() for s in object_definition.secrets]
|
|
285
|
+
|
|
286
|
+
if not external_access_integrations and secrets:
|
|
287
|
+
raise SecretsWithoutExternalAccessIntegrationError(object_definition.fqn)
|
|
288
|
+
|
|
289
|
+
declared_integration = declared_integration | external_access_integrations
|
|
290
|
+
|
|
291
|
+
missing = declared_integration - existing_integrations
|
|
292
|
+
if missing:
|
|
293
|
+
raise ClickException(
|
|
294
|
+
f"Following external access integration does not exists in Snowflake: {', '.join(missing)}"
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def _read_snowflake_requirements_file(file_path: SecurePath):
|
|
299
|
+
if not file_path.exists():
|
|
300
|
+
return []
|
|
301
|
+
return file_path.read_text(file_size_limit_mb=DEFAULT_SIZE_LIMIT_MB).splitlines()
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
@app.command("build", requires_connection=True)
|
|
305
|
+
@with_project_definition()
|
|
306
|
+
def build(
|
|
307
|
+
ignore_anaconda: bool = IgnoreAnacondaOption,
|
|
308
|
+
allow_shared_libraries: bool = AllowSharedLibrariesOption,
|
|
309
|
+
index_url: Optional[str] = IndexUrlOption,
|
|
310
|
+
skip_version_check: bool = SkipVersionCheckOption,
|
|
311
|
+
**options,
|
|
312
|
+
) -> CommandResult:
|
|
313
|
+
"""
|
|
314
|
+
Builds artifacts required for the Snowpark project. The artifacts can be used by `deploy` command.
|
|
315
|
+
For each directory in artifacts a .zip file is created. All non-anaconda dependencies are packaged in
|
|
316
|
+
dependencies.zip file.
|
|
317
|
+
"""
|
|
318
|
+
cli_context = get_cli_context()
|
|
319
|
+
pd = _get_v2_project_definition(cli_context)
|
|
320
|
+
|
|
321
|
+
project_paths = SnowparkProjectPaths(
|
|
322
|
+
project_root=cli_context.project_root,
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
anaconda_packages_manager = AnacondaPackagesManager()
|
|
326
|
+
|
|
327
|
+
# Resolve dependencies
|
|
328
|
+
if project_paths.requirements.exists():
|
|
329
|
+
with (
|
|
330
|
+
cli_console.phase("Resolving dependencies from requirements.txt"),
|
|
331
|
+
SecurePath.temporary_directory() as temp_deps_dir,
|
|
332
|
+
):
|
|
333
|
+
requirements = package_utils.parse_requirements(
|
|
334
|
+
requirements_file=project_paths.requirements,
|
|
335
|
+
)
|
|
336
|
+
anaconda_packages = (
|
|
337
|
+
AnacondaPackages.empty()
|
|
338
|
+
if ignore_anaconda
|
|
339
|
+
else anaconda_packages_manager.find_packages_available_in_snowflake_anaconda()
|
|
340
|
+
)
|
|
341
|
+
download_result = package_utils.download_unavailable_packages(
|
|
342
|
+
requirements=requirements,
|
|
343
|
+
target_dir=temp_deps_dir,
|
|
344
|
+
anaconda_packages=anaconda_packages,
|
|
345
|
+
skip_version_check=skip_version_check,
|
|
346
|
+
pip_index_url=index_url,
|
|
347
|
+
)
|
|
348
|
+
if not download_result.succeeded:
|
|
349
|
+
raise ClickException(download_result.error_message)
|
|
350
|
+
|
|
351
|
+
log.info("Checking to see if packages have shared (.so/.dll) libraries...")
|
|
352
|
+
if package_utils.detect_and_log_shared_libraries(
|
|
353
|
+
download_result.downloaded_packages_details
|
|
354
|
+
):
|
|
355
|
+
if not allow_shared_libraries:
|
|
356
|
+
raise ClickException(
|
|
357
|
+
"Some packages contain shared (.so/.dll) libraries. "
|
|
358
|
+
"Try again with --allow-shared-libraries."
|
|
359
|
+
)
|
|
360
|
+
if download_result.anaconda_packages:
|
|
361
|
+
anaconda_packages.write_requirements_file_in_snowflake_format( # type: ignore
|
|
362
|
+
file_path=project_paths.snowflake_requirements,
|
|
363
|
+
requirements=download_result.anaconda_packages,
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
if any(temp_deps_dir.path.iterdir()):
|
|
367
|
+
cli_console.step(f"Creating {project_paths.dependencies.name}")
|
|
368
|
+
zip_dir(
|
|
369
|
+
source=temp_deps_dir.path,
|
|
370
|
+
dest_zip=project_paths.dependencies,
|
|
371
|
+
)
|
|
372
|
+
else:
|
|
373
|
+
cli_console.step(f"No external dependencies.")
|
|
374
|
+
|
|
375
|
+
artifacts = set()
|
|
376
|
+
for entity in get_snowpark_entities(pd).values():
|
|
377
|
+
artifacts.update(entity.artifacts)
|
|
378
|
+
|
|
379
|
+
with cli_console.phase("Preparing artifacts for source code"):
|
|
380
|
+
for artefact in artifacts:
|
|
381
|
+
artefact_dto = project_paths.get_artefact_dto(artefact)
|
|
382
|
+
artefact_dto.build()
|
|
383
|
+
|
|
384
|
+
return MessageResult(f"Build done.")
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def get_snowpark_entities(
|
|
388
|
+
pd: ProjectDefinition,
|
|
389
|
+
) -> Dict[str, ProcedureEntityModel | FunctionEntityModel]:
|
|
390
|
+
procedures: Dict[str, ProcedureEntityModel] = pd.get_entities_by_type("procedure")
|
|
391
|
+
functions: Dict[str, FunctionEntityModel] = pd.get_entities_by_type("function")
|
|
392
|
+
snowpark_entities = {**procedures, **functions}
|
|
393
|
+
return snowpark_entities
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
@app.command("execute", requires_connection=True)
|
|
397
|
+
def execute(
|
|
398
|
+
object_type: SnowparkObject = ObjectTypeArgument,
|
|
399
|
+
execution_identifier: str = execution_identifier_argument(
|
|
400
|
+
"procedure/function", "hello(1, 'world')"
|
|
401
|
+
),
|
|
402
|
+
**options,
|
|
403
|
+
) -> CommandResult:
|
|
404
|
+
"""Executes a procedure or function in a specified environment."""
|
|
405
|
+
cursor = SnowparkObjectManager().execute(
|
|
406
|
+
execution_identifier=execution_identifier, object_type=object_type
|
|
407
|
+
)
|
|
408
|
+
return SingleQueryResult(cursor)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
@app.command("list", requires_connection=True)
|
|
412
|
+
def list_(
|
|
413
|
+
object_type: SnowparkObject = ObjectTypeArgument,
|
|
414
|
+
like: str = LikeOption,
|
|
415
|
+
scope: Tuple[str, str] = scope_option(
|
|
416
|
+
help_example="`list function --in database my_db`"
|
|
417
|
+
),
|
|
418
|
+
**options,
|
|
419
|
+
):
|
|
420
|
+
"""Lists all available procedures or functions."""
|
|
421
|
+
return object_list(object_type=object_type.value, like=like, scope=scope, **options)
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
@app.command("drop", requires_connection=True)
|
|
425
|
+
def drop(
|
|
426
|
+
object_type: SnowparkObject = ObjectTypeArgument,
|
|
427
|
+
identifier: FQN = IdentifierArgument,
|
|
428
|
+
**options,
|
|
429
|
+
):
|
|
430
|
+
"""Drop procedure or function."""
|
|
431
|
+
return object_drop(object_type=object_type.value, object_name=identifier, **options)
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
@app.command("describe", requires_connection=True)
|
|
435
|
+
def describe(
|
|
436
|
+
object_type: SnowparkObject = ObjectTypeArgument,
|
|
437
|
+
identifier: FQN = IdentifierArgument,
|
|
438
|
+
**options,
|
|
439
|
+
):
|
|
440
|
+
"""Provides description of a procedure or function."""
|
|
441
|
+
return object_describe(
|
|
442
|
+
object_type=object_type.value, object_name=identifier, **options
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def _get_v2_project_definition(cli_context) -> ProjectDefinitionV2:
|
|
447
|
+
pd = cli_context.project_definition
|
|
448
|
+
if not pd.meets_version_requirement("2"):
|
|
449
|
+
pd = convert_project_definition_to_v2(cli_context.project_root, pd)
|
|
450
|
+
return pd
|