snowflake-cli-labs 3.0.0rc4__py3-none-any.whl → 3.0.1__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-3.0.0rc4.dist-info → snowflake_cli_labs-3.0.1.dist-info}/METADATA +6 -96
- snowflake_cli_labs-3.0.1.dist-info/RECORD +5 -0
- snowflake/cli/__about__.py +0 -17
- snowflake/cli/__init__.py +0 -13
- 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/cli_app.py +0 -252
- snowflake/cli/_app/commands_registration/__init__.py +0 -33
- snowflake/cli/_app/commands_registration/builtin_plugins.py +0 -50
- 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 -118
- 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 -67
- 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/secret.py +0 -9
- snowflake/cli/_app/snow_connector.py +0 -309
- snowflake/cli/_app/telemetry.py +0 -220
- snowflake/cli/_app/version_check.py +0 -74
- snowflake/cli/_plugins/__init__.py +0 -13
- snowflake/cli/_plugins/connection/__init__.py +0 -13
- snowflake/cli/_plugins/connection/commands.py +0 -353
- snowflake/cli/_plugins/connection/plugin_spec.py +0 -30
- snowflake/cli/_plugins/connection/util.py +0 -195
- snowflake/cli/_plugins/cortex/__init__.py +0 -13
- snowflake/cli/_plugins/cortex/commands.py +0 -332
- 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 -358
- snowflake/cli/_plugins/git/manager.py +0 -151
- snowflake/cli/_plugins/git/plugin_spec.py +0 -30
- snowflake/cli/_plugins/helpers/__init__.py +0 -13
- snowflake/cli/_plugins/helpers/commands.py +0 -61
- snowflake/cli/_plugins/helpers/plugin_spec.py +0 -30
- snowflake/cli/_plugins/init/__init__.py +0 -13
- snowflake/cli/_plugins/init/commands.py +0 -248
- snowflake/cli/_plugins/init/plugin_spec.py +0 -30
- snowflake/cli/_plugins/nativeapp/__init__.py +0 -13
- snowflake/cli/_plugins/nativeapp/artifacts.py +0 -757
- snowflake/cli/_plugins/nativeapp/bundle_context.py +0 -31
- 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 -149
- snowflake/cli/_plugins/nativeapp/codegen/sandbox.py +0 -306
- snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +0 -249
- snowflake/cli/_plugins/nativeapp/codegen/setup/setup_driver.py.source +0 -59
- 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 -523
- snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +0 -114
- snowflake/cli/_plugins/nativeapp/commands.py +0 -559
- snowflake/cli/_plugins/nativeapp/common_flags.py +0 -44
- snowflake/cli/_plugins/nativeapp/constants.py +0 -27
- snowflake/cli/_plugins/nativeapp/entities/__init__.py +0 -0
- snowflake/cli/_plugins/nativeapp/entities/application.py +0 -878
- snowflake/cli/_plugins/nativeapp/entities/application_package.py +0 -1392
- snowflake/cli/_plugins/nativeapp/exceptions.py +0 -113
- snowflake/cli/_plugins/nativeapp/feature_flags.py +0 -24
- snowflake/cli/_plugins/nativeapp/manager.py +0 -415
- snowflake/cli/_plugins/nativeapp/plugin_spec.py +0 -30
- snowflake/cli/_plugins/nativeapp/policy.py +0 -53
- snowflake/cli/_plugins/nativeapp/project_model.py +0 -211
- snowflake/cli/_plugins/nativeapp/run_processor.py +0 -184
- snowflake/cli/_plugins/nativeapp/same_account_install_method.py +0 -70
- snowflake/cli/_plugins/nativeapp/teardown_processor.py +0 -70
- snowflake/cli/_plugins/nativeapp/utils.py +0 -98
- snowflake/cli/_plugins/nativeapp/v2_conversions/v2_to_v1_decorator.py +0 -262
- snowflake/cli/_plugins/nativeapp/version/__init__.py +0 -13
- snowflake/cli/_plugins/nativeapp/version/commands.py +0 -141
- snowflake/cli/_plugins/nativeapp/version/version_processor.py +0 -98
- snowflake/cli/_plugins/notebook/__init__.py +0 -13
- snowflake/cli/_plugins/notebook/commands.py +0 -86
- 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 -15
- snowflake/cli/_plugins/object/__init__.py +0 -13
- snowflake/cli/_plugins/object/command_aliases.py +0 -95
- snowflake/cli/_plugins/object/commands.py +0 -180
- snowflake/cli/_plugins/object/common.py +0 -85
- snowflake/cli/_plugins/object/manager.py +0 -118
- snowflake/cli/_plugins/object/plugin_spec.py +0 -30
- snowflake/cli/_plugins/snowpark/__init__.py +0 -13
- snowflake/cli/_plugins/snowpark/commands.py +0 -450
- snowflake/cli/_plugins/snowpark/common.py +0 -268
- snowflake/cli/_plugins/snowpark/models.py +0 -150
- snowflake/cli/_plugins/snowpark/package/__init__.py +0 -13
- snowflake/cli/_plugins/snowpark/package/anaconda_packages.py +0 -199
- snowflake/cli/_plugins/snowpark/package/commands.py +0 -195
- snowflake/cli/_plugins/snowpark/package/manager.py +0 -44
- 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_entity.py +0 -29
- snowflake/cli/_plugins/snowpark/snowpark_entity_model.py +0 -173
- snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +0 -109
- snowflake/cli/_plugins/snowpark/snowpark_shared.py +0 -59
- snowflake/cli/_plugins/snowpark/zipper.py +0 -89
- snowflake/cli/_plugins/spcs/__init__.py +0 -33
- 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 -241
- 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 -202
- snowflake/cli/_plugins/spcs/image_repository/manager.py +0 -84
- 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 -345
- snowflake/cli/_plugins/spcs/services/manager.py +0 -208
- snowflake/cli/_plugins/sql/__init__.py +0 -13
- snowflake/cli/_plugins/sql/commands.py +0 -86
- 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 -264
- snowflake/cli/_plugins/stage/diff.py +0 -280
- snowflake/cli/_plugins/stage/manager.py +0 -582
- snowflake/cli/_plugins/stage/md5.py +0 -160
- snowflake/cli/_plugins/stage/plugin_spec.py +0 -30
- snowflake/cli/_plugins/stage/utils.py +0 -54
- snowflake/cli/_plugins/streamlit/__init__.py +0 -13
- snowflake/cli/_plugins/streamlit/commands.py +0 -195
- snowflake/cli/_plugins/streamlit/manager.py +0 -220
- snowflake/cli/_plugins/streamlit/plugin_spec.py +0 -30
- snowflake/cli/_plugins/streamlit/streamlit_entity.py +0 -12
- snowflake/cli/_plugins/streamlit/streamlit_entity_model.py +0 -66
- snowflake/cli/_plugins/workspace/__init__.py +0 -13
- snowflake/cli/_plugins/workspace/action_context.py +0 -18
- snowflake/cli/_plugins/workspace/commands.py +0 -306
- snowflake/cli/_plugins/workspace/manager.py +0 -74
- snowflake/cli/_plugins/workspace/plugin_spec.py +0 -30
- snowflake/cli/api/__init__.py +0 -48
- snowflake/cli/api/cli_global_context.py +0 -247
- snowflake/cli/api/commands/__init__.py +0 -13
- snowflake/cli/api/commands/alias.py +0 -23
- snowflake/cli/api/commands/common.py +0 -25
- snowflake/cli/api/commands/decorators.py +0 -369
- snowflake/cli/api/commands/execution_metadata.py +0 -40
- snowflake/cli/api/commands/experimental_behaviour.py +0 -18
- snowflake/cli/api/commands/flags.py +0 -561
- snowflake/cli/api/commands/overrideable_parameter.py +0 -143
- snowflake/cli/api/commands/snow_typer.py +0 -247
- snowflake/cli/api/commands/utils.py +0 -18
- snowflake/cli/api/config.py +0 -380
- snowflake/cli/api/connections.py +0 -216
- snowflake/cli/api/console/__init__.py +0 -17
- snowflake/cli/api/console/abc.py +0 -94
- snowflake/cli/api/console/console.py +0 -134
- snowflake/cli/api/console/enum.py +0 -17
- snowflake/cli/api/constants.py +0 -90
- snowflake/cli/api/entities/common.py +0 -56
- snowflake/cli/api/entities/utils.py +0 -370
- snowflake/cli/api/errno.py +0 -28
- snowflake/cli/api/exceptions.py +0 -190
- snowflake/cli/api/feature_flags.py +0 -54
- snowflake/cli/api/identifiers.py +0 -190
- snowflake/cli/api/metrics.py +0 -92
- 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 -126
- snowflake/cli/api/project/definition_conversion.py +0 -395
- snowflake/cli/api/project/definition_manager.py +0 -145
- 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/__init__.py +0 -13
- snowflake/cli/api/project/schemas/entities/common.py +0 -153
- snowflake/cli/api/project/schemas/entities/entities.py +0 -61
- snowflake/cli/api/project/schemas/project_definition.py +0 -330
- snowflake/cli/api/project/schemas/template.py +0 -77
- snowflake/cli/api/project/schemas/updatable_model.py +0 -202
- snowflake/cli/api/project/schemas/v1/__init__.py +0 -0
- snowflake/cli/api/project/schemas/v1/identifier_model.py +0 -51
- snowflake/cli/api/project/schemas/v1/native_app/__init__.py +0 -0
- snowflake/cli/api/project/schemas/v1/native_app/application.py +0 -61
- snowflake/cli/api/project/schemas/v1/native_app/native_app.py +0 -93
- snowflake/cli/api/project/schemas/v1/native_app/package.py +0 -84
- snowflake/cli/api/project/schemas/v1/native_app/path_mapping.py +0 -65
- snowflake/cli/api/project/schemas/v1/snowpark/__init__.py +0 -0
- snowflake/cli/api/project/schemas/v1/snowpark/argument.py +0 -28
- snowflake/cli/api/project/schemas/v1/snowpark/callable.py +0 -69
- snowflake/cli/api/project/schemas/v1/snowpark/snowpark.py +0 -36
- snowflake/cli/api/project/schemas/v1/streamlit/__init__.py +0 -0
- snowflake/cli/api/project/schemas/v1/streamlit/streamlit.py +0 -47
- snowflake/cli/api/project/util.py +0 -278
- snowflake/cli/api/rendering/__init__.py +0 -13
- snowflake/cli/api/rendering/jinja.py +0 -118
- snowflake/cli/api/rendering/project_definition_templates.py +0 -43
- snowflake/cli/api/rendering/project_templates.py +0 -98
- snowflake/cli/api/rendering/sql_templates.py +0 -105
- snowflake/cli/api/rest_api.py +0 -178
- snowflake/cli/api/sanitizers.py +0 -43
- snowflake/cli/api/secure_path.py +0 -360
- snowflake/cli/api/secure_utils.py +0 -118
- snowflake/cli/api/sql_execution.py +0 -280
- snowflake/cli/api/utils/__init__.py +0 -13
- snowflake/cli/api/utils/cursor.py +0 -34
- snowflake/cli/api/utils/definition_rendering.py +0 -415
- 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_labs-3.0.0rc4.dist-info/RECORD +0 -242
- snowflake_cli_labs-3.0.0rc4.dist-info/entry_points.txt +0 -2
- {snowflake_cli_labs-3.0.0rc4.dist-info → snowflake_cli_labs-3.0.1.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-3.0.0rc4.dist-info → snowflake_cli_labs-3.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,330 +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 dataclasses import dataclass
|
|
18
|
-
from typing import Any, Dict, List, Optional, Union
|
|
19
|
-
|
|
20
|
-
from packaging.version import Version
|
|
21
|
-
from pydantic import Field, ValidationError, field_validator, model_validator
|
|
22
|
-
from snowflake.cli._plugins.nativeapp.entities.application import ApplicationEntityModel
|
|
23
|
-
from snowflake.cli.api.project.errors import SchemaValidationError
|
|
24
|
-
from snowflake.cli.api.project.schemas.entities.common import (
|
|
25
|
-
TargetField,
|
|
26
|
-
)
|
|
27
|
-
from snowflake.cli.api.project.schemas.entities.entities import (
|
|
28
|
-
EntityModel,
|
|
29
|
-
v2_entity_model_types_map,
|
|
30
|
-
)
|
|
31
|
-
from snowflake.cli.api.project.schemas.updatable_model import UpdatableModel
|
|
32
|
-
from snowflake.cli.api.project.schemas.v1.native_app.native_app import (
|
|
33
|
-
NativeApp,
|
|
34
|
-
NativeAppV11,
|
|
35
|
-
)
|
|
36
|
-
from snowflake.cli.api.project.schemas.v1.snowpark.snowpark import Snowpark
|
|
37
|
-
from snowflake.cli.api.project.schemas.v1.streamlit.streamlit import Streamlit
|
|
38
|
-
from snowflake.cli.api.utils.types import Context
|
|
39
|
-
from typing_extensions import Annotated
|
|
40
|
-
|
|
41
|
-
AnnotatedEntity = Annotated[EntityModel, Field(discriminator="type")]
|
|
42
|
-
scalar = str | int | float | bool
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@dataclass
|
|
46
|
-
class ProjectProperties:
|
|
47
|
-
"""
|
|
48
|
-
This class stores 2 objects representing the snowflake project:
|
|
49
|
-
|
|
50
|
-
The project_context object:
|
|
51
|
-
- Used as the context for templating when users reference variables in the project definition file.
|
|
52
|
-
|
|
53
|
-
The project_definition object:
|
|
54
|
-
- This is a transformed object type through Pydantic, which has been normalized.
|
|
55
|
-
- This object could have slightly different structure than what the users see in their yaml project definition files.
|
|
56
|
-
- This should be used for the business logic of snow CLI modules.
|
|
57
|
-
"""
|
|
58
|
-
|
|
59
|
-
project_definition: ProjectDefinition
|
|
60
|
-
project_context: Context
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
@dataclass
|
|
64
|
-
class YamlOverride:
|
|
65
|
-
data: dict | list
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
class _ProjectDefinitionBase(UpdatableModel):
|
|
69
|
-
def __init__(self, *args, **kwargs):
|
|
70
|
-
try:
|
|
71
|
-
super().__init__(**kwargs)
|
|
72
|
-
except ValidationError as e:
|
|
73
|
-
raise SchemaValidationError(e) from e
|
|
74
|
-
|
|
75
|
-
definition_version: Union[str, int] = Field(
|
|
76
|
-
title="Version of the project definition schema, which is currently 1",
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
@field_validator("definition_version")
|
|
80
|
-
@classmethod
|
|
81
|
-
def _is_supported_version(cls, version: str) -> str:
|
|
82
|
-
version = str(version)
|
|
83
|
-
version_map = get_version_map()
|
|
84
|
-
if version not in version_map:
|
|
85
|
-
raise ValueError(
|
|
86
|
-
f'Version {version} is not supported. Supported versions: {", ".join(version_map)}'
|
|
87
|
-
)
|
|
88
|
-
return version
|
|
89
|
-
|
|
90
|
-
def meets_version_requirement(self, required_version: str) -> bool:
|
|
91
|
-
return Version(self.definition_version) >= Version(required_version)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class DefinitionV10(_ProjectDefinitionBase):
|
|
95
|
-
native_app: Optional[NativeApp] = Field(
|
|
96
|
-
title="Native app definitions for the project", default=None
|
|
97
|
-
)
|
|
98
|
-
snowpark: Optional[Snowpark] = Field(
|
|
99
|
-
title="Snowpark functions and procedures definitions for the project",
|
|
100
|
-
default=None,
|
|
101
|
-
)
|
|
102
|
-
streamlit: Optional[Streamlit] = Field(
|
|
103
|
-
title="Streamlit definitions for the project", default=None
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
class DefinitionV11(DefinitionV10):
|
|
108
|
-
native_app: Optional[NativeAppV11] = Field(
|
|
109
|
-
title="Native app definitions for the project", default=None
|
|
110
|
-
)
|
|
111
|
-
env: Optional[Dict[str, Union[str, int, bool]]] = Field(
|
|
112
|
-
title="Default environment specification for this project.",
|
|
113
|
-
default=None,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
class DefinitionV20(_ProjectDefinitionBase):
|
|
118
|
-
entities: Dict[str, AnnotatedEntity] = Field(title="Entity definitions.")
|
|
119
|
-
|
|
120
|
-
@model_validator(mode="after")
|
|
121
|
-
def validate_entities_identifiers(self):
|
|
122
|
-
for key, entity in self.entities.items():
|
|
123
|
-
entity.set_entity_id(key)
|
|
124
|
-
entity.validate_identifier()
|
|
125
|
-
return self
|
|
126
|
-
|
|
127
|
-
@field_validator("entities", mode="after")
|
|
128
|
-
@classmethod
|
|
129
|
-
def validate_entities(
|
|
130
|
-
cls, entities: Dict[str, AnnotatedEntity]
|
|
131
|
-
) -> Dict[str, AnnotatedEntity]:
|
|
132
|
-
for key, entity in entities.items():
|
|
133
|
-
# TODO Automatically detect TargetFields to validate
|
|
134
|
-
if isinstance(entity, list):
|
|
135
|
-
for e in entity:
|
|
136
|
-
cls._validate_single_entity(e, entities)
|
|
137
|
-
else:
|
|
138
|
-
cls._validate_single_entity(entity, entities)
|
|
139
|
-
return entities
|
|
140
|
-
|
|
141
|
-
@classmethod
|
|
142
|
-
def _validate_single_entity(
|
|
143
|
-
cls, entity: EntityModel, entities: Dict[str, AnnotatedEntity]
|
|
144
|
-
):
|
|
145
|
-
if entity.type == ApplicationEntityModel.get_type():
|
|
146
|
-
if isinstance(entity.from_, TargetField):
|
|
147
|
-
target_key = entity.from_.target
|
|
148
|
-
target_object = entity.from_
|
|
149
|
-
target_type = target_object.get_type()
|
|
150
|
-
cls._validate_target_field(target_key, target_type, entities)
|
|
151
|
-
|
|
152
|
-
@classmethod
|
|
153
|
-
def _validate_target_field(
|
|
154
|
-
cls, target_key: str, target_type: EntityModel, entities: Dict[str, EntityModel]
|
|
155
|
-
):
|
|
156
|
-
if target_key not in entities:
|
|
157
|
-
raise ValueError(f"No such target: {target_key}")
|
|
158
|
-
|
|
159
|
-
# Validate the target type
|
|
160
|
-
actual_target_type = entities[target_key].__class__
|
|
161
|
-
if target_type and target_type is not actual_target_type:
|
|
162
|
-
raise ValueError(
|
|
163
|
-
f"Target type mismatch. Expected {target_type.__name__}, got {actual_target_type.__name__}"
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
env: Optional[Dict[str, Union[str, int, bool]]] = Field(
|
|
167
|
-
title="Default environment specification for this project.",
|
|
168
|
-
default=None,
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
mixins: Optional[Dict[str, Dict]] = Field(
|
|
172
|
-
title="Mixins to apply to entities",
|
|
173
|
-
default=None,
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
@model_validator(mode="before")
|
|
177
|
-
@classmethod
|
|
178
|
-
def apply_mixins(cls, data: Dict) -> Dict:
|
|
179
|
-
"""
|
|
180
|
-
Applies mixins to those entities, whose meta field contains the mixin name.
|
|
181
|
-
"""
|
|
182
|
-
if "mixins" not in data or "entities" not in data:
|
|
183
|
-
return data
|
|
184
|
-
|
|
185
|
-
entities = data["entities"]
|
|
186
|
-
for entity_name, entity in entities.items():
|
|
187
|
-
entity_mixins = entity_mixins_to_list(
|
|
188
|
-
entity.get("meta", {}).get("use_mixins")
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
merged_values = cls._merge_mixins_with_entity(
|
|
192
|
-
entity_id=entity_name,
|
|
193
|
-
entity=entity,
|
|
194
|
-
entity_mixins_names=entity_mixins,
|
|
195
|
-
mixin_defs=data["mixins"],
|
|
196
|
-
)
|
|
197
|
-
entities[entity_name] = merged_values
|
|
198
|
-
return data
|
|
199
|
-
|
|
200
|
-
@classmethod
|
|
201
|
-
def _merge_mixins_with_entity(
|
|
202
|
-
cls,
|
|
203
|
-
entity_id: str,
|
|
204
|
-
entity: dict,
|
|
205
|
-
entity_mixins_names: list,
|
|
206
|
-
mixin_defs: dict,
|
|
207
|
-
) -> dict:
|
|
208
|
-
# Validate mixins
|
|
209
|
-
for mixin_name in entity_mixins_names:
|
|
210
|
-
if mixin_name not in mixin_defs:
|
|
211
|
-
raise ValueError(f"Mixin {mixin_name} not defined")
|
|
212
|
-
|
|
213
|
-
# Build object override data from mixins
|
|
214
|
-
data: dict = {}
|
|
215
|
-
for mx_name in entity_mixins_names:
|
|
216
|
-
data = cls._merge_data(data, mixin_defs[mx_name])
|
|
217
|
-
|
|
218
|
-
for key, override_value in data.items():
|
|
219
|
-
if key not in get_allowed_fields_for_entity(entity):
|
|
220
|
-
raise ValueError(
|
|
221
|
-
f"Unsupported key '{key}' for entity {entity_id} of type {entity['type']} "
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
entity_value = entity.get(key)
|
|
225
|
-
if (
|
|
226
|
-
entity_value is not None
|
|
227
|
-
and not isinstance(entity_value, YamlOverride)
|
|
228
|
-
and not isinstance(entity_value, type(override_value))
|
|
229
|
-
):
|
|
230
|
-
raise ValueError(
|
|
231
|
-
f"Value from mixins for property {key} is of type '{type(override_value).__name__}' "
|
|
232
|
-
f"while entity {entity_id} expects value of type '{type(entity_value).__name__}'"
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
# Apply entity data on top of mixins
|
|
236
|
-
data = cls._merge_data(data, entity)
|
|
237
|
-
return data
|
|
238
|
-
|
|
239
|
-
@classmethod
|
|
240
|
-
def _merge_data(
|
|
241
|
-
cls,
|
|
242
|
-
left: dict | list | scalar | None,
|
|
243
|
-
right: dict | list | scalar | None | YamlOverride,
|
|
244
|
-
):
|
|
245
|
-
"""
|
|
246
|
-
Merges right data into left. Right and left is expected to be of the same type, if not right is returned.
|
|
247
|
-
If left is sequence then missing elements from right are appended.
|
|
248
|
-
If left is dictionary then we update it with data from right. The update is done recursively key by key.
|
|
249
|
-
"""
|
|
250
|
-
if isinstance(right, YamlOverride):
|
|
251
|
-
return right.data
|
|
252
|
-
|
|
253
|
-
if left is None:
|
|
254
|
-
return right
|
|
255
|
-
|
|
256
|
-
# At that point left and right are of the same type
|
|
257
|
-
if isinstance(left, dict) and isinstance(right, dict):
|
|
258
|
-
data = dict(left)
|
|
259
|
-
for key in right:
|
|
260
|
-
data[key] = cls._merge_data(left=data.get(key), right=right[key])
|
|
261
|
-
return data
|
|
262
|
-
|
|
263
|
-
if isinstance(left, list) and isinstance(right, list):
|
|
264
|
-
return _unique_extend(left, right)
|
|
265
|
-
|
|
266
|
-
if not isinstance(right, type(left)):
|
|
267
|
-
raise ValueError(f"Could not merge {type(right)} and {type(left)}.")
|
|
268
|
-
|
|
269
|
-
return right
|
|
270
|
-
|
|
271
|
-
def get_entities_by_type(self, entity_type: str):
|
|
272
|
-
return {i: e for i, e in self.entities.items() if e.get_type() == entity_type}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
def build_project_definition(**data) -> ProjectDefinition:
|
|
276
|
-
"""
|
|
277
|
-
Returns a ProjectDefinition instance with a version matching the provided definition_version value
|
|
278
|
-
"""
|
|
279
|
-
if not isinstance(data, dict):
|
|
280
|
-
return
|
|
281
|
-
version = data.get("definition_version")
|
|
282
|
-
version_model = get_version_map().get(str(version))
|
|
283
|
-
if not version or not version_model:
|
|
284
|
-
# Raises a SchemaValidationError
|
|
285
|
-
_ProjectDefinitionBase(**data)
|
|
286
|
-
return version_model(**data)
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
ProjectDefinitionV1 = Union[DefinitionV10, DefinitionV11]
|
|
290
|
-
ProjectDefinitionV2 = DefinitionV20
|
|
291
|
-
ProjectDefinition = Union[ProjectDefinitionV1, ProjectDefinitionV2]
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
def get_version_map():
|
|
295
|
-
version_map = {"1": DefinitionV10, "1.1": DefinitionV11, "2": DefinitionV20}
|
|
296
|
-
return version_map
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
def entity_mixins_to_list(entity_mixins: Optional[str | List[str]]) -> List[str]:
|
|
300
|
-
"""
|
|
301
|
-
Convert an optional string or a list of strings to a list of strings.
|
|
302
|
-
"""
|
|
303
|
-
if entity_mixins is None:
|
|
304
|
-
return []
|
|
305
|
-
if isinstance(entity_mixins, str):
|
|
306
|
-
return [entity_mixins]
|
|
307
|
-
return entity_mixins
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
def get_allowed_fields_for_entity(entity: Dict[str, Any]) -> List[str]:
|
|
311
|
-
"""
|
|
312
|
-
Get the allowed fields for the given entity.
|
|
313
|
-
"""
|
|
314
|
-
entity_type = entity.get("type")
|
|
315
|
-
if entity_type is None:
|
|
316
|
-
raise ValueError("Entity is missing type declaration.")
|
|
317
|
-
|
|
318
|
-
if entity_type not in v2_entity_model_types_map:
|
|
319
|
-
return []
|
|
320
|
-
|
|
321
|
-
entity_model = v2_entity_model_types_map[entity_type]
|
|
322
|
-
return entity_model.model_fields
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
def _unique_extend(list_a: List, list_b: List) -> List:
|
|
326
|
-
new_list = list(list_a)
|
|
327
|
-
for item in list_b:
|
|
328
|
-
if item not in list_a:
|
|
329
|
-
new_list.append(item)
|
|
330
|
-
return new_list
|
|
@@ -1,77 +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 typing import Any, List, Literal, Optional, Union
|
|
18
|
-
|
|
19
|
-
import typer
|
|
20
|
-
from click import ClickException
|
|
21
|
-
from pydantic import BaseModel, Field
|
|
22
|
-
from snowflake.cli.api.exceptions import InvalidTemplate
|
|
23
|
-
from snowflake.cli.api.secure_path import SecurePath
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class TemplateVariable(BaseModel):
|
|
27
|
-
name: str = Field(..., title="Variable identifier")
|
|
28
|
-
type: Optional[Literal["string", "float", "int"]] = Field( # noqa: A003
|
|
29
|
-
title="Type of the variable", default=None
|
|
30
|
-
)
|
|
31
|
-
prompt: Optional[str] = Field(title="Prompt message for the variable", default=None)
|
|
32
|
-
default: Optional[Any] = Field(title="Default value of the variable", default=None)
|
|
33
|
-
|
|
34
|
-
@property
|
|
35
|
-
def python_type(self):
|
|
36
|
-
# override "unchecked type" (None) with 'str', as Typer deduces type from the value of 'default'
|
|
37
|
-
return {
|
|
38
|
-
"string": str,
|
|
39
|
-
"float": float,
|
|
40
|
-
"int": int,
|
|
41
|
-
None: str,
|
|
42
|
-
}[self.type]
|
|
43
|
-
|
|
44
|
-
def prompt_user_for_value(self, no_interactive: bool) -> Union[str, float, int]:
|
|
45
|
-
if no_interactive:
|
|
46
|
-
if not self.default:
|
|
47
|
-
raise ClickException(f"Cannot determine value of variable {self.name}")
|
|
48
|
-
return self.default
|
|
49
|
-
|
|
50
|
-
prompt = self.prompt if self.prompt else self.name
|
|
51
|
-
return typer.prompt(prompt, default=self.default, type=self.python_type)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class Template(BaseModel):
|
|
55
|
-
minimum_cli_version: Optional[str] = Field(
|
|
56
|
-
None, title="Minimum version of Snowflake CLI supporting this template"
|
|
57
|
-
)
|
|
58
|
-
files_to_render: List[str] = Field(title="List of files to be rendered", default=[])
|
|
59
|
-
variables: List[TemplateVariable] = Field(
|
|
60
|
-
title="List of variables to be rendered", default=[]
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
def __init__(self, template_root: SecurePath, **kwargs):
|
|
64
|
-
super().__init__(**kwargs)
|
|
65
|
-
self._validate_files_exist(template_root)
|
|
66
|
-
|
|
67
|
-
def _validate_files_exist(self, template_root: SecurePath) -> None:
|
|
68
|
-
for path_in_template in self.files_to_render:
|
|
69
|
-
full_path = template_root / path_in_template
|
|
70
|
-
if not full_path.exists():
|
|
71
|
-
raise InvalidTemplate(
|
|
72
|
-
f"[files_to_render] contains not-existing file: {path_in_template}"
|
|
73
|
-
)
|
|
74
|
-
if full_path.is_dir():
|
|
75
|
-
raise InvalidTemplate(
|
|
76
|
-
f"[files_to_render] contains a dictionary: {path_in_template}"
|
|
77
|
-
)
|
|
@@ -1,202 +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 contextlib import contextmanager
|
|
18
|
-
from contextvars import ContextVar
|
|
19
|
-
from typing import Any, Dict, Iterator, Optional
|
|
20
|
-
|
|
21
|
-
from pydantic import (
|
|
22
|
-
BaseModel,
|
|
23
|
-
ConfigDict,
|
|
24
|
-
Field,
|
|
25
|
-
ValidationInfo,
|
|
26
|
-
field_validator,
|
|
27
|
-
)
|
|
28
|
-
from pydantic.fields import FieldInfo
|
|
29
|
-
from snowflake.cli.api.project.util import IDENTIFIER_NO_LENGTH
|
|
30
|
-
|
|
31
|
-
PROJECT_TEMPLATE_START = "<%"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def _is_templated(info: ValidationInfo, value: Any) -> bool:
|
|
35
|
-
return (
|
|
36
|
-
info.context
|
|
37
|
-
and info.context.get("skip_validation_on_templates", False)
|
|
38
|
-
and isinstance(value, str)
|
|
39
|
-
and PROJECT_TEMPLATE_START in value
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
_initial_context: ContextVar[Optional[Dict[str, Any]]] = ContextVar(
|
|
44
|
-
"_init_context_var", default=None
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@contextmanager
|
|
49
|
-
def context(value: Dict[str, Any]) -> Iterator[None]:
|
|
50
|
-
"""
|
|
51
|
-
Thread safe context for Pydantic.
|
|
52
|
-
By using `with context()`, you ensure context changes apply
|
|
53
|
-
to the with block only
|
|
54
|
-
"""
|
|
55
|
-
token = _initial_context.set(value)
|
|
56
|
-
try:
|
|
57
|
-
yield
|
|
58
|
-
finally:
|
|
59
|
-
_initial_context.reset(token)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class UpdatableModel(BaseModel):
|
|
63
|
-
model_config = ConfigDict(validate_assignment=True, extra="forbid")
|
|
64
|
-
|
|
65
|
-
def __init__(self, /, **data: Any) -> None:
|
|
66
|
-
"""
|
|
67
|
-
Pydantic provides 2 options to pass in context:
|
|
68
|
-
1) Through `model_validate()` as a second argument.
|
|
69
|
-
2) Through a custom init method and the use of ContextVar
|
|
70
|
-
|
|
71
|
-
We decided not to use 1) because it silently stops working
|
|
72
|
-
if someone adds a pass through __init__ to any of the Pydantic models.
|
|
73
|
-
|
|
74
|
-
We decided to go with 2) as the safer approach.
|
|
75
|
-
Calling validate_python() in the __init__ is how we can pass context
|
|
76
|
-
on initialization according to Pydantic's documentation:
|
|
77
|
-
https://docs.pydantic.dev/latest/concepts/validators/#using-validation-context-with-basemodel-initialization
|
|
78
|
-
"""
|
|
79
|
-
self.__pydantic_validator__.validate_python(
|
|
80
|
-
data,
|
|
81
|
-
self_instance=self,
|
|
82
|
-
context=_initial_context.get(),
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
@classmethod
|
|
86
|
-
def _is_entity_type_field(cls, field: Any) -> bool:
|
|
87
|
-
"""
|
|
88
|
-
Checks if a field is of type `DiscriminatorField`
|
|
89
|
-
"""
|
|
90
|
-
if not isinstance(field, FieldInfo) or not field.json_schema_extra:
|
|
91
|
-
return False
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
"is_discriminator_field" in field.json_schema_extra
|
|
95
|
-
and field.json_schema_extra["is_discriminator_field"]
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
@classmethod
|
|
99
|
-
def __init_subclass__(cls, **kwargs):
|
|
100
|
-
"""
|
|
101
|
-
This method will collect all the Pydantic annotations for the class
|
|
102
|
-
currently being initialized (any subclass of `UpdatableModel`).
|
|
103
|
-
|
|
104
|
-
It will add a field validator wrapper for every Pydantic field
|
|
105
|
-
in order to skip validation when templates are found.
|
|
106
|
-
|
|
107
|
-
It will apply this to all Pydantic fields, except for fields
|
|
108
|
-
marked as `DiscriminatorField`. These will be skipped because
|
|
109
|
-
Pydantic does not support validators for discriminator field types.
|
|
110
|
-
"""
|
|
111
|
-
|
|
112
|
-
super().__init_subclass__(**kwargs)
|
|
113
|
-
|
|
114
|
-
field_annotations = {}
|
|
115
|
-
field_values = {}
|
|
116
|
-
# Go through the inheritance classes and collect all the annotations and
|
|
117
|
-
# all the values of the class attributes. We go in reverse order so that
|
|
118
|
-
# values in subclasses overrides values from parent classes in case of field overrides.
|
|
119
|
-
|
|
120
|
-
private_attrs = set()
|
|
121
|
-
for class_ in reversed(cls.__mro__):
|
|
122
|
-
class_dict = class_.__dict__
|
|
123
|
-
field_annotations.update(class_dict.get("__annotations__", {}))
|
|
124
|
-
|
|
125
|
-
if "model_fields" in class_dict:
|
|
126
|
-
# This means the class dict has already been processed by Pydantic
|
|
127
|
-
# All fields should properly be populated in model_fields
|
|
128
|
-
field_values.update(class_dict["model_fields"])
|
|
129
|
-
else:
|
|
130
|
-
# If Pydantic did not process this class yet, get the values from class_dict directly
|
|
131
|
-
field_values.update(class_dict)
|
|
132
|
-
for pa in class_dict.get("__private_attributes__", []):
|
|
133
|
-
private_attrs.add(pa)
|
|
134
|
-
|
|
135
|
-
# Add Pydantic validation wrapper around all fields except `DiscriminatorField`s
|
|
136
|
-
for field_name in field_annotations:
|
|
137
|
-
if field_name in private_attrs:
|
|
138
|
-
continue
|
|
139
|
-
field = field_values.get(field_name)
|
|
140
|
-
if not cls._is_entity_type_field(field):
|
|
141
|
-
cls._add_validator(field_name)
|
|
142
|
-
|
|
143
|
-
@classmethod
|
|
144
|
-
def _add_validator(cls, field_name: str):
|
|
145
|
-
"""
|
|
146
|
-
Adds a Pydantic validator with mode=wrap for the provided `field_name`.
|
|
147
|
-
During validation, this will check if the field is templated (not expanded yet)
|
|
148
|
-
and in that case, it will skip all the remaining Pydantic validation on that field.
|
|
149
|
-
|
|
150
|
-
Since this validator is added last, it will skip all the other field validators
|
|
151
|
-
defined in the subclasses when templates are found.
|
|
152
|
-
|
|
153
|
-
This logic on templates only applies when context contains `skip_validation_on_templates` flag.
|
|
154
|
-
"""
|
|
155
|
-
|
|
156
|
-
def validator_skipping_templated_str(cls, value, handler, info: ValidationInfo):
|
|
157
|
-
if _is_templated(info, value):
|
|
158
|
-
return value
|
|
159
|
-
return handler(value)
|
|
160
|
-
|
|
161
|
-
setattr(
|
|
162
|
-
cls,
|
|
163
|
-
# Unique name so that subclasses get a unique instance of this validator
|
|
164
|
-
f"_{cls.__module__}.{cls.__name__}_validate_{field_name}",
|
|
165
|
-
field_validator(field_name, mode="wrap")(validator_skipping_templated_str),
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
def update_from_dict(self, update_values: Dict[str, Any]):
|
|
169
|
-
"""
|
|
170
|
-
Takes a dictionary with values to override.
|
|
171
|
-
If the field type is subclass of a UpdatableModel, its update_from_dict() method is called with
|
|
172
|
-
the value to be set.
|
|
173
|
-
If not, we use simple setattr to set new value.
|
|
174
|
-
Values provided are validated against original restrictions, so it's impossible to overwrite string field with
|
|
175
|
-
integer value etc.
|
|
176
|
-
"""
|
|
177
|
-
for field, value in update_values.items():
|
|
178
|
-
if field in self.model_fields.keys():
|
|
179
|
-
if (
|
|
180
|
-
hasattr(getattr(self, field), "update_from_dict")
|
|
181
|
-
and field in self.model_fields_set
|
|
182
|
-
):
|
|
183
|
-
getattr(self, field).update_from_dict(value)
|
|
184
|
-
else:
|
|
185
|
-
setattr(self, field, value)
|
|
186
|
-
return self
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def DiscriminatorField(*args, **kwargs): # noqa N802
|
|
190
|
-
"""
|
|
191
|
-
Use this type for discriminator fields used for differentiating
|
|
192
|
-
between different entity types.
|
|
193
|
-
|
|
194
|
-
When this `DiscriminatorField` is used on a pydantic attribute,
|
|
195
|
-
we will not allow templating on it.
|
|
196
|
-
"""
|
|
197
|
-
extra = dict(is_discriminator_field=True)
|
|
198
|
-
return Field(json_schema_extra=extra, *args, **kwargs)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def IdentifierField(*args, **kwargs): # noqa N802
|
|
202
|
-
return Field(max_length=254, pattern=IDENTIFIER_NO_LENGTH, *args, **kwargs)
|
|
File without changes
|
|
@@ -1,51 +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 typing import Optional, cast
|
|
18
|
-
|
|
19
|
-
from pydantic import Field
|
|
20
|
-
from snowflake.cli.api.project.schemas.updatable_model import (
|
|
21
|
-
IdentifierField,
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class ObjectIdentifierBaseModel:
|
|
26
|
-
"""
|
|
27
|
-
Type representing a base class defining object that can be identified by fully qualified name (db.schema.name).
|
|
28
|
-
This is not a Pydantic model and the purpose of this class is to provide typing support to Pydantic models
|
|
29
|
-
generated using a factory class ObjectIdentifierModel.
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
name: str
|
|
33
|
-
database: Optional[str]
|
|
34
|
-
schema_name: Optional[str]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def ObjectIdentifierModel(object_name: str) -> ObjectIdentifierBaseModel: # noqa: N802
|
|
38
|
-
"""Generates ObjectIdentifierBaseModel but with object specific descriptions."""
|
|
39
|
-
|
|
40
|
-
class _ObjectIdentifierModel(ObjectIdentifierBaseModel):
|
|
41
|
-
name: str = Field(title=f"{object_name.capitalize()} name")
|
|
42
|
-
database: Optional[str] = IdentifierField(
|
|
43
|
-
title=f"Name of the database for the {object_name}", default=None
|
|
44
|
-
)
|
|
45
|
-
schema_name: Optional[str] = IdentifierField(
|
|
46
|
-
title=f"Name of the schema for the {object_name}",
|
|
47
|
-
default=None,
|
|
48
|
-
alias="schema",
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
return cast(ObjectIdentifierBaseModel, _ObjectIdentifierModel)
|
|
File without changes
|