snowflake-cli-labs 3.0.0rc5__py3-none-any.whl → 3.0.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-3.0.0rc5.dist-info → snowflake_cli_labs-3.0.2.dist-info}/METADATA +6 -96
- snowflake_cli_labs-3.0.2.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 -90
- 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 -400
- 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.0rc5.dist-info/RECORD +0 -242
- snowflake_cli_labs-3.0.0rc5.dist-info/entry_points.txt +0 -2
- {snowflake_cli_labs-3.0.0rc5.dist-info → snowflake_cli_labs-3.0.2.dist-info}/WHEEL +0 -0
- {snowflake_cli_labs-3.0.0rc5.dist-info → snowflake_cli_labs-3.0.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,353 +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 logging
|
|
18
|
-
import os.path
|
|
19
|
-
|
|
20
|
-
import typer
|
|
21
|
-
from click import ClickException, Context, Parameter # type: ignore
|
|
22
|
-
from click.core import ParameterSource # type: ignore
|
|
23
|
-
from click.types import StringParamType
|
|
24
|
-
from snowflake.cli._plugins.connection.util import (
|
|
25
|
-
strip_and_check_if_exists,
|
|
26
|
-
strip_if_value_present,
|
|
27
|
-
)
|
|
28
|
-
from snowflake.cli._plugins.object.manager import ObjectManager
|
|
29
|
-
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
30
|
-
from snowflake.cli.api.commands.flags import (
|
|
31
|
-
PLAIN_PASSWORD_MSG,
|
|
32
|
-
)
|
|
33
|
-
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
34
|
-
from snowflake.cli.api.config import (
|
|
35
|
-
ConnectionConfig,
|
|
36
|
-
add_connection_to_proper_file,
|
|
37
|
-
connection_exists,
|
|
38
|
-
get_all_connections,
|
|
39
|
-
get_connection_dict,
|
|
40
|
-
get_default_connection_name,
|
|
41
|
-
set_config_value,
|
|
42
|
-
)
|
|
43
|
-
from snowflake.cli.api.console import cli_console
|
|
44
|
-
from snowflake.cli.api.constants import ObjectType
|
|
45
|
-
from snowflake.cli.api.output.types import (
|
|
46
|
-
CollectionResult,
|
|
47
|
-
CommandResult,
|
|
48
|
-
MessageResult,
|
|
49
|
-
ObjectResult,
|
|
50
|
-
)
|
|
51
|
-
from snowflake.connector import ProgrammingError
|
|
52
|
-
from snowflake.connector.constants import CONNECTIONS_FILE
|
|
53
|
-
|
|
54
|
-
app = SnowTyperFactory(
|
|
55
|
-
name="connection",
|
|
56
|
-
help="Manages connections to Snowflake.",
|
|
57
|
-
)
|
|
58
|
-
log = logging.getLogger(__name__)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
class EmptyInput:
|
|
62
|
-
def __repr__(self):
|
|
63
|
-
return "optional"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
class OptionalPrompt(StringParamType):
|
|
67
|
-
def convert(self, value, param, ctx):
|
|
68
|
-
return None if isinstance(value, EmptyInput) else value
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def _mask_password(connection_params: dict):
|
|
72
|
-
if "password" in connection_params:
|
|
73
|
-
connection_params["password"] = "****"
|
|
74
|
-
return connection_params
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@app.command(name="list")
|
|
78
|
-
def list_connections(**options) -> CommandResult:
|
|
79
|
-
"""
|
|
80
|
-
Lists configured connections.
|
|
81
|
-
"""
|
|
82
|
-
connections = get_all_connections()
|
|
83
|
-
default_connection = get_default_connection_name()
|
|
84
|
-
result = (
|
|
85
|
-
{
|
|
86
|
-
"connection_name": connection_name,
|
|
87
|
-
"parameters": _mask_password(
|
|
88
|
-
connection_config.to_dict_of_known_non_empty_values()
|
|
89
|
-
),
|
|
90
|
-
"is_default": connection_name == default_connection,
|
|
91
|
-
}
|
|
92
|
-
for connection_name, connection_config in connections.items()
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
if CONNECTIONS_FILE.exists():
|
|
96
|
-
cli_console.warning(
|
|
97
|
-
f"Reading connections from {CONNECTIONS_FILE}. Entries from config.toml are ignored."
|
|
98
|
-
)
|
|
99
|
-
return CollectionResult(result)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def require_integer(field_name: str):
|
|
103
|
-
def callback(value: str):
|
|
104
|
-
if value is None:
|
|
105
|
-
return None
|
|
106
|
-
if value.strip().isdigit():
|
|
107
|
-
return value.strip()
|
|
108
|
-
raise ClickException(f"Value of {field_name} must be integer")
|
|
109
|
-
|
|
110
|
-
return callback
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def _password_callback(ctx: Context, param: Parameter, value: str):
|
|
114
|
-
if value and ctx.get_parameter_source(param.name) == ParameterSource.COMMANDLINE: # type: ignore
|
|
115
|
-
cli_console.warning(PLAIN_PASSWORD_MSG)
|
|
116
|
-
|
|
117
|
-
return value
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
@app.command()
|
|
121
|
-
def add(
|
|
122
|
-
connection_name: str = typer.Option(
|
|
123
|
-
None,
|
|
124
|
-
"--connection-name",
|
|
125
|
-
"-n",
|
|
126
|
-
prompt="Name for this connection",
|
|
127
|
-
help="Name of the new connection.",
|
|
128
|
-
show_default=False,
|
|
129
|
-
callback=strip_if_value_present,
|
|
130
|
-
),
|
|
131
|
-
account: str = typer.Option(
|
|
132
|
-
None,
|
|
133
|
-
"--account",
|
|
134
|
-
"-a",
|
|
135
|
-
"--accountname",
|
|
136
|
-
prompt="Snowflake account name",
|
|
137
|
-
help="Account name to use when authenticating with Snowflake.",
|
|
138
|
-
show_default=False,
|
|
139
|
-
callback=strip_if_value_present,
|
|
140
|
-
),
|
|
141
|
-
user: str = typer.Option(
|
|
142
|
-
None,
|
|
143
|
-
"--user",
|
|
144
|
-
"-u",
|
|
145
|
-
"--username",
|
|
146
|
-
prompt="Snowflake username",
|
|
147
|
-
show_default=False,
|
|
148
|
-
help="Username to connect to Snowflake.",
|
|
149
|
-
callback=strip_if_value_present,
|
|
150
|
-
),
|
|
151
|
-
password: str = typer.Option(
|
|
152
|
-
EmptyInput(),
|
|
153
|
-
"--password",
|
|
154
|
-
"-p",
|
|
155
|
-
click_type=OptionalPrompt(),
|
|
156
|
-
callback=_password_callback,
|
|
157
|
-
prompt="Snowflake password",
|
|
158
|
-
help="Snowflake password.",
|
|
159
|
-
hide_input=True,
|
|
160
|
-
),
|
|
161
|
-
role: str = typer.Option(
|
|
162
|
-
EmptyInput(),
|
|
163
|
-
"--role",
|
|
164
|
-
"-r",
|
|
165
|
-
click_type=OptionalPrompt(),
|
|
166
|
-
prompt="Role for the connection",
|
|
167
|
-
help="Role to use on Snowflake.",
|
|
168
|
-
callback=strip_if_value_present,
|
|
169
|
-
),
|
|
170
|
-
warehouse: str = typer.Option(
|
|
171
|
-
EmptyInput(),
|
|
172
|
-
"--warehouse",
|
|
173
|
-
"-w",
|
|
174
|
-
click_type=OptionalPrompt(),
|
|
175
|
-
prompt="Warehouse for the connection",
|
|
176
|
-
help="Warehouse to use on Snowflake.",
|
|
177
|
-
callback=strip_if_value_present,
|
|
178
|
-
),
|
|
179
|
-
database: str = typer.Option(
|
|
180
|
-
EmptyInput(),
|
|
181
|
-
"--database",
|
|
182
|
-
"-d",
|
|
183
|
-
click_type=OptionalPrompt(),
|
|
184
|
-
prompt="Database for the connection",
|
|
185
|
-
help="Database to use on Snowflake.",
|
|
186
|
-
callback=strip_if_value_present,
|
|
187
|
-
),
|
|
188
|
-
schema: str = typer.Option(
|
|
189
|
-
EmptyInput(),
|
|
190
|
-
"--schema",
|
|
191
|
-
"-s",
|
|
192
|
-
click_type=OptionalPrompt(),
|
|
193
|
-
prompt="Schema for the connection",
|
|
194
|
-
help="Schema to use on Snowflake.",
|
|
195
|
-
callback=strip_if_value_present,
|
|
196
|
-
),
|
|
197
|
-
host: str = typer.Option(
|
|
198
|
-
EmptyInput(),
|
|
199
|
-
"--host",
|
|
200
|
-
"-h",
|
|
201
|
-
click_type=OptionalPrompt(),
|
|
202
|
-
prompt="Connection host",
|
|
203
|
-
help="Host name the connection attempts to connect to Snowflake.",
|
|
204
|
-
callback=strip_if_value_present,
|
|
205
|
-
),
|
|
206
|
-
port: int = typer.Option(
|
|
207
|
-
EmptyInput(),
|
|
208
|
-
"--port",
|
|
209
|
-
"-P",
|
|
210
|
-
click_type=OptionalPrompt(),
|
|
211
|
-
prompt="Connection port",
|
|
212
|
-
help="Port to communicate with on the host.",
|
|
213
|
-
callback=require_integer(field_name="port"),
|
|
214
|
-
),
|
|
215
|
-
region: str = typer.Option(
|
|
216
|
-
EmptyInput(),
|
|
217
|
-
"--region",
|
|
218
|
-
"-R",
|
|
219
|
-
click_type=OptionalPrompt(),
|
|
220
|
-
prompt="Snowflake region",
|
|
221
|
-
help="Region name if not the default Snowflake deployment.",
|
|
222
|
-
callback=strip_if_value_present,
|
|
223
|
-
),
|
|
224
|
-
authenticator: str = typer.Option(
|
|
225
|
-
EmptyInput(),
|
|
226
|
-
"--authenticator",
|
|
227
|
-
"-A",
|
|
228
|
-
click_type=OptionalPrompt(),
|
|
229
|
-
prompt="Authentication method",
|
|
230
|
-
help="Chosen authenticator, if other than password-based",
|
|
231
|
-
),
|
|
232
|
-
private_key_file: str = typer.Option(
|
|
233
|
-
EmptyInput(),
|
|
234
|
-
"--private-key",
|
|
235
|
-
"--private-key-path",
|
|
236
|
-
"-k",
|
|
237
|
-
click_type=OptionalPrompt(),
|
|
238
|
-
prompt="Path to private key file",
|
|
239
|
-
help="Path to file containing private key",
|
|
240
|
-
callback=strip_and_check_if_exists,
|
|
241
|
-
),
|
|
242
|
-
token_file_path: str = typer.Option(
|
|
243
|
-
EmptyInput(),
|
|
244
|
-
"--token-file-path",
|
|
245
|
-
"-t",
|
|
246
|
-
click_type=OptionalPrompt(),
|
|
247
|
-
prompt="Path to token file",
|
|
248
|
-
help="Path to file with an OAuth token that should be used when connecting to Snowflake",
|
|
249
|
-
callback=strip_and_check_if_exists,
|
|
250
|
-
),
|
|
251
|
-
set_as_default: bool = typer.Option(
|
|
252
|
-
False,
|
|
253
|
-
"--default",
|
|
254
|
-
is_flag=True,
|
|
255
|
-
help="If provided the connection will be configured as default connection.",
|
|
256
|
-
),
|
|
257
|
-
**options,
|
|
258
|
-
) -> CommandResult:
|
|
259
|
-
"""Adds a connection to configuration file."""
|
|
260
|
-
if connection_exists(connection_name):
|
|
261
|
-
raise ClickException(f"Connection {connection_name} already exists")
|
|
262
|
-
|
|
263
|
-
connections_file = add_connection_to_proper_file(
|
|
264
|
-
connection_name,
|
|
265
|
-
ConnectionConfig(
|
|
266
|
-
account=account,
|
|
267
|
-
user=user,
|
|
268
|
-
password=password,
|
|
269
|
-
host=host,
|
|
270
|
-
region=region,
|
|
271
|
-
port=port,
|
|
272
|
-
database=database,
|
|
273
|
-
schema=schema,
|
|
274
|
-
warehouse=warehouse,
|
|
275
|
-
role=role,
|
|
276
|
-
authenticator=authenticator,
|
|
277
|
-
private_key_file=private_key_file,
|
|
278
|
-
token_file_path=token_file_path,
|
|
279
|
-
),
|
|
280
|
-
)
|
|
281
|
-
if set_as_default:
|
|
282
|
-
set_config_value(
|
|
283
|
-
section=None, key="default_connection_name", value=connection_name
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
return MessageResult(
|
|
287
|
-
f"Wrote new connection {connection_name} to {connections_file}"
|
|
288
|
-
)
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
@app.command(requires_connection=True)
|
|
292
|
-
def test(
|
|
293
|
-
**options,
|
|
294
|
-
) -> CommandResult:
|
|
295
|
-
"""
|
|
296
|
-
Tests the connection to Snowflake.
|
|
297
|
-
"""
|
|
298
|
-
|
|
299
|
-
# Test connection
|
|
300
|
-
cli_context = get_cli_context()
|
|
301
|
-
conn = cli_context.connection
|
|
302
|
-
|
|
303
|
-
# Test session attributes
|
|
304
|
-
om = ObjectManager()
|
|
305
|
-
try:
|
|
306
|
-
# "use database" operation changes schema to default "public",
|
|
307
|
-
# so to test schema set up by user we need to copy it here:
|
|
308
|
-
schema = conn.schema
|
|
309
|
-
|
|
310
|
-
if conn.role:
|
|
311
|
-
om.use(object_type=ObjectType.ROLE, name=f'"{conn.role}"')
|
|
312
|
-
if conn.database:
|
|
313
|
-
om.use(object_type=ObjectType.DATABASE, name=f'"{conn.database}"')
|
|
314
|
-
if schema:
|
|
315
|
-
om.use(object_type=ObjectType.SCHEMA, name=f'"{schema}"')
|
|
316
|
-
if conn.warehouse:
|
|
317
|
-
om.use(object_type=ObjectType.WAREHOUSE, name=f'"{conn.warehouse}"')
|
|
318
|
-
|
|
319
|
-
except ProgrammingError as err:
|
|
320
|
-
raise ClickException(str(err))
|
|
321
|
-
|
|
322
|
-
conn_ctx = cli_context.connection_context
|
|
323
|
-
result = {
|
|
324
|
-
"Connection name": conn_ctx.connection_name,
|
|
325
|
-
"Status": "OK",
|
|
326
|
-
"Host": conn.host,
|
|
327
|
-
"Account": conn.account,
|
|
328
|
-
"User": conn.user,
|
|
329
|
-
"Role": f'{conn.role or "not set"}',
|
|
330
|
-
"Database": f'{conn.database or "not set"}',
|
|
331
|
-
"Warehouse": f'{conn.warehouse or "not set"}',
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
if conn_ctx.enable_diag:
|
|
335
|
-
result["Diag Report Location"] = os.path.join(
|
|
336
|
-
conn_ctx.diag_log_path, "SnowflakeConnectionTestReport.txt"
|
|
337
|
-
)
|
|
338
|
-
|
|
339
|
-
return ObjectResult(result)
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
@app.command(requires_connection=False)
|
|
343
|
-
def set_default(
|
|
344
|
-
name: str = typer.Argument(
|
|
345
|
-
help="Name of the connection, as defined in your `config.toml`",
|
|
346
|
-
show_default=False,
|
|
347
|
-
),
|
|
348
|
-
**options,
|
|
349
|
-
):
|
|
350
|
-
"""Changes default connection to provided value."""
|
|
351
|
-
get_connection_dict(connection_name=name)
|
|
352
|
-
set_config_value(section=None, key="default_connection_name", value=name)
|
|
353
|
-
return MessageResult(f"Default connection set to: {name}")
|
|
@@ -1,30 +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 snowflake.cli._plugins.connection import commands
|
|
16
|
-
from snowflake.cli.api.plugins.command import (
|
|
17
|
-
SNOWCLI_ROOT_COMMAND_PATH,
|
|
18
|
-
CommandSpec,
|
|
19
|
-
CommandType,
|
|
20
|
-
plugin_hook_impl,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@plugin_hook_impl
|
|
25
|
-
def command_spec():
|
|
26
|
-
return CommandSpec(
|
|
27
|
-
parent_command_path=SNOWCLI_ROOT_COMMAND_PATH,
|
|
28
|
-
command_type=CommandType.COMMAND_GROUP,
|
|
29
|
-
typer_instance=commands.app.create_instance(),
|
|
30
|
-
)
|
|
@@ -1,195 +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 logging
|
|
19
|
-
import os
|
|
20
|
-
from typing import Optional
|
|
21
|
-
|
|
22
|
-
from click.exceptions import ClickException
|
|
23
|
-
from snowflake.connector import SnowflakeConnection
|
|
24
|
-
from snowflake.connector.cursor import DictCursor
|
|
25
|
-
|
|
26
|
-
log = logging.getLogger(__name__)
|
|
27
|
-
|
|
28
|
-
REGIONLESS_QUERY = """
|
|
29
|
-
select value['value'] as REGIONLESS from table(flatten(
|
|
30
|
-
input => parse_json(SYSTEM$BOOTSTRAP_DATA_REQUEST()),
|
|
31
|
-
path => 'clientParamsInfo'
|
|
32
|
-
)) where value['name'] = 'UI_SNOWSIGHT_ENABLE_REGIONLESS_REDIRECT';
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
ALLOWLIST_QUERY = "SELECT SYSTEM$ALLOWLIST()"
|
|
36
|
-
SNOWFLAKE_DEPLOYMENT = "SNOWFLAKE_DEPLOYMENT"
|
|
37
|
-
LOCAL_DEPLOYMENT_REGION: str = "us-west-2"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class MissingConnectionAccountError(ClickException):
|
|
41
|
-
def __init__(self, conn: SnowflakeConnection):
|
|
42
|
-
super().__init__(
|
|
43
|
-
"Could not determine account by system call, configured account name, or configured host. Connection: "
|
|
44
|
-
+ repr(conn)
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class MissingConnectionRegionError(ClickException):
|
|
49
|
-
def __init__(self, host: str | None):
|
|
50
|
-
super().__init__(
|
|
51
|
-
f"The connection host ({host}) was missing or not in "
|
|
52
|
-
"the expected format "
|
|
53
|
-
"(<account>.<deployment>.snowflakecomputing.com)"
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def is_regionless_redirect(conn: SnowflakeConnection) -> bool:
|
|
58
|
-
"""
|
|
59
|
-
Determines if the deployment this connection refers to uses
|
|
60
|
-
regionless URLs in Snowsight (/orgname/account) or regional URLs
|
|
61
|
-
(/region/account). If we cannot determine the correct value we
|
|
62
|
-
assume it's regionless, as this is true for most production deployments.
|
|
63
|
-
"""
|
|
64
|
-
try:
|
|
65
|
-
*_, cursor = conn.execute_string(REGIONLESS_QUERY, cursor_class=DictCursor)
|
|
66
|
-
return cursor.fetchone()["REGIONLESS"].lower() == "true"
|
|
67
|
-
except:
|
|
68
|
-
log.warning(
|
|
69
|
-
"Cannot determine regionless redirect; assuming True.", exc_info=True
|
|
70
|
-
)
|
|
71
|
-
return True
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def get_host_region(host: str) -> str | None:
|
|
75
|
-
"""
|
|
76
|
-
Looks for hosts of form
|
|
77
|
-
<account>.[x.y.z].snowflakecomputing.com
|
|
78
|
-
Returns the three-part [region identifier] or None.
|
|
79
|
-
"""
|
|
80
|
-
host_parts = host.split(".")
|
|
81
|
-
if host_parts[-1] == "local":
|
|
82
|
-
return LOCAL_DEPLOYMENT_REGION
|
|
83
|
-
elif len(host_parts) == 6:
|
|
84
|
-
return ".".join(host_parts[1:4])
|
|
85
|
-
return None
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def guess_regioned_host_from_allowlist(conn: SnowflakeConnection) -> str | None:
|
|
89
|
-
"""
|
|
90
|
-
Use SYSTEM$ALLOWLIST to find a regioned host (<account>.x.y.z.snowflakecomputing.com)
|
|
91
|
-
that corresponds to the given Snowflake connection object.
|
|
92
|
-
"""
|
|
93
|
-
try:
|
|
94
|
-
*_, cursor = conn.execute_string(ALLOWLIST_QUERY, cursor_class=DictCursor)
|
|
95
|
-
allowlist_tuples = json.loads(cursor.fetchone()["SYSTEM$ALLOWLIST()"])
|
|
96
|
-
for t in allowlist_tuples:
|
|
97
|
-
if t["type"] == SNOWFLAKE_DEPLOYMENT:
|
|
98
|
-
if get_host_region(t["host"]) is not None:
|
|
99
|
-
return t["host"]
|
|
100
|
-
except:
|
|
101
|
-
log.warning(
|
|
102
|
-
"Could not call SYSTEM$ALLOWLIST; returning an empty guess.", exc_info=True
|
|
103
|
-
)
|
|
104
|
-
return None
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def get_region(conn: SnowflakeConnection) -> str:
|
|
108
|
-
"""
|
|
109
|
-
Get the region of the given connection, or raise MissingConnectionRegionError.
|
|
110
|
-
"""
|
|
111
|
-
if conn.host:
|
|
112
|
-
if region := get_host_region(conn.host):
|
|
113
|
-
return region
|
|
114
|
-
|
|
115
|
-
if host := guess_regioned_host_from_allowlist(conn):
|
|
116
|
-
if region := get_host_region(host):
|
|
117
|
-
return region
|
|
118
|
-
|
|
119
|
-
raise MissingConnectionRegionError(host or conn.host)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
def get_context(conn: SnowflakeConnection) -> str:
|
|
123
|
-
"""
|
|
124
|
-
Determines the first part of the path in a Snowsight URL.
|
|
125
|
-
This could be a region or it could be an organization, depending
|
|
126
|
-
on whether or not the underlying deployment uses regionless URLs.
|
|
127
|
-
"""
|
|
128
|
-
if is_regionless_redirect(conn):
|
|
129
|
-
*_, cursor = conn.execute_string(
|
|
130
|
-
f"select system$return_current_org_name()", cursor_class=DictCursor
|
|
131
|
-
)
|
|
132
|
-
return cursor.fetchone()["SYSTEM$RETURN_CURRENT_ORG_NAME()"]
|
|
133
|
-
|
|
134
|
-
return get_region(conn)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def get_account(conn: SnowflakeConnection) -> str:
|
|
138
|
-
"""
|
|
139
|
-
Determines the account that this connection refers to.
|
|
140
|
-
"""
|
|
141
|
-
try:
|
|
142
|
-
*_, cursor = conn.execute_string(
|
|
143
|
-
f"select current_account_name()", cursor_class=DictCursor
|
|
144
|
-
)
|
|
145
|
-
return cursor.fetchone()["CURRENT_ACCOUNT_NAME()"].lower()
|
|
146
|
-
except Exception as e:
|
|
147
|
-
# try to extract the account from the connection information
|
|
148
|
-
if conn.account:
|
|
149
|
-
return conn.account
|
|
150
|
-
|
|
151
|
-
if conn.host:
|
|
152
|
-
host_parts = conn.host.split(".")
|
|
153
|
-
return host_parts[0]
|
|
154
|
-
|
|
155
|
-
raise MissingConnectionAccountError(conn)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
def get_snowsight_host(conn: SnowflakeConnection) -> str:
|
|
159
|
-
try:
|
|
160
|
-
*_, cursor = conn.execute_string(
|
|
161
|
-
f"select system$get_snowsight_host()", cursor_class=DictCursor
|
|
162
|
-
)
|
|
163
|
-
return cursor.fetchone()["SYSTEM$GET_SNOWSIGHT_HOST()"]
|
|
164
|
-
except Exception as e:
|
|
165
|
-
# if we cannot determine the host, assume we're on prod
|
|
166
|
-
return "https://app.snowflake.com"
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
def make_snowsight_url(conn: SnowflakeConnection, path: str) -> str:
|
|
170
|
-
"""
|
|
171
|
-
Returns a URL on the correct Snowsight instance for the connected account.
|
|
172
|
-
The path that is passed in must already be properly URL-encoded, and
|
|
173
|
-
can optionally contain a hash/fragment (e.g. #).
|
|
174
|
-
|
|
175
|
-
See also identifier_for_url.
|
|
176
|
-
"""
|
|
177
|
-
snowsight_host = get_snowsight_host(conn)
|
|
178
|
-
deployment = get_context(conn)
|
|
179
|
-
account = get_account(conn)
|
|
180
|
-
path_with_slash = path if path.startswith("/") else f"/{path}"
|
|
181
|
-
return f"{snowsight_host}/{deployment}/{account}{path_with_slash}"
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
def strip_if_value_present(value: Optional[str]) -> Optional[str]:
|
|
185
|
-
return value.strip() if value else value
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def ensure_that_path_exist(path: Optional[str]) -> Optional[str]:
|
|
189
|
-
if path and not os.path.exists(path):
|
|
190
|
-
raise ClickException(f"Path {path} does not exist.")
|
|
191
|
-
return path
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def strip_and_check_if_exists(value: Optional[str]) -> Optional[str]:
|
|
195
|
-
return ensure_that_path_exist(strip_if_value_present(value))
|
|
@@ -1,13 +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.
|