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
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from click import ClickException
|
|
4
|
+
from snowflake.cli.api.commands.common import Variable
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def parse_key_value_variables(variables: Optional[List[str]]) -> List[Variable]:
|
|
8
|
+
"""Util for parsing key=value input. Useful for commands accepting multiple input options."""
|
|
9
|
+
result: List[Variable] = []
|
|
10
|
+
if not variables:
|
|
11
|
+
return result
|
|
12
|
+
for p in variables:
|
|
13
|
+
if "=" not in p:
|
|
14
|
+
raise ClickException(f"Invalid variable: '{p}'")
|
|
15
|
+
|
|
16
|
+
key, value = p.split("=", 1)
|
|
17
|
+
result.append(Variable(key.strip(), value.strip()))
|
|
18
|
+
return result
|
snowflake/cli/api/config.py
CHANGED
|
@@ -115,7 +115,7 @@ def config_init(config_file: Optional[Path]):
|
|
|
115
115
|
Initializes the app configuration. Config provided via cli flag takes precedence.
|
|
116
116
|
If config file does not exist we create an empty one.
|
|
117
117
|
"""
|
|
118
|
-
from snowflake.cli.
|
|
118
|
+
from snowflake.cli._app.loggers import create_initial_loggers
|
|
119
119
|
|
|
120
120
|
if config_file:
|
|
121
121
|
CONFIG_MANAGER.file_path = config_file
|
snowflake/cli/api/console/abc.py
CHANGED
|
@@ -20,7 +20,10 @@ from typing import Callable, Iterator, Optional
|
|
|
20
20
|
|
|
21
21
|
from rich import print as rich_print
|
|
22
22
|
from rich.text import Text
|
|
23
|
-
from snowflake.cli.api.cli_global_context import
|
|
23
|
+
from snowflake.cli.api.cli_global_context import (
|
|
24
|
+
_CliGlobalContextAccess,
|
|
25
|
+
get_cli_context,
|
|
26
|
+
)
|
|
24
27
|
|
|
25
28
|
|
|
26
29
|
class AbstractConsole(ABC):
|
|
@@ -39,7 +42,7 @@ class AbstractConsole(ABC):
|
|
|
39
42
|
|
|
40
43
|
def __init__(self):
|
|
41
44
|
super().__init__()
|
|
42
|
-
self._cli_context =
|
|
45
|
+
self._cli_context = get_cli_context()
|
|
43
46
|
self._in_phase = False
|
|
44
47
|
|
|
45
48
|
@property
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from snowflake.cli.api.entities.common import EntityBase
|
|
2
|
+
from snowflake.cli.api.project.schemas.entities.application_entity_model import (
|
|
3
|
+
ApplicationEntityModel,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ApplicationEntity(EntityBase[ApplicationEntityModel]):
|
|
8
|
+
"""
|
|
9
|
+
A Native App application object, created from an application package.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
pass
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
from contextlib import contextmanager
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from textwrap import dedent
|
|
4
|
+
from typing import List, Optional
|
|
5
|
+
|
|
6
|
+
from click import ClickException
|
|
7
|
+
from snowflake.cli._plugins.nativeapp.artifacts import build_bundle
|
|
8
|
+
from snowflake.cli._plugins.nativeapp.bundle_context import BundleContext
|
|
9
|
+
from snowflake.cli._plugins.nativeapp.codegen.compiler import NativeAppCompiler
|
|
10
|
+
from snowflake.cli._plugins.nativeapp.constants import (
|
|
11
|
+
ALLOWED_SPECIAL_COMMENTS,
|
|
12
|
+
COMMENT_COL,
|
|
13
|
+
INTERNAL_DISTRIBUTION,
|
|
14
|
+
NAME_COL,
|
|
15
|
+
SPECIAL_COMMENT,
|
|
16
|
+
)
|
|
17
|
+
from snowflake.cli._plugins.nativeapp.exceptions import (
|
|
18
|
+
ApplicationPackageAlreadyExistsError,
|
|
19
|
+
)
|
|
20
|
+
from snowflake.cli._plugins.workspace.action_context import ActionContext
|
|
21
|
+
from snowflake.cli.api.console.abc import AbstractConsole
|
|
22
|
+
from snowflake.cli.api.entities.common import EntityBase, get_sql_executor
|
|
23
|
+
from snowflake.cli.api.entities.utils import (
|
|
24
|
+
ensure_correct_owner,
|
|
25
|
+
generic_sql_error_handler,
|
|
26
|
+
render_script_templates,
|
|
27
|
+
)
|
|
28
|
+
from snowflake.cli.api.exceptions import SnowflakeSQLExecutionError
|
|
29
|
+
from snowflake.cli.api.project.schemas.entities.application_package_entity_model import (
|
|
30
|
+
ApplicationPackageEntityModel,
|
|
31
|
+
)
|
|
32
|
+
from snowflake.cli.api.rendering.jinja import (
|
|
33
|
+
jinja_render_from_str,
|
|
34
|
+
)
|
|
35
|
+
from snowflake.connector import ProgrammingError
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ApplicationPackageEntity(EntityBase[ApplicationPackageEntityModel]):
|
|
39
|
+
"""
|
|
40
|
+
A Native App application package.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def action_bundle(self, ctx: ActionContext):
|
|
44
|
+
model = self._entity_model
|
|
45
|
+
bundle_map = build_bundle(
|
|
46
|
+
ctx.project_root, Path(model.deploy_root), model.artifacts
|
|
47
|
+
)
|
|
48
|
+
bundle_context = BundleContext(
|
|
49
|
+
package_name=model.identifier,
|
|
50
|
+
artifacts=model.artifacts,
|
|
51
|
+
project_root=ctx.project_root,
|
|
52
|
+
bundle_root=Path(model.bundle_root),
|
|
53
|
+
deploy_root=Path(model.deploy_root),
|
|
54
|
+
generated_root=Path(model.generated_root),
|
|
55
|
+
)
|
|
56
|
+
compiler = NativeAppCompiler(bundle_context)
|
|
57
|
+
compiler.compile_artifacts()
|
|
58
|
+
return bundle_map
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def get_existing_app_pkg_info(
|
|
62
|
+
package_name: str,
|
|
63
|
+
package_role: str,
|
|
64
|
+
) -> Optional[dict]:
|
|
65
|
+
"""
|
|
66
|
+
Check for an existing application package by the same name as in project definition, in account.
|
|
67
|
+
It executes a 'show application packages like' query and returns the result as single row, if one exists.
|
|
68
|
+
"""
|
|
69
|
+
sql_executor = get_sql_executor()
|
|
70
|
+
with sql_executor.use_role(package_role):
|
|
71
|
+
return sql_executor.show_specific_object(
|
|
72
|
+
"application packages", package_name, name_col=NAME_COL
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
@staticmethod
|
|
76
|
+
def get_app_pkg_distribution_in_snowflake(
|
|
77
|
+
package_name: str,
|
|
78
|
+
package_role: str,
|
|
79
|
+
) -> str:
|
|
80
|
+
"""
|
|
81
|
+
Returns the 'distribution' attribute of a 'describe application package' SQL query, in lowercase.
|
|
82
|
+
"""
|
|
83
|
+
sql_executor = get_sql_executor()
|
|
84
|
+
with sql_executor.use_role(package_role):
|
|
85
|
+
try:
|
|
86
|
+
desc_cursor = sql_executor.execute_query(
|
|
87
|
+
f"describe application package {package_name}"
|
|
88
|
+
)
|
|
89
|
+
except ProgrammingError as err:
|
|
90
|
+
generic_sql_error_handler(err)
|
|
91
|
+
|
|
92
|
+
if desc_cursor.rowcount is None or desc_cursor.rowcount == 0:
|
|
93
|
+
raise SnowflakeSQLExecutionError()
|
|
94
|
+
else:
|
|
95
|
+
for row in desc_cursor:
|
|
96
|
+
if row[0].lower() == "distribution":
|
|
97
|
+
return row[1].lower()
|
|
98
|
+
raise ProgrammingError(
|
|
99
|
+
msg=dedent(
|
|
100
|
+
f"""\
|
|
101
|
+
Could not find the 'distribution' attribute for application package {package_name} in the output of SQL query:
|
|
102
|
+
'describe application package {package_name}'
|
|
103
|
+
"""
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
@classmethod
|
|
108
|
+
def verify_project_distribution(
|
|
109
|
+
cls,
|
|
110
|
+
console: AbstractConsole,
|
|
111
|
+
package_name: str,
|
|
112
|
+
package_role: str,
|
|
113
|
+
package_distribution: str,
|
|
114
|
+
expected_distribution: Optional[str] = None,
|
|
115
|
+
) -> bool:
|
|
116
|
+
"""
|
|
117
|
+
Returns true if the 'distribution' attribute of an existing application package in snowflake
|
|
118
|
+
is the same as the the attribute specified in project definition file.
|
|
119
|
+
"""
|
|
120
|
+
actual_distribution = (
|
|
121
|
+
expected_distribution
|
|
122
|
+
if expected_distribution
|
|
123
|
+
else cls.get_app_pkg_distribution_in_snowflake(
|
|
124
|
+
package_name=package_name,
|
|
125
|
+
package_role=package_role,
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
project_def_distribution = package_distribution.lower()
|
|
129
|
+
if actual_distribution != project_def_distribution:
|
|
130
|
+
console.warning(
|
|
131
|
+
dedent(
|
|
132
|
+
f"""\
|
|
133
|
+
Application package {package_name} in your Snowflake account has distribution property {actual_distribution},
|
|
134
|
+
which does not match the value specified in project definition file: {project_def_distribution}.
|
|
135
|
+
"""
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
return False
|
|
139
|
+
return True
|
|
140
|
+
|
|
141
|
+
@staticmethod
|
|
142
|
+
@contextmanager
|
|
143
|
+
def use_package_warehouse(
|
|
144
|
+
package_warehouse: Optional[str],
|
|
145
|
+
):
|
|
146
|
+
if package_warehouse:
|
|
147
|
+
with get_sql_executor().use_warehouse(package_warehouse):
|
|
148
|
+
yield
|
|
149
|
+
else:
|
|
150
|
+
raise ClickException(
|
|
151
|
+
dedent(
|
|
152
|
+
f"""\
|
|
153
|
+
Application package warehouse cannot be empty.
|
|
154
|
+
Please provide a value for it in your connection information or your project definition file.
|
|
155
|
+
"""
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
@classmethod
|
|
160
|
+
def apply_package_scripts(
|
|
161
|
+
cls,
|
|
162
|
+
console: AbstractConsole,
|
|
163
|
+
package_scripts: List[str],
|
|
164
|
+
package_warehouse: Optional[str],
|
|
165
|
+
project_root: Path,
|
|
166
|
+
package_role: str,
|
|
167
|
+
package_name: str,
|
|
168
|
+
) -> None:
|
|
169
|
+
"""
|
|
170
|
+
Assuming the application package exists and we are using the correct role,
|
|
171
|
+
applies all package scripts in-order to the application package.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
if package_scripts:
|
|
175
|
+
console.warning(
|
|
176
|
+
"WARNING: native_app.package.scripts is deprecated. Please migrate to using native_app.package.post_deploy."
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
queued_queries = render_script_templates(
|
|
180
|
+
project_root,
|
|
181
|
+
jinja_render_from_str,
|
|
182
|
+
dict(package_name=package_name),
|
|
183
|
+
package_scripts,
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# once we're sure all the templates expanded correctly, execute all of them
|
|
187
|
+
with cls.use_package_warehouse(
|
|
188
|
+
package_warehouse=package_warehouse,
|
|
189
|
+
):
|
|
190
|
+
try:
|
|
191
|
+
for i, queries in enumerate(queued_queries):
|
|
192
|
+
console.step(f"Applying package script: {package_scripts[i]}")
|
|
193
|
+
get_sql_executor().execute_queries(queries)
|
|
194
|
+
except ProgrammingError as err:
|
|
195
|
+
generic_sql_error_handler(
|
|
196
|
+
err, role=package_role, warehouse=package_warehouse
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
@classmethod
|
|
200
|
+
def create_app_package(
|
|
201
|
+
cls,
|
|
202
|
+
console: AbstractConsole,
|
|
203
|
+
package_name: str,
|
|
204
|
+
package_role: str,
|
|
205
|
+
package_distribution: str,
|
|
206
|
+
) -> None:
|
|
207
|
+
"""
|
|
208
|
+
Creates the application package with our up-to-date stage if none exists.
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
# 1. Check for existing existing application package
|
|
212
|
+
show_obj_row = cls.get_existing_app_pkg_info(
|
|
213
|
+
package_name=package_name,
|
|
214
|
+
package_role=package_role,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
if show_obj_row:
|
|
218
|
+
# 1. Check for the right owner role
|
|
219
|
+
ensure_correct_owner(
|
|
220
|
+
row=show_obj_row, role=package_role, obj_name=package_name
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# 2. Check distribution of the existing application package
|
|
224
|
+
actual_distribution = cls.get_app_pkg_distribution_in_snowflake(
|
|
225
|
+
package_name=package_name,
|
|
226
|
+
package_role=package_role,
|
|
227
|
+
)
|
|
228
|
+
if not cls.verify_project_distribution(
|
|
229
|
+
console=console,
|
|
230
|
+
package_name=package_name,
|
|
231
|
+
package_role=package_role,
|
|
232
|
+
package_distribution=package_distribution,
|
|
233
|
+
expected_distribution=actual_distribution,
|
|
234
|
+
):
|
|
235
|
+
console.warning(
|
|
236
|
+
f"Continuing to execute `snow app run` on application package {package_name} with distribution '{actual_distribution}'."
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
# 3. If actual_distribution is external, skip comment check
|
|
240
|
+
if actual_distribution == INTERNAL_DISTRIBUTION:
|
|
241
|
+
row_comment = show_obj_row[COMMENT_COL]
|
|
242
|
+
|
|
243
|
+
if row_comment not in ALLOWED_SPECIAL_COMMENTS:
|
|
244
|
+
raise ApplicationPackageAlreadyExistsError(package_name)
|
|
245
|
+
|
|
246
|
+
return
|
|
247
|
+
|
|
248
|
+
# If no application package pre-exists, create an application package, with the specified distribution in the project definition file.
|
|
249
|
+
sql_executor = get_sql_executor()
|
|
250
|
+
with sql_executor.use_role(package_role):
|
|
251
|
+
console.step(f"Creating new application package {package_name} in account.")
|
|
252
|
+
sql_executor.execute_query(
|
|
253
|
+
dedent(
|
|
254
|
+
f"""\
|
|
255
|
+
create application package {package_name}
|
|
256
|
+
comment = {SPECIAL_COMMENT}
|
|
257
|
+
distribution = {package_distribution}
|
|
258
|
+
"""
|
|
259
|
+
)
|
|
260
|
+
)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import Generic, Type, TypeVar, get_args
|
|
3
|
+
|
|
4
|
+
from snowflake.cli._plugins.workspace.action_context import ActionContext
|
|
5
|
+
from snowflake.cli.api.sql_execution import SqlExecutor
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class EntityActions(str, Enum):
|
|
9
|
+
BUNDLE = "action_bundle"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
T = TypeVar("T")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class EntityBase(Generic[T]):
|
|
16
|
+
"""
|
|
17
|
+
Base class for the fully-featured entity classes.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, entity_model: T):
|
|
21
|
+
self._entity_model = entity_model
|
|
22
|
+
|
|
23
|
+
@classmethod
|
|
24
|
+
def get_entity_model_type(cls) -> Type[T]:
|
|
25
|
+
"""
|
|
26
|
+
Returns the generic model class specified in each entity class.
|
|
27
|
+
|
|
28
|
+
For example, calling ApplicationEntity.get_entity_model_type() will return the ApplicationEntityModel class.
|
|
29
|
+
"""
|
|
30
|
+
return get_args(cls.__orig_bases__[0])[0] # type: ignore[attr-defined]
|
|
31
|
+
|
|
32
|
+
def supports(self, action: EntityActions) -> bool:
|
|
33
|
+
"""
|
|
34
|
+
Checks whether this entity supports the given action. An entity is considered to support an action if it implements a method with the action name.
|
|
35
|
+
"""
|
|
36
|
+
return callable(getattr(self, action, None))
|
|
37
|
+
|
|
38
|
+
def perform(self, action: EntityActions, action_ctx: ActionContext):
|
|
39
|
+
"""
|
|
40
|
+
Performs the requested action.
|
|
41
|
+
"""
|
|
42
|
+
return getattr(self, action)(action_ctx)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_sql_executor() -> SqlExecutor:
|
|
46
|
+
"""Returns an SQL Executor that uses the connection from the current CLI context"""
|
|
47
|
+
return SqlExecutor()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from typing import Generic, TypeVar
|
|
2
|
+
|
|
3
|
+
from snowflake.cli.api.entities.common import EntityBase
|
|
4
|
+
from snowflake.cli.api.project.schemas.entities.snowpark_entity import (
|
|
5
|
+
FunctionEntityModel,
|
|
6
|
+
ProcedureEntityModel,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
T = TypeVar("T")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SnowparkEntity(EntityBase[Generic[T]]):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class FunctionEntity(SnowparkEntity[FunctionEntityModel]):
|
|
17
|
+
"""
|
|
18
|
+
A single UDF
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ProcedureEntity(SnowparkEntity[ProcedureEntityModel]):
|
|
25
|
+
"""
|
|
26
|
+
A stored procedure
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
pass
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from snowflake.cli.api.entities.common import EntityBase
|
|
2
|
+
from snowflake.cli.api.project.schemas.entities.streamlit_entity_model import (
|
|
3
|
+
StreamlitEntityModel,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StreamlitEntity(EntityBase[StreamlitEntityModel]):
|
|
8
|
+
"""
|
|
9
|
+
A Streamlit app.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
pass
|