snowflake-cli-labs 2.8.0rc1__py3-none-any.whl → 2.8.2__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.
- README.md +21 -0
- {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-2.8.2.dist-info}/METADATA +7 -95
- snowflake_cli_labs-2.8.2.dist-info/RECORD +5 -0
- snowflake/cli/__about__.py +0 -17
- snowflake/cli/__init__.py +0 -13
- snowflake/cli/api/__init__.py +0 -48
- snowflake/cli/api/cli_global_context.py +0 -390
- snowflake/cli/api/commands/__init__.py +0 -13
- snowflake/cli/api/commands/alias.py +0 -23
- snowflake/cli/api/commands/decorators.py +0 -354
- snowflake/cli/api/commands/execution_metadata.py +0 -40
- snowflake/cli/api/commands/experimental_behaviour.py +0 -19
- snowflake/cli/api/commands/flags.py +0 -640
- snowflake/cli/api/commands/project_initialisation.py +0 -65
- snowflake/cli/api/commands/snow_typer.py +0 -237
- snowflake/cli/api/commands/typer_pre_execute.py +0 -26
- snowflake/cli/api/config.py +0 -348
- snowflake/cli/api/console/__init__.py +0 -17
- snowflake/cli/api/console/abc.py +0 -89
- snowflake/cli/api/console/console.py +0 -134
- snowflake/cli/api/console/enum.py +0 -17
- snowflake/cli/api/constants.py +0 -79
- snowflake/cli/api/errno.py +0 -27
- snowflake/cli/api/exceptions.py +0 -164
- snowflake/cli/api/feature_flags.py +0 -55
- snowflake/cli/api/identifiers.py +0 -154
- snowflake/cli/api/output/__init__.py +0 -13
- snowflake/cli/api/output/formats.py +0 -20
- snowflake/cli/api/output/types.py +0 -118
- snowflake/cli/api/plugins/__init__.py +0 -13
- snowflake/cli/api/plugins/command/__init__.py +0 -72
- snowflake/cli/api/plugins/command/plugin_hook_specs.py +0 -21
- snowflake/cli/api/plugins/plugin_config.py +0 -32
- snowflake/cli/api/project/__init__.py +0 -13
- snowflake/cli/api/project/definition.py +0 -84
- snowflake/cli/api/project/definition_manager.py +0 -134
- snowflake/cli/api/project/errors.py +0 -56
- snowflake/cli/api/project/project_verification.py +0 -23
- snowflake/cli/api/project/schemas/__init__.py +0 -13
- 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/api/project/schemas/entities/common.py +0 -78
- snowflake/cli/api/project/schemas/entities/entities.py +0 -30
- snowflake/cli/api/project/schemas/identifier_model.py +0 -49
- snowflake/cli/api/project/schemas/native_app/__init__.py +0 -13
- snowflake/cli/api/project/schemas/native_app/application.py +0 -62
- snowflake/cli/api/project/schemas/native_app/native_app.py +0 -93
- snowflake/cli/api/project/schemas/native_app/package.py +0 -78
- snowflake/cli/api/project/schemas/native_app/path_mapping.py +0 -65
- snowflake/cli/api/project/schemas/project_definition.py +0 -199
- snowflake/cli/api/project/schemas/snowpark/__init__.py +0 -13
- snowflake/cli/api/project/schemas/snowpark/argument.py +0 -28
- snowflake/cli/api/project/schemas/snowpark/callable.py +0 -69
- snowflake/cli/api/project/schemas/snowpark/snowpark.py +0 -36
- snowflake/cli/api/project/schemas/streamlit/__init__.py +0 -13
- snowflake/cli/api/project/schemas/streamlit/streamlit.py +0 -46
- snowflake/cli/api/project/schemas/template.py +0 -77
- snowflake/cli/api/project/schemas/updatable_model.py +0 -194
- snowflake/cli/api/project/util.py +0 -261
- snowflake/cli/api/rendering/__init__.py +0 -13
- snowflake/cli/api/rendering/jinja.py +0 -112
- snowflake/cli/api/rendering/project_definition_templates.py +0 -39
- snowflake/cli/api/rendering/project_templates.py +0 -98
- snowflake/cli/api/rendering/sql_templates.py +0 -60
- snowflake/cli/api/rest_api.py +0 -172
- snowflake/cli/api/sanitizers.py +0 -43
- snowflake/cli/api/secure_path.py +0 -362
- snowflake/cli/api/secure_utils.py +0 -29
- snowflake/cli/api/sql_execution.py +0 -260
- snowflake/cli/api/utils/__init__.py +0 -13
- snowflake/cli/api/utils/cursor.py +0 -34
- snowflake/cli/api/utils/definition_rendering.py +0 -383
- snowflake/cli/api/utils/dict_utils.py +0 -73
- snowflake/cli/api/utils/error_handling.py +0 -23
- snowflake/cli/api/utils/graph.py +0 -97
- snowflake/cli/api/utils/models.py +0 -63
- snowflake/cli/api/utils/naming_utils.py +0 -13
- snowflake/cli/api/utils/path_utils.py +0 -36
- snowflake/cli/api/utils/templating_functions.py +0 -144
- snowflake/cli/api/utils/types.py +0 -35
- snowflake/cli/app/__init__.py +0 -22
- snowflake/cli/app/__main__.py +0 -31
- snowflake/cli/app/api_impl/__init__.py +0 -13
- snowflake/cli/app/api_impl/plugin/__init__.py +0 -13
- snowflake/cli/app/api_impl/plugin/plugin_config_provider_impl.py +0 -66
- snowflake/cli/app/build_and_push.sh +0 -8
- snowflake/cli/app/cli_app.py +0 -243
- snowflake/cli/app/commands_registration/__init__.py +0 -33
- snowflake/cli/app/commands_registration/builtin_plugins.py +0 -54
- snowflake/cli/app/commands_registration/command_plugins_loader.py +0 -169
- snowflake/cli/app/commands_registration/commands_registration_with_callbacks.py +0 -105
- snowflake/cli/app/commands_registration/exception_logging.py +0 -26
- snowflake/cli/app/commands_registration/threadsafe.py +0 -48
- snowflake/cli/app/commands_registration/typer_registration.py +0 -153
- snowflake/cli/app/constants.py +0 -19
- snowflake/cli/app/dev/__init__.py +0 -13
- snowflake/cli/app/dev/commands_structure.py +0 -48
- snowflake/cli/app/dev/docs/__init__.py +0 -13
- snowflake/cli/app/dev/docs/commands_docs_generator.py +0 -100
- snowflake/cli/app/dev/docs/generator.py +0 -35
- snowflake/cli/app/dev/docs/project_definition_docs_generator.py +0 -58
- snowflake/cli/app/dev/docs/project_definition_generate_json_schema.py +0 -227
- snowflake/cli/app/dev/docs/template_utils.py +0 -23
- snowflake/cli/app/dev/docs/templates/definition_description.rst.jinja2 +0 -38
- snowflake/cli/app/dev/docs/templates/overview.rst.jinja2 +0 -9
- snowflake/cli/app/dev/docs/templates/usage.rst.jinja2 +0 -57
- snowflake/cli/app/dev/pycharm_remote_debug.py +0 -46
- snowflake/cli/app/loggers.py +0 -199
- snowflake/cli/app/main_typer.py +0 -62
- snowflake/cli/app/printing.py +0 -181
- snowflake/cli/app/snow_connector.py +0 -243
- snowflake/cli/app/telemetry.py +0 -189
- snowflake/cli/plugins/__init__.py +0 -13
- snowflake/cli/plugins/connection/__init__.py +0 -13
- snowflake/cli/plugins/connection/commands.py +0 -330
- snowflake/cli/plugins/connection/plugin_spec.py +0 -30
- snowflake/cli/plugins/connection/util.py +0 -179
- snowflake/cli/plugins/cortex/__init__.py +0 -13
- snowflake/cli/plugins/cortex/commands.py +0 -327
- snowflake/cli/plugins/cortex/constants.py +0 -17
- snowflake/cli/plugins/cortex/manager.py +0 -189
- snowflake/cli/plugins/cortex/plugin_spec.py +0 -30
- snowflake/cli/plugins/cortex/types.py +0 -22
- snowflake/cli/plugins/git/__init__.py +0 -13
- snowflake/cli/plugins/git/commands.py +0 -305
- snowflake/cli/plugins/git/manager.py +0 -96
- snowflake/cli/plugins/git/plugin_spec.py +0 -30
- snowflake/cli/plugins/init/__init__.py +0 -13
- snowflake/cli/plugins/init/commands.py +0 -244
- snowflake/cli/plugins/init/plugin_spec.py +0 -30
- snowflake/cli/plugins/nativeapp/__init__.py +0 -13
- snowflake/cli/plugins/nativeapp/artifacts.py +0 -742
- snowflake/cli/plugins/nativeapp/codegen/__init__.py +0 -13
- snowflake/cli/plugins/nativeapp/codegen/artifact_processor.py +0 -91
- snowflake/cli/plugins/nativeapp/codegen/compiler.py +0 -130
- snowflake/cli/plugins/nativeapp/codegen/sandbox.py +0 -306
- snowflake/cli/plugins/nativeapp/codegen/setup/native_app_setup_processor.py +0 -172
- snowflake/cli/plugins/nativeapp/codegen/setup/setup_driver.py.source +0 -56
- snowflake/cli/plugins/nativeapp/codegen/snowpark/callback_source.py.jinja +0 -181
- snowflake/cli/plugins/nativeapp/codegen/snowpark/extension_function_utils.py +0 -217
- snowflake/cli/plugins/nativeapp/codegen/snowpark/models.py +0 -61
- snowflake/cli/plugins/nativeapp/codegen/snowpark/python_processor.py +0 -528
- snowflake/cli/plugins/nativeapp/commands.py +0 -439
- snowflake/cli/plugins/nativeapp/common_flags.py +0 -44
- snowflake/cli/plugins/nativeapp/constants.py +0 -27
- snowflake/cli/plugins/nativeapp/exceptions.py +0 -122
- snowflake/cli/plugins/nativeapp/feature_flags.py +0 -24
- snowflake/cli/plugins/nativeapp/init.py +0 -345
- snowflake/cli/plugins/nativeapp/manager.py +0 -823
- snowflake/cli/plugins/nativeapp/plugin_spec.py +0 -30
- snowflake/cli/plugins/nativeapp/policy.py +0 -50
- snowflake/cli/plugins/nativeapp/project_model.py +0 -195
- snowflake/cli/plugins/nativeapp/run_processor.py +0 -389
- snowflake/cli/plugins/nativeapp/teardown_processor.py +0 -301
- snowflake/cli/plugins/nativeapp/utils.py +0 -98
- snowflake/cli/plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +0 -135
- snowflake/cli/plugins/nativeapp/version/__init__.py +0 -13
- snowflake/cli/plugins/nativeapp/version/commands.py +0 -170
- snowflake/cli/plugins/nativeapp/version/version_processor.py +0 -362
- snowflake/cli/plugins/notebook/__init__.py +0 -13
- snowflake/cli/plugins/notebook/commands.py +0 -84
- snowflake/cli/plugins/notebook/exceptions.py +0 -20
- snowflake/cli/plugins/notebook/manager.py +0 -71
- snowflake/cli/plugins/notebook/plugin_spec.py +0 -30
- snowflake/cli/plugins/notebook/types.py +0 -16
- snowflake/cli/plugins/object/__init__.py +0 -13
- snowflake/cli/plugins/object/command_aliases.py +0 -94
- snowflake/cli/plugins/object/commands.py +0 -174
- snowflake/cli/plugins/object/common.py +0 -85
- snowflake/cli/plugins/object/manager.py +0 -96
- snowflake/cli/plugins/object/plugin_spec.py +0 -30
- 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/__init__.py +0 -13
- 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/models.py +0 -156
- snowflake/cli/plugins/snowpark/package/__init__.py +0 -13
- snowflake/cli/plugins/snowpark/package/anaconda_packages.py +0 -233
- snowflake/cli/plugins/snowpark/package/commands.py +0 -256
- snowflake/cli/plugins/snowpark/package/manager.py +0 -43
- snowflake/cli/plugins/snowpark/package/utils.py +0 -26
- snowflake/cli/plugins/snowpark/package_utils.py +0 -354
- snowflake/cli/plugins/snowpark/plugin_spec.py +0 -30
- snowflake/cli/plugins/snowpark/snowpark_package_paths.py +0 -65
- snowflake/cli/plugins/snowpark/snowpark_shared.py +0 -95
- snowflake/cli/plugins/snowpark/zipper.py +0 -81
- snowflake/cli/plugins/spcs/__init__.py +0 -35
- snowflake/cli/plugins/spcs/common.py +0 -99
- snowflake/cli/plugins/spcs/compute_pool/__init__.py +0 -13
- snowflake/cli/plugins/spcs/compute_pool/commands.py +0 -240
- snowflake/cli/plugins/spcs/compute_pool/manager.py +0 -121
- snowflake/cli/plugins/spcs/image_registry/__init__.py +0 -13
- snowflake/cli/plugins/spcs/image_registry/commands.py +0 -65
- snowflake/cli/plugins/spcs/image_registry/manager.py +0 -105
- snowflake/cli/plugins/spcs/image_repository/__init__.py +0 -13
- snowflake/cli/plugins/spcs/image_repository/commands.py +0 -196
- snowflake/cli/plugins/spcs/image_repository/manager.py +0 -84
- snowflake/cli/plugins/spcs/jobs/__init__.py +0 -13
- snowflake/cli/plugins/spcs/jobs/commands.py +0 -78
- snowflake/cli/plugins/spcs/jobs/manager.py +0 -53
- snowflake/cli/plugins/spcs/plugin_spec.py +0 -30
- snowflake/cli/plugins/spcs/services/__init__.py +0 -13
- snowflake/cli/plugins/spcs/services/commands.py +0 -311
- snowflake/cli/plugins/spcs/services/manager.py +0 -170
- snowflake/cli/plugins/sql/__init__.py +0 -13
- snowflake/cli/plugins/sql/commands.py +0 -83
- snowflake/cli/plugins/sql/manager.py +0 -92
- snowflake/cli/plugins/sql/plugin_spec.py +0 -30
- snowflake/cli/plugins/sql/snowsql_templating.py +0 -28
- snowflake/cli/plugins/stage/__init__.py +0 -13
- snowflake/cli/plugins/stage/commands.py +0 -261
- snowflake/cli/plugins/stage/diff.py +0 -326
- snowflake/cli/plugins/stage/manager.py +0 -544
- snowflake/cli/plugins/stage/md5.py +0 -160
- snowflake/cli/plugins/stage/plugin_spec.py +0 -30
- snowflake/cli/plugins/streamlit/__init__.py +0 -13
- snowflake/cli/plugins/streamlit/commands.py +0 -186
- snowflake/cli/plugins/streamlit/manager.py +0 -222
- 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/__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_labs-2.8.0rc1.dist-info → snowflake_cli_labs-2.8.2.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-2.8.0rc1.dist-info → snowflake_cli_labs-2.8.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,172 +0,0 @@
|
|
|
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 json
|
|
18
|
-
import os.path
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
from typing import List, Optional
|
|
21
|
-
|
|
22
|
-
from click import ClickException
|
|
23
|
-
from snowflake.cli.api.console import cli_console as cc
|
|
24
|
-
from snowflake.cli.api.project.schemas.native_app.path_mapping import (
|
|
25
|
-
PathMapping,
|
|
26
|
-
ProcessorMapping,
|
|
27
|
-
)
|
|
28
|
-
from snowflake.cli.plugins.nativeapp.artifacts import BundleMap, find_setup_script_file
|
|
29
|
-
from snowflake.cli.plugins.nativeapp.codegen.artifact_processor import (
|
|
30
|
-
ArtifactProcessor,
|
|
31
|
-
is_python_file_artifact,
|
|
32
|
-
)
|
|
33
|
-
from snowflake.cli.plugins.nativeapp.codegen.sandbox import (
|
|
34
|
-
ExecutionEnvironmentType,
|
|
35
|
-
SandboxEnvBuilder,
|
|
36
|
-
execute_script_in_sandbox,
|
|
37
|
-
)
|
|
38
|
-
from snowflake.cli.plugins.nativeapp.project_model import NativeAppProjectModel
|
|
39
|
-
from snowflake.cli.plugins.stage.diff import to_stage_path
|
|
40
|
-
|
|
41
|
-
DEFAULT_TIMEOUT = 30
|
|
42
|
-
DRIVER_PATH = Path(__file__).parent / "setup_driver.py.source"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class NativeAppSetupProcessor(ArtifactProcessor):
|
|
46
|
-
def __init__(
|
|
47
|
-
self,
|
|
48
|
-
na_project: NativeAppProjectModel,
|
|
49
|
-
):
|
|
50
|
-
super().__init__(na_project=na_project)
|
|
51
|
-
|
|
52
|
-
def process(
|
|
53
|
-
self,
|
|
54
|
-
artifact_to_process: PathMapping,
|
|
55
|
-
processor_mapping: Optional[ProcessorMapping],
|
|
56
|
-
**kwargs,
|
|
57
|
-
) -> None:
|
|
58
|
-
"""
|
|
59
|
-
Processes a Python setup script and generates the corresponding SQL commands.
|
|
60
|
-
"""
|
|
61
|
-
bundle_map = BundleMap(
|
|
62
|
-
project_root=self._na_project.project_root,
|
|
63
|
-
deploy_root=self._na_project.deploy_root,
|
|
64
|
-
)
|
|
65
|
-
bundle_map.add(artifact_to_process)
|
|
66
|
-
|
|
67
|
-
self._create_or_update_sandbox()
|
|
68
|
-
|
|
69
|
-
cc.phase("Processing Python setup files")
|
|
70
|
-
|
|
71
|
-
files_to_process = []
|
|
72
|
-
for src_file, dest_file in bundle_map.all_mappings(
|
|
73
|
-
absolute=True, expand_directories=True, predicate=is_python_file_artifact
|
|
74
|
-
):
|
|
75
|
-
cc.message(
|
|
76
|
-
f"Found Python setup file: {src_file.relative_to(self._na_project.project_root)}"
|
|
77
|
-
)
|
|
78
|
-
files_to_process.append(src_file)
|
|
79
|
-
|
|
80
|
-
sql_files_mapping = self._execute_in_sandbox(files_to_process)
|
|
81
|
-
self._generate_setup_sql(sql_files_mapping)
|
|
82
|
-
|
|
83
|
-
def _execute_in_sandbox(self, py_files: List[Path]) -> dict:
|
|
84
|
-
file_count = len(py_files)
|
|
85
|
-
cc.step(f"Processing {file_count} setup file{'s' if file_count > 1 else ''}")
|
|
86
|
-
|
|
87
|
-
env_vars = {
|
|
88
|
-
"_SNOWFLAKE_CLI_PROJECT_PATH": str(self._na_project.project_root),
|
|
89
|
-
"_SNOWFLAKE_CLI_SETUP_FILES": os.pathsep.join(map(str, py_files)),
|
|
90
|
-
"_SNOWFLAKE_CLI_APP_NAME": str(self._na_project.package_name),
|
|
91
|
-
"_SNOWFLAKE_CLI_SQL_DEST_DIR": str(self.generated_root),
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
try:
|
|
95
|
-
result = execute_script_in_sandbox(
|
|
96
|
-
script_source=DRIVER_PATH.read_text(),
|
|
97
|
-
env_type=ExecutionEnvironmentType.VENV,
|
|
98
|
-
cwd=self._na_project.bundle_root,
|
|
99
|
-
timeout=DEFAULT_TIMEOUT,
|
|
100
|
-
path=self.sandbox_root,
|
|
101
|
-
env_vars=env_vars,
|
|
102
|
-
)
|
|
103
|
-
except Exception as e:
|
|
104
|
-
raise ClickException(
|
|
105
|
-
f"Exception while executing python setup script logic: {e}"
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
if result.returncode == 0:
|
|
109
|
-
sql_file_mappings = json.loads(result.stdout)
|
|
110
|
-
return sql_file_mappings
|
|
111
|
-
else:
|
|
112
|
-
raise ClickException(
|
|
113
|
-
f"Failed to execute python setup script logic: {result.stderr}"
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
def _generate_setup_sql(self, sql_file_mappings: dict) -> None:
|
|
117
|
-
if not sql_file_mappings:
|
|
118
|
-
# Nothing to generate
|
|
119
|
-
return
|
|
120
|
-
|
|
121
|
-
generated_root = self.generated_root
|
|
122
|
-
generated_root.mkdir(exist_ok=True, parents=True)
|
|
123
|
-
|
|
124
|
-
cc.step("Patching setup script")
|
|
125
|
-
setup_file_path = find_setup_script_file(
|
|
126
|
-
deploy_root=self._na_project.deploy_root
|
|
127
|
-
)
|
|
128
|
-
with self.edit_file(setup_file_path) as f:
|
|
129
|
-
new_contents = [f.contents]
|
|
130
|
-
|
|
131
|
-
if sql_file_mappings["schemas"]:
|
|
132
|
-
schemas_file = generated_root / sql_file_mappings["schemas"]
|
|
133
|
-
new_contents.insert(
|
|
134
|
-
0,
|
|
135
|
-
f"EXECUTE IMMEDIATE FROM '/{to_stage_path(schemas_file.relative_to(self._na_project.deploy_root))}';",
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
if sql_file_mappings["compute_pools"]:
|
|
139
|
-
compute_pools_file = generated_root / sql_file_mappings["compute_pools"]
|
|
140
|
-
new_contents.append(
|
|
141
|
-
f"EXECUTE IMMEDIATE FROM '/{to_stage_path(compute_pools_file.relative_to(self._na_project.deploy_root))}';"
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
if sql_file_mappings["services"]:
|
|
145
|
-
services_file = generated_root / sql_file_mappings["services"]
|
|
146
|
-
new_contents.append(
|
|
147
|
-
f"EXECUTE IMMEDIATE FROM '/{to_stage_path(services_file.relative_to(self._na_project.deploy_root))}';"
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
f.edited_contents = "\n".join(new_contents)
|
|
151
|
-
|
|
152
|
-
@property
|
|
153
|
-
def sandbox_root(self):
|
|
154
|
-
return self._na_project.bundle_root / "setup_py_venv"
|
|
155
|
-
|
|
156
|
-
@property
|
|
157
|
-
def generated_root(self):
|
|
158
|
-
return self._na_project.generated_root / "setup_py"
|
|
159
|
-
|
|
160
|
-
def _create_or_update_sandbox(self):
|
|
161
|
-
sandbox_root = self.sandbox_root
|
|
162
|
-
env_builder = SandboxEnvBuilder(sandbox_root, with_pip=True)
|
|
163
|
-
if sandbox_root.exists():
|
|
164
|
-
cc.step("Virtual environment found")
|
|
165
|
-
else:
|
|
166
|
-
cc.step(
|
|
167
|
-
f"Creating virtual environment in {sandbox_root.relative_to(self._na_project.project_root)}"
|
|
168
|
-
)
|
|
169
|
-
env_builder.ensure_created()
|
|
170
|
-
|
|
171
|
-
# Temporarily fetch the library from a location specified via env vars
|
|
172
|
-
env_builder.pip_install(os.environ["SNOWFLAKE_APP_PYTHON_LOC"])
|
|
@@ -1,56 +0,0 @@
|
|
|
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
|
-
import contextlib
|
|
16
|
-
import os
|
|
17
|
-
import sys
|
|
18
|
-
from pathlib import Path
|
|
19
|
-
|
|
20
|
-
import snowflake.app.context as ctx
|
|
21
|
-
from snowflake.app.sql import SQLGenerator
|
|
22
|
-
|
|
23
|
-
ctx._project_path = os.environ["_SNOWFLAKE_CLI_PROJECT_PATH"]
|
|
24
|
-
ctx._current_app_name = os.environ["_SNOWFLAKE_CLI_APP_NAME"]
|
|
25
|
-
__snowflake_internal_py_files = os.environ["_SNOWFLAKE_CLI_SETUP_FILES"].split(
|
|
26
|
-
os.pathsep
|
|
27
|
-
)
|
|
28
|
-
__snowflake_internal_sql_dest_dir = os.environ["_SNOWFLAKE_CLI_SQL_DEST_DIR"]
|
|
29
|
-
|
|
30
|
-
try:
|
|
31
|
-
import importlib
|
|
32
|
-
|
|
33
|
-
with contextlib.redirect_stdout(None):
|
|
34
|
-
with contextlib.redirect_stderr(None):
|
|
35
|
-
for __snowflake_internal_py_file in __snowflake_internal_py_files:
|
|
36
|
-
__snowflake_internal_spec = importlib.util.spec_from_file_location(
|
|
37
|
-
"<string>", __snowflake_internal_py_file
|
|
38
|
-
)
|
|
39
|
-
__snowflake_internal_module = importlib.util.module_from_spec(
|
|
40
|
-
__snowflake_internal_spec
|
|
41
|
-
)
|
|
42
|
-
__snowflake_internal_spec.loader.exec_module(
|
|
43
|
-
__snowflake_internal_module
|
|
44
|
-
)
|
|
45
|
-
except Exception as exc: # Catch any error
|
|
46
|
-
print("An exception occurred while executing file: ", exc, file=sys.stderr)
|
|
47
|
-
sys.exit(1)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
import json
|
|
51
|
-
|
|
52
|
-
output_dir = Path(__snowflake_internal_sql_dest_dir)
|
|
53
|
-
output_dir.mkdir(exist_ok=True, parents=True)
|
|
54
|
-
path_mappings = SQLGenerator(dest_dir=output_dir).generate()
|
|
55
|
-
|
|
56
|
-
print(json.dumps(path_mappings, default=str))
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import contextlib
|
|
2
|
-
import functools
|
|
3
|
-
import inspect
|
|
4
|
-
import sys
|
|
5
|
-
from typing import Callable, Tuple
|
|
6
|
-
|
|
7
|
-
try:
|
|
8
|
-
import snowflake.snowpark
|
|
9
|
-
except ModuleNotFoundError as exc:
|
|
10
|
-
print(
|
|
11
|
-
"An exception occurred while importing snowflake-snowpark-python package: ",
|
|
12
|
-
exc,
|
|
13
|
-
file=sys.stderr,
|
|
14
|
-
)
|
|
15
|
-
sys.exit(1)
|
|
16
|
-
|
|
17
|
-
__snowflake_internal_found_correct_version = hasattr(
|
|
18
|
-
snowflake.snowpark.context, "_is_execution_environment_sandboxed_for_client"
|
|
19
|
-
) and hasattr(snowflake.snowpark.context, "_should_continue_registration")
|
|
20
|
-
|
|
21
|
-
if not __snowflake_internal_found_correct_version:
|
|
22
|
-
print(
|
|
23
|
-
"Did not find the minimum required version for snowflake-snowpark-python package. Please upgrade to v1.15.0 or higher.",
|
|
24
|
-
file=sys.stderr,
|
|
25
|
-
)
|
|
26
|
-
sys.exit(1)
|
|
27
|
-
|
|
28
|
-
__snowflake_global_collected_extension_fn_json = []
|
|
29
|
-
|
|
30
|
-
def __snowflake_internal_create_extension_fn_registration_callback():
|
|
31
|
-
def __snowflake_internal_try_extract_lineno(extension_fn):
|
|
32
|
-
try:
|
|
33
|
-
return inspect.getsourcelines(extension_fn)[1]
|
|
34
|
-
except Exception:
|
|
35
|
-
return None
|
|
36
|
-
|
|
37
|
-
def __snowflake_internal_extract_extension_fn_name(extension_fn):
|
|
38
|
-
try:
|
|
39
|
-
import snowflake.snowpark._internal.utils as snowpark_utils
|
|
40
|
-
|
|
41
|
-
if hasattr(snowpark_utils, 'TEMP_OBJECT_NAME_PREFIX'):
|
|
42
|
-
if extension_fn.object_name.startswith(snowpark_utils.TEMP_OBJECT_NAME_PREFIX):
|
|
43
|
-
# The object name is a generated one, don't use it
|
|
44
|
-
return None
|
|
45
|
-
|
|
46
|
-
except Exception:
|
|
47
|
-
# ignore any exception and fall back to using the object name reported from Snowpark
|
|
48
|
-
pass
|
|
49
|
-
|
|
50
|
-
return extension_fn.object_name
|
|
51
|
-
|
|
52
|
-
def __snowflake_internal_create_package_list(extension_fn):
|
|
53
|
-
if not extension_fn.all_packages.strip():
|
|
54
|
-
return []
|
|
55
|
-
return [pkg_spec.strip() for pkg_spec in extension_fn.all_packages.split(",")]
|
|
56
|
-
|
|
57
|
-
def __snowflake_internal_make_extension_fn_signature(extension_fn):
|
|
58
|
-
# Try to fetch the original argument names from the extension function
|
|
59
|
-
try:
|
|
60
|
-
args_spec = inspect.getfullargspec(extension_fn.func)
|
|
61
|
-
original_arg_names = args_spec[0]
|
|
62
|
-
start_index = len(original_arg_names) - len(extension_fn.input_sql_types)
|
|
63
|
-
signature = []
|
|
64
|
-
defaults_start_index = len(original_arg_names) - len(args_spec.defaults or [])
|
|
65
|
-
for i in range(len(extension_fn.input_sql_types)):
|
|
66
|
-
arg = {
|
|
67
|
-
'name': original_arg_names[start_index + i],
|
|
68
|
-
'type': extension_fn.input_sql_types[i]
|
|
69
|
-
}
|
|
70
|
-
if i >= defaults_start_index:
|
|
71
|
-
arg['default'] = args_spec.defaults[defaults_start_index + i]
|
|
72
|
-
signature.append(arg)
|
|
73
|
-
|
|
74
|
-
return signature
|
|
75
|
-
except Exception as e:
|
|
76
|
-
msg = str(e)
|
|
77
|
-
pass # ignore, we'll use the fallback strategy
|
|
78
|
-
|
|
79
|
-
# Failed to extract the original arguments through reflection, fall back to alternative approach
|
|
80
|
-
return [
|
|
81
|
-
{"name": input_arg.name, "type": input_type}
|
|
82
|
-
for (input_arg, input_type) in zip(extension_fn.input_args, extension_fn.input_sql_types)
|
|
83
|
-
]
|
|
84
|
-
|
|
85
|
-
def __snowflake_internal_to_extension_fn_type(object_type):
|
|
86
|
-
if object_type.name == "AGGREGATE_FUNCTION":
|
|
87
|
-
return "aggregate function"
|
|
88
|
-
if object_type.name == "TABLE_FUNCTION":
|
|
89
|
-
return "table function"
|
|
90
|
-
return object_type.name.lower()
|
|
91
|
-
|
|
92
|
-
def __snowflake_internal_imports_union_to_str_type(raw_imports):
|
|
93
|
-
final_imports = []
|
|
94
|
-
if raw_imports:
|
|
95
|
-
for raw_import in raw_imports:
|
|
96
|
-
if isinstance(raw_import, str):
|
|
97
|
-
final_imports.append(raw_import)
|
|
98
|
-
else:
|
|
99
|
-
final_imports.append(raw_import[0])
|
|
100
|
-
return final_imports
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
def __snowflake_internal_extension_fn_to_json(extension_fn):
|
|
104
|
-
if not (isinstance(extension_fn.func, Callable) or isinstance(extension_fn.func, Tuple)):
|
|
105
|
-
return
|
|
106
|
-
|
|
107
|
-
if extension_fn.anonymous:
|
|
108
|
-
# unsupported, native application extension functions need to be explicitly named
|
|
109
|
-
return
|
|
110
|
-
|
|
111
|
-
# Collect basic properties of the extension function
|
|
112
|
-
extension_fn_json = {
|
|
113
|
-
"type": __snowflake_internal_to_extension_fn_type(extension_fn.object_type),
|
|
114
|
-
"lineno": __snowflake_internal_try_extract_lineno(extension_fn.func),
|
|
115
|
-
"name": __snowflake_internal_extract_extension_fn_name(extension_fn),
|
|
116
|
-
"handler": extension_fn.func.__name__,
|
|
117
|
-
"imports": __snowflake_internal_imports_union_to_str_type(extension_fn.raw_imports),
|
|
118
|
-
"packages": __snowflake_internal_create_package_list(extension_fn),
|
|
119
|
-
"runtime": extension_fn.runtime_version,
|
|
120
|
-
"returns": extension_fn.return_sql.upper().replace("RETURNS ", "").strip(),
|
|
121
|
-
"signature": __snowflake_internal_make_extension_fn_signature(extension_fn),
|
|
122
|
-
"external_access_integrations": extension_fn.external_access_integrations or [],
|
|
123
|
-
"secrets": extension_fn.secrets or {},
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if extension_fn.object_type.name == "PROCEDURE" and extension_fn.execute_as is not None:
|
|
127
|
-
extension_fn_json['execute_as_caller'] = (extension_fn.execute_as == 'caller')
|
|
128
|
-
|
|
129
|
-
if extension_fn.native_app_params is not None:
|
|
130
|
-
schema = extension_fn.native_app_params.get("schema")
|
|
131
|
-
if schema is not None:
|
|
132
|
-
extension_fn_json["schema"] = schema
|
|
133
|
-
app_roles = extension_fn.native_app_params.get("application_roles")
|
|
134
|
-
if app_roles is not None:
|
|
135
|
-
extension_fn_json["application_roles"] = app_roles
|
|
136
|
-
|
|
137
|
-
return extension_fn_json
|
|
138
|
-
|
|
139
|
-
def __snowflake_internal_collect_extension_fn(
|
|
140
|
-
collected_extension_fn_json_list, extension_function_properties
|
|
141
|
-
):
|
|
142
|
-
extension_fn_json = __snowflake_internal_extension_fn_to_json(extension_function_properties)
|
|
143
|
-
if extension_fn_json: # Do not append if extension_fn_json is None
|
|
144
|
-
collected_extension_fn_json_list.append(extension_fn_json)
|
|
145
|
-
return False
|
|
146
|
-
|
|
147
|
-
return functools.partial(
|
|
148
|
-
__snowflake_internal_collect_extension_fn,
|
|
149
|
-
__snowflake_global_collected_extension_fn_json,
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
snowflake.snowpark.context._is_execution_environment_sandboxed_for_client = ( # noqa: SLF001
|
|
153
|
-
True
|
|
154
|
-
)
|
|
155
|
-
snowflake.snowpark.context._should_continue_registration = ( # noqa: SLF001
|
|
156
|
-
__snowflake_internal_create_extension_fn_registration_callback()
|
|
157
|
-
)
|
|
158
|
-
snowflake.snowpark.session._is_execution_environment_sandboxed_for_client = ( # noqa: SLF001
|
|
159
|
-
True
|
|
160
|
-
)
|
|
161
|
-
|
|
162
|
-
for global_key in list(globals().keys()):
|
|
163
|
-
if global_key.startswith("__snowflake_internal"):
|
|
164
|
-
del globals()[global_key]
|
|
165
|
-
|
|
166
|
-
del globals()["global_key"] # make sure to clean up the loop variable as well
|
|
167
|
-
|
|
168
|
-
try:
|
|
169
|
-
import importlib
|
|
170
|
-
with contextlib.redirect_stdout(None):
|
|
171
|
-
with contextlib.redirect_stderr(None):
|
|
172
|
-
__snowflake_internal_spec = importlib.util.spec_from_file_location("<string>", r"{{py_file}}")
|
|
173
|
-
__snowflake_internal_module = importlib.util.module_from_spec(__snowflake_internal_spec)
|
|
174
|
-
__snowflake_internal_spec.loader.exec_module(__snowflake_internal_module)
|
|
175
|
-
except Exception as exc: # Catch any error
|
|
176
|
-
print("An exception occurred while executing file: ", exc, file=sys.stderr)
|
|
177
|
-
sys.exit(1)
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
import json
|
|
181
|
-
print(json.dumps(__snowflake_global_collected_extension_fn_json))
|
|
@@ -1,217 +0,0 @@
|
|
|
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 ast
|
|
18
|
-
from typing import (
|
|
19
|
-
List,
|
|
20
|
-
Optional,
|
|
21
|
-
Sequence,
|
|
22
|
-
Union,
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
from click.exceptions import ClickException
|
|
26
|
-
from snowflake.cli.api.project.schemas.snowpark.argument import Argument
|
|
27
|
-
from snowflake.cli.api.project.util import (
|
|
28
|
-
is_valid_identifier,
|
|
29
|
-
is_valid_string_literal,
|
|
30
|
-
to_identifier,
|
|
31
|
-
to_string_literal,
|
|
32
|
-
)
|
|
33
|
-
from snowflake.cli.plugins.nativeapp.codegen.snowpark.models import (
|
|
34
|
-
ExtensionFunctionTypeEnum,
|
|
35
|
-
NativeAppExtensionFunction,
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
ASTDefNode = Union[ast.FunctionDef, ast.ClassDef]
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class MalformedExtensionFunctionError(ClickException):
|
|
42
|
-
"""Required extension function attribute is missing."""
|
|
43
|
-
|
|
44
|
-
def __init__(self, message: str):
|
|
45
|
-
super().__init__(message=message)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def get_sql_object_type(extension_fn: NativeAppExtensionFunction) -> Optional[str]:
|
|
49
|
-
if extension_fn.function_type == ExtensionFunctionTypeEnum.PROCEDURE:
|
|
50
|
-
return "PROCEDURE"
|
|
51
|
-
elif extension_fn.function_type in (
|
|
52
|
-
ExtensionFunctionTypeEnum.FUNCTION,
|
|
53
|
-
ExtensionFunctionTypeEnum.TABLE_FUNCTION,
|
|
54
|
-
):
|
|
55
|
-
return "FUNCTION"
|
|
56
|
-
elif extension_fn.function_type == extension_fn.function_type.AGGREGATE_FUNCTION:
|
|
57
|
-
return "AGGREGATE FUNCTION"
|
|
58
|
-
else:
|
|
59
|
-
return None
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def get_sql_argument_signature(arg: Argument) -> str:
|
|
63
|
-
formatted = f"{arg.name} {arg.arg_type}"
|
|
64
|
-
if arg.default is not None:
|
|
65
|
-
formatted = f"{formatted} DEFAULT {arg.default}"
|
|
66
|
-
return formatted
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def get_function_type_signature_for_grant(
|
|
70
|
-
extension_fn: NativeAppExtensionFunction,
|
|
71
|
-
) -> str:
|
|
72
|
-
"""
|
|
73
|
-
Returns the type signature for the specified function, e.g. "int, varchar", suitable for inclusion in a GRANT statement.
|
|
74
|
-
"""
|
|
75
|
-
return ", ".join([arg.arg_type for arg in extension_fn.signature])
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def get_qualified_object_name(extension_fn: NativeAppExtensionFunction) -> str:
|
|
79
|
-
qualified_name = to_identifier(extension_fn.name)
|
|
80
|
-
if extension_fn.schema_name:
|
|
81
|
-
if is_valid_identifier(extension_fn.schema_name):
|
|
82
|
-
qualified_name = f"{extension_fn.schema_name}.{qualified_name}"
|
|
83
|
-
else:
|
|
84
|
-
full_schema = ".".join(
|
|
85
|
-
[
|
|
86
|
-
to_identifier(schema_part)
|
|
87
|
-
for schema_part in extension_fn.schema_name.split(".")
|
|
88
|
-
]
|
|
89
|
-
)
|
|
90
|
-
qualified_name = f"{full_schema}.{qualified_name}"
|
|
91
|
-
|
|
92
|
-
return qualified_name
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def ensure_string_literal(value: str) -> str:
|
|
96
|
-
"""
|
|
97
|
-
Returns the string literal representation of the given value, or the value itself if
|
|
98
|
-
it was already a valid string literal.
|
|
99
|
-
"""
|
|
100
|
-
if is_valid_string_literal(value):
|
|
101
|
-
return value
|
|
102
|
-
return to_string_literal(value)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
def ensure_all_string_literals(values: Sequence[str]) -> List[str]:
|
|
106
|
-
"""
|
|
107
|
-
Ensures that all provided values are valid string literals.
|
|
108
|
-
|
|
109
|
-
Returns:
|
|
110
|
-
A list with all values transformed to be valid string literals (as necessary).
|
|
111
|
-
"""
|
|
112
|
-
return [ensure_string_literal(value) for value in values]
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
class _SnowparkHandlerAccumulator(ast.NodeVisitor):
|
|
116
|
-
"""
|
|
117
|
-
A NodeVisitor that collects AST nodes corresponding to a provided list of Snowpark external functions.
|
|
118
|
-
The returned nodes are filtered using the handlers provided for each of the Snowpark functions.
|
|
119
|
-
Returned definitions can be either function definition or class definition AST nodes.
|
|
120
|
-
"""
|
|
121
|
-
|
|
122
|
-
def __init__(self, functions: Sequence[NativeAppExtensionFunction]):
|
|
123
|
-
self._wanted_handlers_by_name = {
|
|
124
|
-
fn.handler.split(".")[-1]: fn for fn in functions
|
|
125
|
-
}
|
|
126
|
-
self.definitions: List[ASTDefNode] = []
|
|
127
|
-
|
|
128
|
-
def visit_FunctionDef(self, node: ast.FunctionDef): # noqa: N802
|
|
129
|
-
if self._want(node):
|
|
130
|
-
self.definitions.append(node)
|
|
131
|
-
self.generic_visit(node)
|
|
132
|
-
|
|
133
|
-
def visit_ClassDef(self, node: ast.ClassDef): # noqa: N802
|
|
134
|
-
if self._want(node):
|
|
135
|
-
self.definitions.append(node)
|
|
136
|
-
self.generic_visit(node)
|
|
137
|
-
|
|
138
|
-
def _want(self, node: ASTDefNode) -> bool:
|
|
139
|
-
if not node.decorator_list:
|
|
140
|
-
# No decorators for this definition, ignore it
|
|
141
|
-
return False
|
|
142
|
-
|
|
143
|
-
return node.name in self._wanted_handlers_by_name
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def _get_decorator_id(node: ast.AST) -> Optional[str]:
|
|
147
|
-
"""
|
|
148
|
-
Returns the fully qualified identifier for a decorator, e.g. "foo" or "foo.bar".
|
|
149
|
-
"""
|
|
150
|
-
if isinstance(node, ast.Name):
|
|
151
|
-
return node.id
|
|
152
|
-
elif isinstance(node, ast.Attribute):
|
|
153
|
-
return f"{_get_decorator_id(node.value)}.{node.attr}"
|
|
154
|
-
elif isinstance(node, ast.Call):
|
|
155
|
-
return _get_decorator_id(node.func)
|
|
156
|
-
else:
|
|
157
|
-
return None
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def _collect_ast_handler_definitions(
|
|
161
|
-
tree: ast.AST, extension_functions: Sequence[NativeAppExtensionFunction]
|
|
162
|
-
) -> Sequence[ASTDefNode]:
|
|
163
|
-
accumulator = _SnowparkHandlerAccumulator(extension_functions)
|
|
164
|
-
accumulator.visit(tree)
|
|
165
|
-
return accumulator.definitions
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
def deannotate_module_source(
|
|
169
|
-
module_source: str,
|
|
170
|
-
extension_functions: Sequence[NativeAppExtensionFunction],
|
|
171
|
-
annotations_to_preserve: Sequence[str] = (),
|
|
172
|
-
) -> str:
|
|
173
|
-
"""
|
|
174
|
-
Removes annotations from a set of specified extension functions.
|
|
175
|
-
|
|
176
|
-
Arguments:
|
|
177
|
-
module_source (str): The source code of the module to deannotate.
|
|
178
|
-
extension_functions (Sequence[NativeAppExtensionFunction]): The list of extension functions
|
|
179
|
-
to deannotate. Other functions encountered will be ignored.
|
|
180
|
-
annotations_to_preserve (Sequence[str], optional): The list of annotations to preserve. The
|
|
181
|
-
names should appear as they are found in the source code, e.g. "foo" for @foo or
|
|
182
|
-
"annotations.bar" for @annotations.bar.
|
|
183
|
-
|
|
184
|
-
Returns:
|
|
185
|
-
A de-annotated version of the module source if any match was found. In order to preserve
|
|
186
|
-
line numbers, annotations are simply commented out instead of completely removed.
|
|
187
|
-
"""
|
|
188
|
-
|
|
189
|
-
tree = ast.parse(module_source)
|
|
190
|
-
|
|
191
|
-
definitions = _collect_ast_handler_definitions(tree, extension_functions)
|
|
192
|
-
if not definitions:
|
|
193
|
-
return module_source
|
|
194
|
-
|
|
195
|
-
module_lines = module_source.splitlines()
|
|
196
|
-
for definition in definitions:
|
|
197
|
-
# Comment out all decorators. As per the python grammar, decorators must be terminated by a
|
|
198
|
-
# new line, so the line ranges can't overlap.
|
|
199
|
-
for decorator in definition.decorator_list:
|
|
200
|
-
decorator_id = _get_decorator_id(decorator)
|
|
201
|
-
if decorator_id is None:
|
|
202
|
-
continue
|
|
203
|
-
if annotations_to_preserve and decorator_id in annotations_to_preserve:
|
|
204
|
-
continue
|
|
205
|
-
|
|
206
|
-
# AST indices are 1-based
|
|
207
|
-
start_lineno = decorator.lineno - 1
|
|
208
|
-
if decorator.end_lineno is not None:
|
|
209
|
-
end_lineno = decorator.end_lineno - 1
|
|
210
|
-
else:
|
|
211
|
-
end_lineno = start_lineno
|
|
212
|
-
|
|
213
|
-
for lineno in range(start_lineno, end_lineno + 1):
|
|
214
|
-
module_lines[lineno] = "#: " + module_lines[lineno]
|
|
215
|
-
|
|
216
|
-
# we're writing files in text mode, so we should use '\n' regardless of the platform
|
|
217
|
-
return "\n".join(module_lines)
|
|
@@ -1,61 +0,0 @@
|
|
|
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 enum import Enum
|
|
18
|
-
from typing import List, Optional
|
|
19
|
-
|
|
20
|
-
from pydantic import Field
|
|
21
|
-
from snowflake.cli.api.project.schemas.snowpark.callable import _CallableBase
|
|
22
|
-
from snowflake.cli.api.project.schemas.updatable_model import IdentifierField
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class ExtensionFunctionTypeEnum(str, Enum):
|
|
26
|
-
PROCEDURE = "procedure"
|
|
27
|
-
FUNCTION = "function"
|
|
28
|
-
TABLE_FUNCTION = "table function"
|
|
29
|
-
AGGREGATE_FUNCTION = "aggregate function"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class NativeAppExtensionFunction(_CallableBase):
|
|
33
|
-
function_type: ExtensionFunctionTypeEnum = Field(
|
|
34
|
-
title="The type of extension function, one of 'procedure', 'function', 'table function' or 'aggregate function'",
|
|
35
|
-
alias="type",
|
|
36
|
-
)
|
|
37
|
-
lineno: Optional[int] = Field(
|
|
38
|
-
title="The starting line number of the extension function (1-based)",
|
|
39
|
-
default=None,
|
|
40
|
-
)
|
|
41
|
-
name: Optional[str] = Field(
|
|
42
|
-
title="The name of the extension function", default=None
|
|
43
|
-
)
|
|
44
|
-
packages: Optional[List[str]] = Field(
|
|
45
|
-
title="List of packages (with optional version constraints) to be loaded for the function",
|
|
46
|
-
default=[],
|
|
47
|
-
)
|
|
48
|
-
schema_name: Optional[str] = IdentifierField(
|
|
49
|
-
title=f"Name of the schema for the function",
|
|
50
|
-
default=None,
|
|
51
|
-
alias="schema",
|
|
52
|
-
)
|
|
53
|
-
application_roles: Optional[List[str]] = Field(
|
|
54
|
-
title="Application roles granted usage to the function",
|
|
55
|
-
default=[],
|
|
56
|
-
)
|
|
57
|
-
execute_as_caller: Optional[bool] = Field(
|
|
58
|
-
title="Determine whether the procedure is executed with the privileges of "
|
|
59
|
-
"the owner or with the privileges of the caller",
|
|
60
|
-
default=False,
|
|
61
|
-
)
|