snowflake-cli-labs 2.8.1__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 +11 -7
- snowflake/cli/{plugins → _plugins}/git/manager.py +55 -9
- 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 +2 -2
- 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 +3 -2
- snowflake/cli/{plugins → _plugins}/notebook/manager.py +5 -5
- snowflake/cli/{plugins/nativeapp → _plugins/notebook}/plugin_spec.py +1 -1
- snowflake/cli/{plugins → _plugins}/object/command_aliases.py +4 -4
- snowflake/cli/{plugins → _plugins}/object/commands.py +4 -5
- snowflake/cli/{plugins → _plugins}/object/manager.py +36 -15
- 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 +0 -7
- 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 +2 -2
- 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 +8 -8
- 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 +6 -6
- 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 +44 -11
- 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 +15 -14
- snowflake/cli/{plugins → _plugins}/stage/diff.py +1 -47
- snowflake/cli/{plugins → _plugins}/stage/manager.py +12 -7
- 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 +64 -48
- snowflake/cli/{plugins → _plugins}/streamlit/manager.py +67 -69
- 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 +127 -228
- 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 +28 -5
- 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 +43 -23
- snowflake/cli/api/utils/definition_rendering.py +45 -13
- {snowflake_cli_labs-2.8.1.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 -546
- 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.1.dist-info/RECORD +0 -240
- snowflake_cli_labs-2.8.1.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 → _plugins}/notebook/types.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.1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-2.8.1.dist-info → snowflake_cli_labs-3.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Copyright (c) 2024 Snowflake Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import List, Literal, Optional, Union
|
|
19
|
+
|
|
20
|
+
from pydantic import Field, field_validator
|
|
21
|
+
from snowflake.cli.api.identifiers import FQN
|
|
22
|
+
from snowflake.cli.api.project.schemas.entities.common import (
|
|
23
|
+
EntityModelBase,
|
|
24
|
+
ExternalAccessBaseModel,
|
|
25
|
+
ImportsBaseModel,
|
|
26
|
+
)
|
|
27
|
+
from snowflake.cli.api.project.schemas.updatable_model import (
|
|
28
|
+
DiscriminatorField,
|
|
29
|
+
UpdatableModel,
|
|
30
|
+
)
|
|
31
|
+
from snowflake.cli.api.project.schemas.v1.snowpark.argument import Argument
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class PathMapping(UpdatableModel):
|
|
35
|
+
class Config:
|
|
36
|
+
frozen = True
|
|
37
|
+
|
|
38
|
+
src: Path = Field(title="Source path (relative to project root)", default=None)
|
|
39
|
+
|
|
40
|
+
dest: Optional[str] = Field(
|
|
41
|
+
title="Destination path on stage",
|
|
42
|
+
description="Paths are relative to stage root; paths ending with a slash indicate that the destination is a directory which source files should be copied into.",
|
|
43
|
+
default=None,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class SnowparkEntityModel(EntityModelBase, ExternalAccessBaseModel, ImportsBaseModel):
|
|
48
|
+
handler: str = Field(
|
|
49
|
+
title="Function’s or procedure’s implementation of the object inside source module",
|
|
50
|
+
examples=["functions.hello_function"],
|
|
51
|
+
)
|
|
52
|
+
returns: str = Field(
|
|
53
|
+
title="Type of the result"
|
|
54
|
+
) # TODO: again, consider Literal/Enum
|
|
55
|
+
signature: Union[str, List[Argument]] = Field(
|
|
56
|
+
title="The signature parameter describes consecutive arguments passed to the object"
|
|
57
|
+
)
|
|
58
|
+
runtime: Optional[Union[str, float]] = Field(
|
|
59
|
+
title="Python version to use when executing ", default=None
|
|
60
|
+
)
|
|
61
|
+
stage: str = Field(title="Stage in which artifacts will be stored")
|
|
62
|
+
artifacts: List[Union[PathMapping, str]] = Field(title="List of required sources")
|
|
63
|
+
|
|
64
|
+
@field_validator("artifacts")
|
|
65
|
+
@classmethod
|
|
66
|
+
def _convert_artifacts(cls, artifacts: Union[dict, str]):
|
|
67
|
+
_artifacts = []
|
|
68
|
+
for artefact in artifacts:
|
|
69
|
+
if isinstance(artefact, PathMapping):
|
|
70
|
+
_artifacts.append(artefact)
|
|
71
|
+
else:
|
|
72
|
+
_artifacts.append(PathMapping(src=artefact))
|
|
73
|
+
return _artifacts
|
|
74
|
+
|
|
75
|
+
@field_validator("runtime")
|
|
76
|
+
@classmethod
|
|
77
|
+
def convert_runtime(cls, runtime_input: Union[str, float]) -> str:
|
|
78
|
+
if isinstance(runtime_input, float):
|
|
79
|
+
return str(runtime_input)
|
|
80
|
+
return runtime_input
|
|
81
|
+
|
|
82
|
+
@field_validator("artifacts")
|
|
83
|
+
@classmethod
|
|
84
|
+
def validate_artifacts(cls, artifacts: List[Path]) -> List[Path]:
|
|
85
|
+
for artefact in artifacts:
|
|
86
|
+
if "*" in str(artefact):
|
|
87
|
+
raise ValueError("Glob patterns not supported for Snowpark artifacts.")
|
|
88
|
+
return artifacts
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def udf_sproc_identifier(self) -> UdfSprocIdentifier:
|
|
92
|
+
return UdfSprocIdentifier.from_definition(self)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class ProcedureEntityModel(SnowparkEntityModel):
|
|
96
|
+
type: Literal["procedure"] = DiscriminatorField() # noqa: A003
|
|
97
|
+
execute_as_caller: Optional[bool] = Field(
|
|
98
|
+
title="Determine whether the procedure is executed with the privileges of "
|
|
99
|
+
"the owner (you) or with the privileges of the caller",
|
|
100
|
+
default=False,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class FunctionEntityModel(SnowparkEntityModel):
|
|
105
|
+
type: Literal["function"] = DiscriminatorField() # noqa: A003
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class UdfSprocIdentifier:
|
|
109
|
+
def __init__(self, identifier: FQN, arg_names, arg_types, arg_defaults):
|
|
110
|
+
self._identifier = identifier
|
|
111
|
+
self._arg_names = arg_names
|
|
112
|
+
self._arg_types = arg_types
|
|
113
|
+
self._arg_defaults = arg_defaults
|
|
114
|
+
|
|
115
|
+
def _identifier_from_signature(self, sig: List[str], for_sql: bool = False):
|
|
116
|
+
signature = self._comma_join(sig)
|
|
117
|
+
id_ = self._identifier.sql_identifier if for_sql else self._identifier
|
|
118
|
+
return f"{id_}({signature})"
|
|
119
|
+
|
|
120
|
+
@staticmethod
|
|
121
|
+
def _comma_join(*args):
|
|
122
|
+
return ", ".join(*args)
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def identifier_with_arg_names(self):
|
|
126
|
+
return self._identifier_from_signature(self._arg_names)
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def identifier_with_arg_types(self):
|
|
130
|
+
return self._identifier_from_signature(self._arg_types)
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def identifier_with_arg_names_types(self):
|
|
134
|
+
sig = [f"{n} {t}" for n, t in zip(self._arg_names, self._arg_types)]
|
|
135
|
+
return self._identifier_from_signature(sig)
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def identifier_with_arg_names_types_defaults(self):
|
|
139
|
+
return self._identifier_from_signature(self._full_signature())
|
|
140
|
+
|
|
141
|
+
def _is_signature_type_a_string(self, sig_type: str) -> bool:
|
|
142
|
+
return sig_type.lower() in ["string", "varchar"]
|
|
143
|
+
|
|
144
|
+
def _full_signature(self):
|
|
145
|
+
sig = []
|
|
146
|
+
for name, _type, _default in zip(
|
|
147
|
+
self._arg_names, self._arg_types, self._arg_defaults
|
|
148
|
+
):
|
|
149
|
+
s = f"{name} {_type}"
|
|
150
|
+
if _default:
|
|
151
|
+
if self._is_signature_type_a_string(_type):
|
|
152
|
+
_default = f"'{_default}'"
|
|
153
|
+
s += f" default {_default}"
|
|
154
|
+
sig.append(s)
|
|
155
|
+
return sig
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def identifier_for_sql(self):
|
|
159
|
+
return self._identifier_from_signature(self._full_signature(), for_sql=True)
|
|
160
|
+
|
|
161
|
+
@classmethod
|
|
162
|
+
def from_definition(cls, udf_sproc: SnowparkEntityModel):
|
|
163
|
+
names = []
|
|
164
|
+
types = []
|
|
165
|
+
defaults = []
|
|
166
|
+
if udf_sproc.signature and udf_sproc.signature != "null":
|
|
167
|
+
for arg in udf_sproc.signature:
|
|
168
|
+
names.append(arg.name) # type:ignore
|
|
169
|
+
types.append(arg.arg_type) # type:ignore
|
|
170
|
+
defaults.append(arg.default) # type:ignore
|
|
171
|
+
|
|
172
|
+
identifier = udf_sproc.fqn.using_context()
|
|
173
|
+
return cls(identifier, names, types, defaults)
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Copyright (c) 2024 Snowflake Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from pathlib import Path, PurePosixPath
|
|
18
|
+
|
|
19
|
+
from snowflake.cli._plugins.snowpark.snowpark_entity_model import PathMapping
|
|
20
|
+
from snowflake.cli._plugins.snowpark.zipper import zip_dir
|
|
21
|
+
from snowflake.cli.api.console import cli_console
|
|
22
|
+
from snowflake.cli.api.constants import DEPLOYMENT_STAGE
|
|
23
|
+
from snowflake.cli.api.identifiers import FQN
|
|
24
|
+
from snowflake.cli.api.secure_path import SecurePath
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class SnowparkProjectPaths:
|
|
29
|
+
"""
|
|
30
|
+
This class represents allows you to manage files paths related to given project.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
project_root: Path
|
|
34
|
+
|
|
35
|
+
def path_relative_to_root(self, artifact_path: Path) -> Path:
|
|
36
|
+
if artifact_path.is_absolute():
|
|
37
|
+
return artifact_path
|
|
38
|
+
return (self.project_root / artifact_path).resolve()
|
|
39
|
+
|
|
40
|
+
def get_artefact_dto(self, artifact_path: PathMapping) -> Artefact:
|
|
41
|
+
return Artefact(
|
|
42
|
+
dest=artifact_path.dest,
|
|
43
|
+
path=self.path_relative_to_root(artifact_path.src),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def get_dependencies_artefact(self) -> Artefact:
|
|
47
|
+
return Artefact(dest=None, path=self.dependencies)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def snowflake_requirements(self) -> SecurePath:
|
|
51
|
+
return SecurePath(
|
|
52
|
+
self.path_relative_to_root(Path("requirements.snowflake.txt"))
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def requirements(self) -> SecurePath:
|
|
57
|
+
return SecurePath(self.path_relative_to_root(Path("requirements.txt")))
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def dependencies(self) -> Path:
|
|
61
|
+
return self.path_relative_to_root(Path("dependencies.zip"))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass(unsafe_hash=True)
|
|
65
|
+
class Artefact:
|
|
66
|
+
"""Helper for getting paths related to given artefact."""
|
|
67
|
+
|
|
68
|
+
path: Path
|
|
69
|
+
dest: str | None = None
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def _artefact_name(self) -> str:
|
|
73
|
+
if self.path.is_dir():
|
|
74
|
+
return self.path.stem + ".zip"
|
|
75
|
+
return self.path.name
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def post_build_path(self) -> Path:
|
|
79
|
+
"""
|
|
80
|
+
Returns post-build artefact path. Directories are mapped to corresponding .zip files.
|
|
81
|
+
"""
|
|
82
|
+
return self.path.parent / self._artefact_name
|
|
83
|
+
|
|
84
|
+
def upload_path(self, stage: FQN | str | None) -> str:
|
|
85
|
+
"""
|
|
86
|
+
Path on stage to which the artefact should be uploaded.
|
|
87
|
+
"""
|
|
88
|
+
stage = stage or DEPLOYMENT_STAGE
|
|
89
|
+
if isinstance(stage, str):
|
|
90
|
+
stage = FQN.from_stage(stage).using_context()
|
|
91
|
+
|
|
92
|
+
stage_path = PurePosixPath(f"@{stage}")
|
|
93
|
+
if self.dest:
|
|
94
|
+
stage_path = stage_path / self.dest
|
|
95
|
+
return str(stage_path) + "/"
|
|
96
|
+
|
|
97
|
+
def import_path(self, stage: FQN | str | None) -> str:
|
|
98
|
+
"""Path for UDF/sproc imports clause."""
|
|
99
|
+
return self.upload_path(stage) + self._artefact_name
|
|
100
|
+
|
|
101
|
+
def build(self) -> None:
|
|
102
|
+
"""Build the artefact. Applies only to directories. Files are untouched."""
|
|
103
|
+
if not self.path.is_dir():
|
|
104
|
+
return
|
|
105
|
+
cli_console.step(f"Creating: {self.post_build_path.name}")
|
|
106
|
+
zip_dir(
|
|
107
|
+
source=self.path,
|
|
108
|
+
dest_zip=self.post_build_path,
|
|
109
|
+
)
|
|
@@ -14,33 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
import click
|
|
18
17
|
import typer
|
|
19
|
-
from snowflake.cli.api.commands.flags import (
|
|
20
|
-
deprecated_flag_callback,
|
|
21
|
-
deprecated_flag_callback_enum,
|
|
22
|
-
)
|
|
23
|
-
from snowflake.cli.plugins.snowpark.models import YesNoAsk
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def deprecated_allow_native_libraries_option(old_flag_name: str):
|
|
27
|
-
return typer.Option(
|
|
28
|
-
YesNoAsk.NO.value,
|
|
29
|
-
old_flag_name,
|
|
30
|
-
help="Allows native libraries, when using packages installed through PIP",
|
|
31
|
-
hidden=True,
|
|
32
|
-
callback=deprecated_flag_callback_enum(
|
|
33
|
-
f"{old_flag_name} flag is deprecated. Use --allow-shared-libraries flag instead."
|
|
34
|
-
),
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def resolve_allow_shared_libraries_yes_no_ask(allow_shared_libraries: YesNoAsk) -> bool:
|
|
39
|
-
if allow_shared_libraries == YesNoAsk.ASK:
|
|
40
|
-
return click.confirm("Continue with package installation?", default=False)
|
|
41
|
-
else:
|
|
42
|
-
return allow_shared_libraries == YesNoAsk.YES
|
|
43
|
-
|
|
44
18
|
|
|
45
19
|
AllowSharedLibrariesOption: bool = typer.Option(
|
|
46
20
|
False,
|
|
@@ -48,16 +22,6 @@ AllowSharedLibrariesOption: bool = typer.Option(
|
|
|
48
22
|
help="Allows shared (.so) libraries, when using packages installed through PIP.",
|
|
49
23
|
)
|
|
50
24
|
|
|
51
|
-
DeprecatedCheckAnacondaForPyPiDependencies: bool = typer.Option(
|
|
52
|
-
True,
|
|
53
|
-
"--check-anaconda-for-pypi-deps/--no-check-anaconda-for-pypi-deps",
|
|
54
|
-
"-a",
|
|
55
|
-
help="""Checks if any of missing Anaconda packages dependencies can be imported directly from Anaconda. Valid values include: `true`, `false`, Default: `true`.""",
|
|
56
|
-
hidden=True,
|
|
57
|
-
callback=deprecated_flag_callback(
|
|
58
|
-
"--check-anaconda-for-pypi-deps flag is deprecated. Use --ignore-anaconda flag instead."
|
|
59
|
-
),
|
|
60
|
-
)
|
|
61
25
|
|
|
62
26
|
IgnoreAnacondaOption: bool = typer.Option(
|
|
63
27
|
False,
|
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
import fnmatch
|
|
18
18
|
import logging
|
|
19
19
|
from pathlib import Path
|
|
20
|
-
from typing import
|
|
20
|
+
from typing import Dict, List, Literal
|
|
21
21
|
from zipfile import ZIP_DEFLATED, ZipFile
|
|
22
22
|
|
|
23
23
|
log = logging.getLogger(__name__)
|
|
@@ -59,16 +59,24 @@ def add_file_to_existing_zip(zip_file: str, file: str):
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
def zip_dir(
|
|
62
|
-
source: Path
|
|
62
|
+
source: Path | List[Path],
|
|
63
|
+
dest_zip: Path,
|
|
64
|
+
mode: Literal["r", "w", "x", "a"] = "w",
|
|
63
65
|
) -> None:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
|
|
67
|
+
if isinstance(source, Path):
|
|
68
|
+
source = [source]
|
|
69
|
+
|
|
70
|
+
files_to_pack: Dict[Path, List[Path]] = {
|
|
71
|
+
src: list(filter(_to_be_zipped, (f.absolute() for f in src.glob("**/*"))))
|
|
72
|
+
for src in source
|
|
73
|
+
}
|
|
67
74
|
|
|
68
75
|
with ZipFile(dest_zip, mode, ZIP_DEFLATED, allowZip64=True) as package_zip:
|
|
69
|
-
for
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
for src, files in files_to_pack.items():
|
|
77
|
+
for file in files:
|
|
78
|
+
log.debug("Adding %s to %s", file, dest_zip)
|
|
79
|
+
package_zip.write(file, arcname=file.relative_to(src))
|
|
72
80
|
|
|
73
81
|
|
|
74
82
|
def _to_be_zipped(file: Path) -> bool:
|
|
@@ -12,16 +12,15 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from snowflake.cli.
|
|
16
|
-
from snowflake.cli.plugins.spcs.compute_pool.commands import (
|
|
15
|
+
from snowflake.cli._plugins.spcs.compute_pool.commands import (
|
|
17
16
|
app as compute_pools_app,
|
|
18
17
|
)
|
|
19
|
-
from snowflake.cli.
|
|
20
|
-
from snowflake.cli.
|
|
18
|
+
from snowflake.cli._plugins.spcs.image_registry.commands import app as registry_app
|
|
19
|
+
from snowflake.cli._plugins.spcs.image_repository.commands import (
|
|
21
20
|
app as image_repository_app,
|
|
22
21
|
)
|
|
23
|
-
from snowflake.cli.
|
|
24
|
-
from snowflake.cli.
|
|
22
|
+
from snowflake.cli._plugins.spcs.services.commands import app as services_app
|
|
23
|
+
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
25
24
|
|
|
26
25
|
app = SnowTyperFactory(
|
|
27
26
|
name="spcs",
|
|
@@ -30,6 +29,5 @@ app = SnowTyperFactory(
|
|
|
30
29
|
|
|
31
30
|
app.add_typer(compute_pools_app)
|
|
32
31
|
app.add_typer(services_app)
|
|
33
|
-
app.add_typer(jobs_app)
|
|
34
32
|
app.add_typer(registry_app)
|
|
35
33
|
app.add_typer(image_repository_app)
|
|
@@ -18,6 +18,14 @@ from typing import Optional
|
|
|
18
18
|
|
|
19
19
|
import typer
|
|
20
20
|
from click import ClickException
|
|
21
|
+
from snowflake.cli._plugins.object.command_aliases import (
|
|
22
|
+
add_object_command_aliases,
|
|
23
|
+
)
|
|
24
|
+
from snowflake.cli._plugins.object.common import CommentOption
|
|
25
|
+
from snowflake.cli._plugins.spcs.common import (
|
|
26
|
+
validate_and_set_instances,
|
|
27
|
+
)
|
|
28
|
+
from snowflake.cli._plugins.spcs.compute_pool.manager import ComputePoolManager
|
|
21
29
|
from snowflake.cli.api.commands.flags import (
|
|
22
30
|
IfNotExistsOption,
|
|
23
31
|
OverrideableOption,
|
|
@@ -29,14 +37,6 @@ from snowflake.cli.api.constants import ObjectType
|
|
|
29
37
|
from snowflake.cli.api.identifiers import FQN
|
|
30
38
|
from snowflake.cli.api.output.types import CommandResult, SingleQueryResult
|
|
31
39
|
from snowflake.cli.api.project.util import is_valid_object_name
|
|
32
|
-
from snowflake.cli.plugins.object.command_aliases import (
|
|
33
|
-
add_object_command_aliases,
|
|
34
|
-
)
|
|
35
|
-
from snowflake.cli.plugins.object.common import CommentOption
|
|
36
|
-
from snowflake.cli.plugins.spcs.common import (
|
|
37
|
-
validate_and_set_instances,
|
|
38
|
-
)
|
|
39
|
-
from snowflake.cli.plugins.spcs.compute_pool.manager import ComputePoolManager
|
|
40
40
|
|
|
41
41
|
app = SnowTyperFactory(
|
|
42
42
|
name="compute-pool",
|
|
@@ -16,13 +16,13 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
from typing import List, Optional
|
|
18
18
|
|
|
19
|
-
from snowflake.cli.
|
|
20
|
-
from snowflake.cli.api.sql_execution import SqlExecutionMixin
|
|
21
|
-
from snowflake.cli.plugins.spcs.common import (
|
|
19
|
+
from snowflake.cli._plugins.spcs.common import (
|
|
22
20
|
NoPropertiesProvidedError,
|
|
23
21
|
handle_object_already_exists,
|
|
24
22
|
strip_empty_lines,
|
|
25
23
|
)
|
|
24
|
+
from snowflake.cli.api.constants import ObjectType
|
|
25
|
+
from snowflake.cli.api.sql_execution import SqlExecutionMixin
|
|
26
26
|
from snowflake.connector.cursor import SnowflakeCursor
|
|
27
27
|
from snowflake.connector.errors import ProgrammingError
|
|
28
28
|
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from snowflake.cli.
|
|
16
|
-
from snowflake.cli.api.output.types import MessageResult, ObjectResult
|
|
17
|
-
from snowflake.cli.plugins.spcs.image_registry.manager import (
|
|
15
|
+
from snowflake.cli._plugins.spcs.image_registry.manager import (
|
|
18
16
|
RegistryManager,
|
|
19
17
|
)
|
|
18
|
+
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
19
|
+
from snowflake.cli.api.output.types import MessageResult, ObjectResult
|
|
20
20
|
|
|
21
21
|
app = SnowTyperFactory(
|
|
22
22
|
name="image-registry",
|
|
@@ -20,6 +20,12 @@ from typing import Optional
|
|
|
20
20
|
import requests
|
|
21
21
|
import typer
|
|
22
22
|
from click import ClickException
|
|
23
|
+
from snowflake.cli._plugins.object.command_aliases import (
|
|
24
|
+
add_object_command_aliases,
|
|
25
|
+
scope_option,
|
|
26
|
+
)
|
|
27
|
+
from snowflake.cli._plugins.spcs.image_registry.manager import RegistryManager
|
|
28
|
+
from snowflake.cli._plugins.spcs.image_repository.manager import ImageRepositoryManager
|
|
23
29
|
from snowflake.cli.api.commands.flags import (
|
|
24
30
|
IfNotExistsOption,
|
|
25
31
|
ReplaceOption,
|
|
@@ -36,12 +42,6 @@ from snowflake.cli.api.output.types import (
|
|
|
36
42
|
SingleQueryResult,
|
|
37
43
|
)
|
|
38
44
|
from snowflake.cli.api.project.util import is_valid_object_name
|
|
39
|
-
from snowflake.cli.plugins.object.command_aliases import (
|
|
40
|
-
add_object_command_aliases,
|
|
41
|
-
scope_option,
|
|
42
|
-
)
|
|
43
|
-
from snowflake.cli.plugins.spcs.image_registry.manager import RegistryManager
|
|
44
|
-
from snowflake.cli.plugins.spcs.image_repository.manager import ImageRepositoryManager
|
|
45
45
|
|
|
46
46
|
app = SnowTyperFactory(
|
|
47
47
|
name="image-repository",
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
from urllib.parse import urlparse
|
|
16
16
|
|
|
17
|
+
from snowflake.cli._plugins.spcs.common import handle_object_already_exists
|
|
17
18
|
from snowflake.cli.api.constants import ObjectType
|
|
18
19
|
from snowflake.cli.api.identifiers import FQN
|
|
19
20
|
from snowflake.cli.api.sql_execution import SqlExecutionMixin
|
|
20
|
-
from snowflake.cli.plugins.spcs.common import handle_object_already_exists
|
|
21
21
|
from snowflake.connector.errors import ProgrammingError
|
|
22
22
|
|
|
23
23
|
|
|
@@ -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.spcs import app
|
|
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.spcs import app
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
@plugin_hook_impl
|
|
@@ -20,6 +20,16 @@ from typing import List, Optional
|
|
|
20
20
|
|
|
21
21
|
import typer
|
|
22
22
|
from click import ClickException
|
|
23
|
+
from snowflake.cli._plugins.object.command_aliases import (
|
|
24
|
+
add_object_command_aliases,
|
|
25
|
+
scope_option,
|
|
26
|
+
)
|
|
27
|
+
from snowflake.cli._plugins.object.common import CommentOption, Tag, TagOption
|
|
28
|
+
from snowflake.cli._plugins.spcs.common import (
|
|
29
|
+
print_log_lines,
|
|
30
|
+
validate_and_set_instances,
|
|
31
|
+
)
|
|
32
|
+
from snowflake.cli._plugins.spcs.services.manager import ServiceManager
|
|
23
33
|
from snowflake.cli.api.commands.flags import (
|
|
24
34
|
IfNotExistsOption,
|
|
25
35
|
OverrideableOption,
|
|
@@ -36,16 +46,6 @@ from snowflake.cli.api.output.types import (
|
|
|
36
46
|
SingleQueryResult,
|
|
37
47
|
)
|
|
38
48
|
from snowflake.cli.api.project.util import is_valid_object_name
|
|
39
|
-
from snowflake.cli.plugins.object.command_aliases import (
|
|
40
|
-
add_object_command_aliases,
|
|
41
|
-
scope_option,
|
|
42
|
-
)
|
|
43
|
-
from snowflake.cli.plugins.object.common import CommentOption, Tag, TagOption
|
|
44
|
-
from snowflake.cli.plugins.spcs.common import (
|
|
45
|
-
print_log_lines,
|
|
46
|
-
validate_and_set_instances,
|
|
47
|
-
)
|
|
48
|
-
from snowflake.cli.plugins.spcs.services.manager import ServiceManager
|
|
49
49
|
|
|
50
50
|
app = SnowTyperFactory(
|
|
51
51
|
name="service",
|
|
@@ -63,7 +63,7 @@ def _service_name_callback(name: FQN) -> FQN:
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
ServiceNameArgument = identifier_argument(
|
|
66
|
-
sf_object="service
|
|
66
|
+
sf_object="service",
|
|
67
67
|
example="my_service",
|
|
68
68
|
callback=_service_name_callback,
|
|
69
69
|
)
|
|
@@ -161,6 +161,39 @@ def create(
|
|
|
161
161
|
return SingleQueryResult(cursor)
|
|
162
162
|
|
|
163
163
|
|
|
164
|
+
@app.command(requires_connection=True)
|
|
165
|
+
def execute_job(
|
|
166
|
+
name: FQN = ServiceNameArgument,
|
|
167
|
+
compute_pool: str = typer.Option(
|
|
168
|
+
...,
|
|
169
|
+
"--compute-pool",
|
|
170
|
+
help="Compute pool to run the job service on.",
|
|
171
|
+
show_default=False,
|
|
172
|
+
),
|
|
173
|
+
spec_path: Path = SpecPathOption,
|
|
174
|
+
external_access_integrations: Optional[List[str]] = typer.Option(
|
|
175
|
+
None,
|
|
176
|
+
"--eai-name",
|
|
177
|
+
help="Identifies External Access Integrations(EAI) that the job service can access. This option may be specified multiple times for multiple EAIs.",
|
|
178
|
+
),
|
|
179
|
+
query_warehouse: Optional[str] = QueryWarehouseOption(),
|
|
180
|
+
comment: Optional[str] = CommentOption(help=_COMMENT_HELP),
|
|
181
|
+
**options,
|
|
182
|
+
) -> CommandResult:
|
|
183
|
+
"""
|
|
184
|
+
Creates and executes a job service in the current schema.
|
|
185
|
+
"""
|
|
186
|
+
cursor = ServiceManager().execute_job(
|
|
187
|
+
job_service_name=name.identifier,
|
|
188
|
+
compute_pool=compute_pool,
|
|
189
|
+
spec_path=spec_path,
|
|
190
|
+
external_access_integrations=external_access_integrations,
|
|
191
|
+
query_warehouse=query_warehouse,
|
|
192
|
+
comment=comment,
|
|
193
|
+
)
|
|
194
|
+
return SingleQueryResult(cursor)
|
|
195
|
+
|
|
196
|
+
|
|
164
197
|
@app.command(requires_connection=True)
|
|
165
198
|
def status(name: FQN = ServiceNameArgument, **options) -> CommandResult:
|
|
166
199
|
"""
|
|
@@ -19,15 +19,15 @@ from pathlib import Path
|
|
|
19
19
|
from typing import List, Optional
|
|
20
20
|
|
|
21
21
|
import yaml
|
|
22
|
-
from snowflake.cli.
|
|
23
|
-
from snowflake.cli.
|
|
24
|
-
from snowflake.cli.api.sql_execution import SqlExecutionMixin
|
|
25
|
-
from snowflake.cli.plugins.object.common import Tag
|
|
26
|
-
from snowflake.cli.plugins.spcs.common import (
|
|
22
|
+
from snowflake.cli._plugins.object.common import Tag
|
|
23
|
+
from snowflake.cli._plugins.spcs.common import (
|
|
27
24
|
NoPropertiesProvidedError,
|
|
28
25
|
handle_object_already_exists,
|
|
29
26
|
strip_empty_lines,
|
|
30
27
|
)
|
|
28
|
+
from snowflake.cli.api.constants import DEFAULT_SIZE_LIMIT_MB, ObjectType
|
|
29
|
+
from snowflake.cli.api.secure_path import SecurePath
|
|
30
|
+
from snowflake.cli.api.sql_execution import SqlExecutionMixin
|
|
31
31
|
from snowflake.connector.cursor import SnowflakeCursor
|
|
32
32
|
from snowflake.connector.errors import ProgrammingError
|
|
33
33
|
|
|
@@ -85,6 +85,44 @@ class ServiceManager(SqlExecutionMixin):
|
|
|
85
85
|
except ProgrammingError as e:
|
|
86
86
|
handle_object_already_exists(e, ObjectType.SERVICE, service_name)
|
|
87
87
|
|
|
88
|
+
def execute_job(
|
|
89
|
+
self,
|
|
90
|
+
job_service_name: str,
|
|
91
|
+
compute_pool: str,
|
|
92
|
+
spec_path: Path,
|
|
93
|
+
external_access_integrations: Optional[List[str]],
|
|
94
|
+
query_warehouse: Optional[str],
|
|
95
|
+
comment: Optional[str],
|
|
96
|
+
) -> SnowflakeCursor:
|
|
97
|
+
spec = self._read_yaml(spec_path)
|
|
98
|
+
query = f"""\
|
|
99
|
+
EXECUTE JOB SERVICE
|
|
100
|
+
IN COMPUTE POOL {compute_pool}
|
|
101
|
+
FROM SPECIFICATION $$
|
|
102
|
+
{spec}
|
|
103
|
+
$$
|
|
104
|
+
NAME = {job_service_name}
|
|
105
|
+
""".splitlines()
|
|
106
|
+
|
|
107
|
+
if external_access_integrations:
|
|
108
|
+
external_access_integration_list = ",".join(
|
|
109
|
+
f"{e}" for e in external_access_integrations
|
|
110
|
+
)
|
|
111
|
+
query.append(
|
|
112
|
+
f"EXTERNAL_ACCESS_INTEGRATIONS = ({external_access_integration_list})"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
if query_warehouse:
|
|
116
|
+
query.append(f"QUERY_WAREHOUSE = {query_warehouse}")
|
|
117
|
+
|
|
118
|
+
if comment:
|
|
119
|
+
query.append(f"COMMENT = {comment}")
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
return self._execute_query(strip_empty_lines(query))
|
|
123
|
+
except ProgrammingError as e:
|
|
124
|
+
handle_object_already_exists(e, ObjectType.SERVICE, job_service_name)
|
|
125
|
+
|
|
88
126
|
def _read_yaml(self, path: Path) -> str:
|
|
89
127
|
# TODO(aivanou): Add validation towards schema
|
|
90
128
|
with SecurePath(path).open("r", read_file_limit_mb=DEFAULT_SIZE_LIMIT_MB) as fh:
|