snowflake-connector-python 3.16.0__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- snowflake/connector/__init__.py +96 -0
- snowflake/connector/_query_context_cache.py +276 -0
- snowflake/connector/_sql_util.py +48 -0
- snowflake/connector/_utils.py +70 -0
- snowflake/connector/arrow_context.py +203 -0
- snowflake/connector/auth/__init__.py +53 -0
- snowflake/connector/auth/_auth.py +586 -0
- snowflake/connector/auth/_http_server.py +220 -0
- snowflake/connector/auth/_oauth_base.py +400 -0
- snowflake/connector/auth/by_plugin.py +219 -0
- snowflake/connector/auth/default.py +36 -0
- snowflake/connector/auth/idtoken.py +72 -0
- snowflake/connector/auth/keypair.py +222 -0
- snowflake/connector/auth/no_auth.py +39 -0
- snowflake/connector/auth/oauth.py +49 -0
- snowflake/connector/auth/oauth_code.py +479 -0
- snowflake/connector/auth/oauth_credentials.py +66 -0
- snowflake/connector/auth/okta.py +335 -0
- snowflake/connector/auth/pat.py +39 -0
- snowflake/connector/auth/usrpwdmfa.py +69 -0
- snowflake/connector/auth/webbrowser.py +502 -0
- snowflake/connector/auth/workload_identity.py +94 -0
- snowflake/connector/azure_storage_client.py +276 -0
- snowflake/connector/backoff_policies.py +141 -0
- snowflake/connector/bind_upload_agent.py +89 -0
- snowflake/connector/cache.py +696 -0
- snowflake/connector/compat.py +127 -0
- snowflake/connector/config_manager.py +496 -0
- snowflake/connector/connection.py +2273 -0
- snowflake/connector/connection_diagnostic.py +776 -0
- snowflake/connector/constants.py +442 -0
- snowflake/connector/converter.py +785 -0
- snowflake/connector/converter_issue23517.py +87 -0
- snowflake/connector/converter_null.py +14 -0
- snowflake/connector/converter_snowsql.py +205 -0
- snowflake/connector/cursor.py +1951 -0
- snowflake/connector/dbapi.py +53 -0
- snowflake/connector/description.py +19 -0
- snowflake/connector/direct_file_operation_utils.py +88 -0
- snowflake/connector/encryption_util.py +220 -0
- snowflake/connector/errorcode.py +91 -0
- snowflake/connector/errors.py +615 -0
- snowflake/connector/externals_utils/__init__.py +0 -0
- snowflake/connector/externals_utils/externals_setup.py +27 -0
- snowflake/connector/feature.py +4 -0
- snowflake/connector/file_compression_type.py +118 -0
- snowflake/connector/file_lock.py +72 -0
- snowflake/connector/file_transfer_agent.py +1215 -0
- snowflake/connector/file_util.py +153 -0
- snowflake/connector/gcs_storage_client.py +474 -0
- snowflake/connector/gzip_decoder.py +85 -0
- snowflake/connector/local_storage_client.py +90 -0
- snowflake/connector/log_configuration.py +60 -0
- snowflake/connector/logging_utils/__init__.py +0 -0
- snowflake/connector/logging_utils/filters.py +72 -0
- snowflake/connector/nanoarrow_arrow_iterator.cp313-win_amd64.pyd +0 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +60 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +557 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +98 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +125 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +115 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +1005 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +127 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +47 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +83 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +97 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +72 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +73 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +30 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +45 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +71 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +56 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +75 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +46 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +95 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +57 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +36 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +34 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +36 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +346 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +145 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +101 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +127 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1908 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +215 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +125 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +55 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +148 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +162 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +97 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +239 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +210 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +84 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +84 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +206 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +118 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +162 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +898 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +190 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +3204 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3217 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3618 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +379 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +256 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +512 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +350 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +33273 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +397 -0
- snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +100 -0
- snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +49 -0
- snowflake/connector/network.py +1297 -0
- snowflake/connector/ocsp_asn1crypto.py +447 -0
- snowflake/connector/ocsp_snowflake.py +1883 -0
- snowflake/connector/options.py +131 -0
- snowflake/connector/pandas_tools.py +732 -0
- snowflake/connector/proxy.py +43 -0
- snowflake/connector/py.typed +0 -0
- snowflake/connector/result_batch.py +786 -0
- snowflake/connector/result_set.py +319 -0
- snowflake/connector/s3_storage_client.py +605 -0
- snowflake/connector/secret_detector.py +181 -0
- snowflake/connector/sf_dirs.py +64 -0
- snowflake/connector/sfbinaryformat.py +35 -0
- snowflake/connector/sfdatetime.py +345 -0
- snowflake/connector/snow_logging.py +144 -0
- snowflake/connector/sqlstate.py +9 -0
- snowflake/connector/ssd_internal_keys.py +30 -0
- snowflake/connector/ssl_wrap_socket.py +134 -0
- snowflake/connector/storage_client.py +478 -0
- snowflake/connector/telemetry.py +249 -0
- snowflake/connector/telemetry_oob.py +543 -0
- snowflake/connector/test_util.py +30 -0
- snowflake/connector/time_util.py +159 -0
- snowflake/connector/token_cache.py +402 -0
- snowflake/connector/tool/__init__.py +0 -0
- snowflake/connector/tool/dump_certs.py +57 -0
- snowflake/connector/tool/dump_ocsp_response.py +139 -0
- snowflake/connector/tool/dump_ocsp_response_cache.py +194 -0
- snowflake/connector/tool/probe_connection.py +69 -0
- snowflake/connector/url_util.py +49 -0
- snowflake/connector/util_text.py +301 -0
- snowflake/connector/vendored/__init__.py +3 -0
- snowflake/connector/vendored/requests/LICENSE +175 -0
- snowflake/connector/vendored/requests/__init__.py +169 -0
- snowflake/connector/vendored/requests/__version__.py +14 -0
- snowflake/connector/vendored/requests/_internal_utils.py +50 -0
- snowflake/connector/vendored/requests/adapters.py +537 -0
- snowflake/connector/vendored/requests/api.py +157 -0
- snowflake/connector/vendored/requests/auth.py +315 -0
- snowflake/connector/vendored/requests/certs.py +17 -0
- snowflake/connector/vendored/requests/compat.py +79 -0
- snowflake/connector/vendored/requests/cookies.py +561 -0
- snowflake/connector/vendored/requests/exceptions.py +140 -0
- snowflake/connector/vendored/requests/help.py +134 -0
- snowflake/connector/vendored/requests/hooks.py +33 -0
- snowflake/connector/vendored/requests/models.py +1033 -0
- snowflake/connector/vendored/requests/sessions.py +833 -0
- snowflake/connector/vendored/requests/status_codes.py +128 -0
- snowflake/connector/vendored/requests/structures.py +99 -0
- snowflake/connector/vendored/requests/utils.py +1093 -0
- snowflake/connector/vendored/urllib3/LICENSE.txt +21 -0
- snowflake/connector/vendored/urllib3/__init__.py +85 -0
- snowflake/connector/vendored/urllib3/_collections.py +355 -0
- snowflake/connector/vendored/urllib3/_version.py +2 -0
- snowflake/connector/vendored/urllib3/connection.py +572 -0
- snowflake/connector/vendored/urllib3/connectionpool.py +1137 -0
- snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/contrib/_appengine_environ.py +36 -0
- snowflake/connector/vendored/urllib3/contrib/_securetransport/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/contrib/_securetransport/bindings.py +519 -0
- snowflake/connector/vendored/urllib3/contrib/_securetransport/low_level.py +397 -0
- snowflake/connector/vendored/urllib3/contrib/appengine.py +314 -0
- snowflake/connector/vendored/urllib3/contrib/ntlmpool.py +130 -0
- snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +509 -0
- snowflake/connector/vendored/urllib3/contrib/securetransport.py +920 -0
- snowflake/connector/vendored/urllib3/contrib/socks.py +216 -0
- snowflake/connector/vendored/urllib3/exceptions.py +323 -0
- snowflake/connector/vendored/urllib3/fields.py +274 -0
- snowflake/connector/vendored/urllib3/filepost.py +98 -0
- snowflake/connector/vendored/urllib3/packages/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/packages/backports/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/packages/backports/makefile.py +51 -0
- snowflake/connector/vendored/urllib3/packages/backports/weakref_finalize.py +155 -0
- snowflake/connector/vendored/urllib3/packages/six.py +1076 -0
- snowflake/connector/vendored/urllib3/poolmanager.py +540 -0
- snowflake/connector/vendored/urllib3/request.py +191 -0
- snowflake/connector/vendored/urllib3/response.py +885 -0
- snowflake/connector/vendored/urllib3/util/__init__.py +49 -0
- snowflake/connector/vendored/urllib3/util/connection.py +156 -0
- snowflake/connector/vendored/urllib3/util/proxy.py +57 -0
- snowflake/connector/vendored/urllib3/util/queue.py +22 -0
- snowflake/connector/vendored/urllib3/util/request.py +146 -0
- snowflake/connector/vendored/urllib3/util/response.py +107 -0
- snowflake/connector/vendored/urllib3/util/retry.py +620 -0
- snowflake/connector/vendored/urllib3/util/ssl_.py +495 -0
- snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +159 -0
- snowflake/connector/vendored/urllib3/util/ssltransport.py +221 -0
- snowflake/connector/vendored/urllib3/util/timeout.py +271 -0
- snowflake/connector/vendored/urllib3/util/url.py +435 -0
- snowflake/connector/vendored/urllib3/util/wait.py +152 -0
- snowflake/connector/version.py +3 -0
- snowflake/connector/wif_util.py +407 -0
- snowflake_connector_python-3.16.0.dist-info/METADATA +1475 -0
- snowflake_connector_python-3.16.0.dist-info/RECORD +246 -0
- snowflake_connector_python-3.16.0.dist-info/WHEEL +5 -0
- snowflake_connector_python-3.16.0.dist-info/entry_points.txt +4 -0
- snowflake_connector_python-3.16.0.dist-info/licenses/LICENSE.txt +202 -0
- snowflake_connector_python-3.16.0.dist-info/licenses/NOTICE +8 -0
- snowflake_connector_python-3.16.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""This module implements some constructors and singletons as required by the DB API v2.0 (PEP-249)."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import datetime
|
|
7
|
+
import time
|
|
8
|
+
|
|
9
|
+
from .constants import (
|
|
10
|
+
get_binary_types,
|
|
11
|
+
get_number_types,
|
|
12
|
+
get_string_types,
|
|
13
|
+
get_timestamp_types,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class _DBAPITypeObject:
|
|
18
|
+
def __init__(self, *values) -> None:
|
|
19
|
+
self.values = values
|
|
20
|
+
|
|
21
|
+
def __cmp__(self, other):
|
|
22
|
+
if other in self.values:
|
|
23
|
+
return 0
|
|
24
|
+
if other < self.values:
|
|
25
|
+
return 1
|
|
26
|
+
else:
|
|
27
|
+
return -1
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
Date = datetime.date
|
|
31
|
+
Time = datetime.time
|
|
32
|
+
Timestamp = datetime.datetime
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def DateFromTicks(ticks: float) -> datetime.date:
|
|
36
|
+
return Date(*time.localtime(ticks)[:3])
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def TimeFromTicks(ticks: float) -> datetime.time:
|
|
40
|
+
return Time(*time.localtime(ticks)[3:6])
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def TimestampFromTicks(ticks: float) -> datetime.datetime:
|
|
44
|
+
return Timestamp(*time.localtime(ticks)[:6])
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
Binary = bytes
|
|
48
|
+
|
|
49
|
+
STRING = _DBAPITypeObject(get_string_types())
|
|
50
|
+
BINARY = _DBAPITypeObject(get_binary_types())
|
|
51
|
+
NUMBER = _DBAPITypeObject(get_number_types())
|
|
52
|
+
DATETIME = _DBAPITypeObject(get_timestamp_types())
|
|
53
|
+
ROWID = _DBAPITypeObject()
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Various constants."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import platform
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
from .version import VERSION
|
|
10
|
+
|
|
11
|
+
SNOWFLAKE_CONNECTOR_VERSION = ".".join(str(v) for v in VERSION[0:3])
|
|
12
|
+
PYTHON_VERSION = ".".join(str(v) for v in sys.version_info[:3])
|
|
13
|
+
OPERATING_SYSTEM = platform.system()
|
|
14
|
+
PLATFORM = platform.platform()
|
|
15
|
+
IMPLEMENTATION = platform.python_implementation()
|
|
16
|
+
COMPILER = platform.python_compiler()
|
|
17
|
+
|
|
18
|
+
CLIENT_NAME = "PythonConnector" # don't change!
|
|
19
|
+
CLIENT_VERSION = ".".join([str(v) for v in VERSION[:3]])
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from .connection import SnowflakeConnection
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
10
|
+
|
|
11
|
+
from .constants import CMD_TYPE_UPLOAD
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class FileOperationParserBase(ABC):
|
|
15
|
+
"""The interface of internal utility functions for file operation parsing."""
|
|
16
|
+
|
|
17
|
+
@abstractmethod
|
|
18
|
+
def __init__(self, connection):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
@abstractmethod
|
|
22
|
+
def parse_file_operation(
|
|
23
|
+
self,
|
|
24
|
+
stage_location,
|
|
25
|
+
local_file_name,
|
|
26
|
+
target_directory,
|
|
27
|
+
command_type,
|
|
28
|
+
options,
|
|
29
|
+
has_source_from_stream=False,
|
|
30
|
+
):
|
|
31
|
+
"""Converts the file operation details into a SQL and returns the SQL parsing result."""
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class StreamDownloaderBase(ABC):
|
|
36
|
+
"""The interface of internal utility functions for stream downloading of file."""
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def __init__(self, connection):
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
@abstractmethod
|
|
43
|
+
def download_as_stream(self, ret, decompress=False):
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class FileOperationParser(FileOperationParserBase):
|
|
48
|
+
def __init__(self, connection: SnowflakeConnection):
|
|
49
|
+
self._connection = connection
|
|
50
|
+
|
|
51
|
+
def parse_file_operation(
|
|
52
|
+
self,
|
|
53
|
+
stage_location,
|
|
54
|
+
local_file_name,
|
|
55
|
+
target_directory,
|
|
56
|
+
command_type,
|
|
57
|
+
options,
|
|
58
|
+
has_source_from_stream=False,
|
|
59
|
+
):
|
|
60
|
+
"""Parses a file operation by constructing SQL and getting the SQL parsing result from server."""
|
|
61
|
+
options = options or {}
|
|
62
|
+
options_in_sql = " ".join(f"{k}={v}" for k, v in options.items())
|
|
63
|
+
|
|
64
|
+
if command_type == CMD_TYPE_UPLOAD:
|
|
65
|
+
if has_source_from_stream:
|
|
66
|
+
stage_location, unprefixed_local_file_name = os.path.split(
|
|
67
|
+
stage_location
|
|
68
|
+
)
|
|
69
|
+
local_file_name = "file://" + unprefixed_local_file_name
|
|
70
|
+
sql = f"PUT {local_file_name} ? {options_in_sql}"
|
|
71
|
+
params = [stage_location]
|
|
72
|
+
else:
|
|
73
|
+
raise NotImplementedError(f"unsupported command type: {command_type}")
|
|
74
|
+
|
|
75
|
+
with self._connection.cursor() as cursor:
|
|
76
|
+
# Send constructed SQL to server and get back parsing result.
|
|
77
|
+
processed_params = cursor._connection._process_params_qmarks(params, cursor)
|
|
78
|
+
return cursor._execute_helper(
|
|
79
|
+
sql, binding_params=processed_params, is_internal=True
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class StreamDownloader(StreamDownloaderBase):
|
|
84
|
+
def __init__(self, connection):
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
def download_as_stream(self, ret, decompress=False):
|
|
88
|
+
raise NotImplementedError("download_as_stream is not yet supported")
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import base64
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import tempfile
|
|
8
|
+
from logging import getLogger
|
|
9
|
+
from typing import IO, TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
from cryptography.hazmat.backends import default_backend
|
|
12
|
+
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
13
|
+
|
|
14
|
+
from .compat import PKCS5_OFFSET, PKCS5_PAD, PKCS5_UNPAD
|
|
15
|
+
from .constants import UTF8, EncryptionMetadata, MaterialDescriptor, kilobyte
|
|
16
|
+
from .file_util import owner_rw_opener
|
|
17
|
+
from .util_text import random_string
|
|
18
|
+
|
|
19
|
+
block_size = int(algorithms.AES.block_size / 8) # in bytes
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
22
|
+
from .storage_client import SnowflakeFileEncryptionMaterial
|
|
23
|
+
|
|
24
|
+
logger = getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def matdesc_to_unicode(matdesc: MaterialDescriptor) -> str:
|
|
28
|
+
"""Convert Material Descriptor to Unicode String."""
|
|
29
|
+
return str(
|
|
30
|
+
json.dumps(
|
|
31
|
+
{
|
|
32
|
+
"queryId": matdesc.query_id,
|
|
33
|
+
"smkId": str(matdesc.smk_id),
|
|
34
|
+
"keySize": str(matdesc.key_size),
|
|
35
|
+
},
|
|
36
|
+
separators=(",", ":"),
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class SnowflakeEncryptionUtil:
|
|
42
|
+
@staticmethod
|
|
43
|
+
def get_secure_random(byte_length: int) -> bytes:
|
|
44
|
+
return os.urandom(byte_length)
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def encrypt_stream(
|
|
48
|
+
encryption_material: SnowflakeFileEncryptionMaterial,
|
|
49
|
+
src: IO[bytes],
|
|
50
|
+
out: IO[bytes],
|
|
51
|
+
chunk_size: int = 64 * kilobyte, # block_size * 4 * 1024,
|
|
52
|
+
) -> EncryptionMetadata:
|
|
53
|
+
"""Reads content from src and write the encrypted content into out.
|
|
54
|
+
|
|
55
|
+
This function is sensitive to current position of src and out.
|
|
56
|
+
It does not seek to position 0 in neither stream objects before or after the encryption.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
encryption_material: The encryption material for file.
|
|
60
|
+
src: The input stream.
|
|
61
|
+
out: The output stream.
|
|
62
|
+
chunk_size: The size of read chunks (Default value = block_size * 4 * 1024
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
The encryption metadata.
|
|
66
|
+
"""
|
|
67
|
+
logger = getLogger(__name__)
|
|
68
|
+
decoded_key = base64.standard_b64decode(
|
|
69
|
+
encryption_material.query_stage_master_key
|
|
70
|
+
)
|
|
71
|
+
key_size = len(decoded_key)
|
|
72
|
+
logger.debug("key_size = %s", key_size)
|
|
73
|
+
|
|
74
|
+
# Generate key for data encryption
|
|
75
|
+
iv_data = SnowflakeEncryptionUtil.get_secure_random(block_size)
|
|
76
|
+
file_key = SnowflakeEncryptionUtil.get_secure_random(key_size)
|
|
77
|
+
backend = default_backend()
|
|
78
|
+
cipher = Cipher(algorithms.AES(file_key), modes.CBC(iv_data), backend=backend)
|
|
79
|
+
encryptor = cipher.encryptor()
|
|
80
|
+
|
|
81
|
+
padded = False
|
|
82
|
+
while True:
|
|
83
|
+
chunk = src.read(chunk_size)
|
|
84
|
+
if len(chunk) == 0:
|
|
85
|
+
break
|
|
86
|
+
elif len(chunk) % block_size != 0:
|
|
87
|
+
chunk = PKCS5_PAD(chunk, block_size)
|
|
88
|
+
padded = True
|
|
89
|
+
out.write(encryptor.update(chunk))
|
|
90
|
+
if not padded:
|
|
91
|
+
out.write(encryptor.update(block_size * chr(block_size).encode(UTF8)))
|
|
92
|
+
out.write(encryptor.finalize())
|
|
93
|
+
|
|
94
|
+
# encrypt key with QRMK
|
|
95
|
+
cipher = Cipher(algorithms.AES(decoded_key), modes.ECB(), backend=backend)
|
|
96
|
+
encryptor = cipher.encryptor()
|
|
97
|
+
enc_kek = (
|
|
98
|
+
encryptor.update(PKCS5_PAD(file_key, block_size)) + encryptor.finalize()
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
mat_desc = MaterialDescriptor(
|
|
102
|
+
smk_id=encryption_material.smk_id,
|
|
103
|
+
query_id=encryption_material.query_id,
|
|
104
|
+
key_size=key_size * 8,
|
|
105
|
+
)
|
|
106
|
+
metadata = EncryptionMetadata(
|
|
107
|
+
key=base64.b64encode(enc_kek).decode("utf-8"),
|
|
108
|
+
iv=base64.b64encode(iv_data).decode("utf-8"),
|
|
109
|
+
matdesc=matdesc_to_unicode(mat_desc),
|
|
110
|
+
)
|
|
111
|
+
return metadata
|
|
112
|
+
|
|
113
|
+
@staticmethod
|
|
114
|
+
def encrypt_file(
|
|
115
|
+
encryption_material: SnowflakeFileEncryptionMaterial,
|
|
116
|
+
in_filename: str,
|
|
117
|
+
chunk_size: int = 64 * kilobyte,
|
|
118
|
+
tmp_dir: str | None = None,
|
|
119
|
+
) -> tuple[EncryptionMetadata, str]:
|
|
120
|
+
"""Encrypts a file in a temporary directory.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
encryption_material: The encryption material for file.
|
|
124
|
+
in_filename: The input file's name.
|
|
125
|
+
chunk_size: The size of read chunks (Default value = block_size * 4 * 1024).
|
|
126
|
+
tmp_dir: Temporary directory to use, optional (Default value = None).
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
The encryption metadata and the encrypted file's location.
|
|
130
|
+
"""
|
|
131
|
+
logger = getLogger(__name__)
|
|
132
|
+
temp_output_fd, temp_output_file = tempfile.mkstemp(
|
|
133
|
+
text=False, dir=tmp_dir, prefix=os.path.basename(in_filename) + "#"
|
|
134
|
+
)
|
|
135
|
+
logger.debug(
|
|
136
|
+
"unencrypted file: %s, temp file: %s, tmp_dir: %s",
|
|
137
|
+
in_filename,
|
|
138
|
+
temp_output_file,
|
|
139
|
+
tmp_dir,
|
|
140
|
+
)
|
|
141
|
+
with open(in_filename, "rb") as infile:
|
|
142
|
+
with os.fdopen(temp_output_fd, "wb") as outfile:
|
|
143
|
+
metadata = SnowflakeEncryptionUtil.encrypt_stream(
|
|
144
|
+
encryption_material, infile, outfile, chunk_size
|
|
145
|
+
)
|
|
146
|
+
return metadata, temp_output_file
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def decrypt_stream(
|
|
150
|
+
metadata: EncryptionMetadata,
|
|
151
|
+
encryption_material: SnowflakeFileEncryptionMaterial,
|
|
152
|
+
src: IO[bytes],
|
|
153
|
+
out: IO[bytes],
|
|
154
|
+
chunk_size: int = 64 * kilobyte, # block_size * 4 * 1024,
|
|
155
|
+
) -> None:
|
|
156
|
+
"""To read from `src` stream then decrypt to `out` stream."""
|
|
157
|
+
|
|
158
|
+
key_base64 = metadata.key
|
|
159
|
+
iv_base64 = metadata.iv
|
|
160
|
+
decoded_key = base64.standard_b64decode(
|
|
161
|
+
encryption_material.query_stage_master_key
|
|
162
|
+
)
|
|
163
|
+
key_bytes = base64.standard_b64decode(key_base64)
|
|
164
|
+
iv_bytes = base64.standard_b64decode(iv_base64)
|
|
165
|
+
|
|
166
|
+
backend = default_backend()
|
|
167
|
+
cipher = Cipher(algorithms.AES(decoded_key), modes.ECB(), backend=backend)
|
|
168
|
+
decryptor = cipher.decryptor()
|
|
169
|
+
file_key = PKCS5_UNPAD(decryptor.update(key_bytes) + decryptor.finalize())
|
|
170
|
+
cipher = Cipher(algorithms.AES(file_key), modes.CBC(iv_bytes), backend=backend)
|
|
171
|
+
decryptor = cipher.decryptor()
|
|
172
|
+
|
|
173
|
+
last_decrypted_chunk = None
|
|
174
|
+
chunk = src.read(chunk_size)
|
|
175
|
+
while len(chunk) != 0:
|
|
176
|
+
if last_decrypted_chunk is not None:
|
|
177
|
+
out.write(last_decrypted_chunk)
|
|
178
|
+
d = decryptor.update(chunk)
|
|
179
|
+
last_decrypted_chunk = d
|
|
180
|
+
chunk = src.read(chunk_size)
|
|
181
|
+
|
|
182
|
+
if last_decrypted_chunk is not None:
|
|
183
|
+
offset = PKCS5_OFFSET(last_decrypted_chunk)
|
|
184
|
+
out.write(last_decrypted_chunk[:-offset])
|
|
185
|
+
out.write(decryptor.finalize())
|
|
186
|
+
|
|
187
|
+
@staticmethod
|
|
188
|
+
def decrypt_file(
|
|
189
|
+
metadata: EncryptionMetadata,
|
|
190
|
+
encryption_material: SnowflakeFileEncryptionMaterial,
|
|
191
|
+
in_filename: str,
|
|
192
|
+
chunk_size: int = 64 * kilobyte,
|
|
193
|
+
tmp_dir: str | None = None,
|
|
194
|
+
unsafe_file_write: bool = False,
|
|
195
|
+
) -> str:
|
|
196
|
+
"""Decrypts a file and stores the output in the temporary directory.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
metadata: The file's metadata input.
|
|
200
|
+
encryption_material: The file's encryption material.
|
|
201
|
+
in_filename: The name of the input file.
|
|
202
|
+
chunk_size: The size of read chunks (Default value = block_size * 4 * 1024).
|
|
203
|
+
tmp_dir: Temporary directory to use, optional (Default value = None).
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
The decrypted file's location.
|
|
207
|
+
"""
|
|
208
|
+
temp_output_file = f"{os.path.basename(in_filename)}#{random_string()}"
|
|
209
|
+
if tmp_dir:
|
|
210
|
+
temp_output_file = os.path.join(tmp_dir, temp_output_file)
|
|
211
|
+
|
|
212
|
+
logger.debug("encrypted file: %s, tmp file: %s", in_filename, temp_output_file)
|
|
213
|
+
|
|
214
|
+
file_opener = None if unsafe_file_write else owner_rw_opener
|
|
215
|
+
with open(in_filename, "rb") as infile:
|
|
216
|
+
with open(temp_output_file, "wb", opener=file_opener) as outfile:
|
|
217
|
+
SnowflakeEncryptionUtil.decrypt_stream(
|
|
218
|
+
metadata, encryption_material, infile, outfile, chunk_size
|
|
219
|
+
)
|
|
220
|
+
return temp_output_file
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
# network
|
|
5
|
+
ER_FAILED_TO_CONNECT_TO_DB = 250001
|
|
6
|
+
ER_CONNECTION_IS_CLOSED = 250002
|
|
7
|
+
ER_FAILED_TO_REQUEST = 250003
|
|
8
|
+
ER_NOT_HTTPS_USED = 250004
|
|
9
|
+
ER_FAILED_TO_SERVER = 250005
|
|
10
|
+
ER_IDP_CONNECTION_ERROR = 250006
|
|
11
|
+
ER_INCORRECT_DESTINATION = 250007
|
|
12
|
+
ER_UNABLE_TO_OPEN_BROWSER = 250008
|
|
13
|
+
ER_UNABLE_TO_START_WEBSERVER = 250009
|
|
14
|
+
ER_INVALID_CERTIFICATE = 250011 # not used but keep here to reserve errno
|
|
15
|
+
ER_INVALID_BACKOFF_POLICY = 250012
|
|
16
|
+
|
|
17
|
+
# connection
|
|
18
|
+
ER_NO_ACCOUNT_NAME = 251001
|
|
19
|
+
ER_OLD_PYTHON = 251002
|
|
20
|
+
ER_NO_WINDOWS_SUPPORT = 251003
|
|
21
|
+
ER_FAILED_TO_GET_BOOTSTRAP = 251004
|
|
22
|
+
ER_NO_USER = 251005
|
|
23
|
+
ER_NO_PASSWORD = 251006
|
|
24
|
+
ER_INVALID_VALUE = 251007
|
|
25
|
+
ER_INVALID_PRIVATE_KEY = 251008
|
|
26
|
+
ER_NO_HOSTNAME_FOUND = 251009
|
|
27
|
+
ER_JWT_RETRY_EXPIRED = 251010
|
|
28
|
+
ER_CONNECTION_TIMEOUT = 251011
|
|
29
|
+
ER_RETRYABLE_CODE = 251012
|
|
30
|
+
ER_NO_CLIENT_ID = 251013
|
|
31
|
+
ER_OAUTH_STATE_CHANGED = 251014
|
|
32
|
+
ER_OAUTH_CALLBACK_ERROR = 251015
|
|
33
|
+
ER_OAUTH_SERVER_TIMEOUT = 251016
|
|
34
|
+
ER_INVALID_WIF_SETTINGS = 251017
|
|
35
|
+
ER_WIF_CREDENTIALS_NOT_FOUND = 251018
|
|
36
|
+
ER_EXPERIMENTAL_AUTHENTICATION_NOT_SUPPORTED = 251019
|
|
37
|
+
ER_NO_CLIENT_SECRET = 251020
|
|
38
|
+
|
|
39
|
+
# cursor
|
|
40
|
+
ER_FAILED_TO_REWRITE_MULTI_ROW_INSERT = 252001
|
|
41
|
+
ER_NO_ADDITIONAL_CHUNK = 252002
|
|
42
|
+
ER_NOT_POSITIVE_SIZE = 252003
|
|
43
|
+
ER_FAILED_PROCESSING_PYFORMAT = 252004
|
|
44
|
+
ER_FAILED_TO_CONVERT_ROW_TO_PYTHON_TYPE = 252005
|
|
45
|
+
ER_CURSOR_IS_CLOSED = 252006
|
|
46
|
+
ER_FAILED_TO_RENEW_SESSION = 252007
|
|
47
|
+
ER_UNSUPPORTED_METHOD = 252008
|
|
48
|
+
ER_NO_DATA_FOUND = 252009
|
|
49
|
+
ER_CHUNK_DOWNLOAD_FAILED = 252010
|
|
50
|
+
ER_NOT_IMPLICITY_SNOWFLAKE_DATATYPE = 252011
|
|
51
|
+
ER_FAILED_PROCESSING_QMARK = 252012
|
|
52
|
+
|
|
53
|
+
# file_transfer
|
|
54
|
+
ER_INVALID_STAGE_FS = 253001
|
|
55
|
+
ER_FAILED_TO_DOWNLOAD_FROM_STAGE = 253002
|
|
56
|
+
ER_FAILED_TO_UPLOAD_TO_STAGE = 253003
|
|
57
|
+
ER_INVALID_STAGE_LOCATION = 253004
|
|
58
|
+
ER_LOCAL_PATH_NOT_DIRECTORY = 253005
|
|
59
|
+
ER_FILE_NOT_EXISTS = 253006
|
|
60
|
+
ER_COMPRESSION_NOT_SUPPORTED = 253007
|
|
61
|
+
ER_INTERNAL_NOT_MATCH_ENCRYPT_MATERIAL = 253008
|
|
62
|
+
ER_FAILED_TO_CHECK_EXISTING_FILES = 253009
|
|
63
|
+
|
|
64
|
+
# ocsp
|
|
65
|
+
ER_OCSP_URL_INFO_MISSING = 254001
|
|
66
|
+
ER_OCSP_RESPONSE_UNAVAILABLE = 254002
|
|
67
|
+
ER_OCSP_RESPONSE_FETCH_EXCEPTION = 254003
|
|
68
|
+
ER_OCSP_FAILED_TO_CONNECT_CACHE_SERVER = 254004
|
|
69
|
+
ER_OCSP_RESPONSE_CERT_STATUS_INVALID = 254005
|
|
70
|
+
ER_OCSP_RESPONSE_CERT_STATUS_UNKNOWN = 254006
|
|
71
|
+
ER_OCSP_RESPONSE_CERT_STATUS_REVOKED = 254007
|
|
72
|
+
ER_OCSP_RESPONSE_STATUS_UNSUCCESSFUL = 254008
|
|
73
|
+
ER_OCSP_RESPONSE_ATTACHED_CERT_INVALID = 254009
|
|
74
|
+
ER_OCSP_RESPONSE_ATTACHED_CERT_EXPIRED = 254010
|
|
75
|
+
ER_OCSP_RESPONSE_INVALID_SIGNATURE = 254011
|
|
76
|
+
ER_OCSP_RESPONSE_INVALID_EXPIRY_INFO_MISSING = 254012
|
|
77
|
+
ER_OCSP_RESPONSE_EXPIRED = 254013
|
|
78
|
+
ER_OCSP_RESPONSE_FETCH_FAILURE = 254014
|
|
79
|
+
ER_OCSP_RESPONSE_LOAD_FAILURE = 254015
|
|
80
|
+
ER_OCSP_RESPONSE_CACHE_DOWNLOAD_FAILED = 254016
|
|
81
|
+
ER_OCSP_RESPONSE_CACHE_DECODE_FAILED = 254017
|
|
82
|
+
ER_INVALID_OCSP_RESPONSE_SSD = 254018
|
|
83
|
+
ER_INVALID_SSD = 254019
|
|
84
|
+
|
|
85
|
+
# converter
|
|
86
|
+
ER_NOT_SUPPORT_DATA_TYPE = 255001
|
|
87
|
+
ER_NO_PYARROW = 255002
|
|
88
|
+
ER_NO_ARROW_RESULT = 255003
|
|
89
|
+
ER_NO_PYARROW_SNOWSQL = 255004
|
|
90
|
+
ER_FAILED_TO_READ_ARROW_STREAM = 255005
|
|
91
|
+
ER_NO_NUMPY = 255006
|