snowflake-connector-python 5.2.0__cp315-cp315-macosx_11_0_arm64.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.
Files changed (202) hide show
  1. snowflake/connector/__init__.py +136 -0
  2. snowflake/connector/_common/__init__.py +0 -0
  3. snowflake/connector/_common/extras.py +134 -0
  4. snowflake/connector/_common/telemetry.py +221 -0
  5. snowflake/connector/_common/wif_util.py +92 -0
  6. snowflake/connector/_core/sf_core_python.cpython-315-darwin.so +0 -0
  7. snowflake/connector/_core/sf_core_python.pyi +79 -0
  8. snowflake/connector/_internal/__init__.py +6 -0
  9. snowflake/connector/_internal/_private_key_helper.py +31 -0
  10. snowflake/connector/_internal/api_client/__init__.py +93 -0
  11. snowflake/connector/_internal/api_client/bridge.py +41 -0
  12. snowflake/connector/_internal/api_client/client_api.py +976 -0
  13. snowflake/connector/_internal/arrow.py +47 -0
  14. snowflake/connector/_internal/arrow_context.py +240 -0
  15. snowflake/connector/_internal/arrow_stream_async.py +266 -0
  16. snowflake/connector/_internal/arrow_stream_iterator.cpython-311-darwin.so +0 -0
  17. snowflake/connector/_internal/arrow_stream_iterator.cpython-312-darwin.so +0 -0
  18. snowflake/connector/_internal/arrow_stream_iterator.cpython-313-darwin.so +0 -0
  19. snowflake/connector/_internal/arrow_stream_iterator.cpython-314-darwin.so +0 -0
  20. snowflake/connector/_internal/arrow_stream_iterator.cpython-314t-darwin.so +0 -0
  21. snowflake/connector/_internal/arrow_stream_iterator.cpython-315-darwin.so +0 -0
  22. snowflake/connector/_internal/arrow_stream_iterator.pyi +42 -0
  23. snowflake/connector/_internal/arrow_stream_utils.py +171 -0
  24. snowflake/connector/_internal/authenticator_type.py +53 -0
  25. snowflake/connector/_internal/backward_compatibility.py +245 -0
  26. snowflake/connector/_internal/binding_converters.py +741 -0
  27. snowflake/connector/_internal/config_utils.py +71 -0
  28. snowflake/connector/_internal/connection/__init__.py +39 -0
  29. snowflake/connector/_internal/connection/connection.py +616 -0
  30. snowflake/connector/_internal/connection/connection_types.py +13 -0
  31. snowflake/connector/_internal/connection/constants.py +25 -0
  32. snowflake/connector/_internal/connection/decorators.py +31 -0
  33. snowflake/connector/_internal/connection/freezable_proxy.py +104 -0
  34. snowflake/connector/_internal/connection/queries.py +10 -0
  35. snowflake/connector/_internal/connection_config_mixin.py +755 -0
  36. snowflake/connector/_internal/cursor/__init__.py +25 -0
  37. snowflake/connector/_internal/cursor/base.py +732 -0
  38. snowflake/connector/_internal/cursor/cursor_types.py +13 -0
  39. snowflake/connector/_internal/cursor/decorators.py +56 -0
  40. snowflake/connector/_internal/cursor/query_result.py +202 -0
  41. snowflake/connector/_internal/cursor/query_result_waiter.py +98 -0
  42. snowflake/connector/_internal/cursor/result_metadata.py +255 -0
  43. snowflake/connector/_internal/cursor/result_set_wrapper.py +66 -0
  44. snowflake/connector/_internal/decorators.py +539 -0
  45. snowflake/connector/_internal/error_kinds.py +111 -0
  46. snowflake/connector/_internal/errorcode.py +35 -0
  47. snowflake/connector/_internal/errorhandler.py +278 -0
  48. snowflake/connector/_internal/fips.py +28 -0
  49. snowflake/connector/_internal/logging/__init__.py +52 -0
  50. snowflake/connector/_internal/logging/config.py +134 -0
  51. snowflake/connector/_internal/logging/core_logger.py +218 -0
  52. snowflake/connector/_internal/logging/native_extension_logger.py +144 -0
  53. snowflake/connector/_internal/logout_config_mapping.py +187 -0
  54. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +57 -0
  55. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
  56. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.cpp +943 -0
  57. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.hpp +63 -0
  58. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +18 -0
  59. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
  60. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
  61. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
  62. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +118 -0
  63. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +116 -0
  64. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.cpp +323 -0
  65. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.hpp +133 -0
  66. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.cpp +275 -0
  67. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.hpp +168 -0
  68. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.cpp +439 -0
  69. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.hpp +30 -0
  70. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +48 -0
  71. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
  72. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +76 -0
  73. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
  74. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +90 -0
  75. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +63 -0
  76. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +62 -0
  77. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
  78. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +29 -0
  79. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
  80. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
  81. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
  82. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +41 -0
  83. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +65 -0
  84. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +54 -0
  85. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
  86. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +79 -0
  87. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
  88. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +52 -0
  89. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
  90. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
  91. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +117 -0
  92. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +54 -0
  93. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +34 -0
  94. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +33 -0
  95. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
  96. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +18 -0
  97. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
  98. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +39 -0
  99. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
  100. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +326 -0
  101. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +138 -0
  102. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
  103. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
  104. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
  105. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.cpp +13286 -0
  106. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.pyx +204 -0
  107. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +109 -0
  108. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +125 -0
  109. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
  110. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1914 -0
  111. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +208 -0
  112. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +128 -0
  113. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
  114. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +58 -0
  115. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +144 -0
  116. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
  117. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
  118. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
  119. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +160 -0
  120. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +98 -0
  121. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +243 -0
  122. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
  123. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +207 -0
  124. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +80 -0
  125. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +83 -0
  126. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
  127. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
  128. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +201 -0
  129. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +108 -0
  130. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
  131. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
  132. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
  133. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
  134. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
  135. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +164 -0
  136. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +926 -0
  137. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +182 -0
  138. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
  139. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
  140. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc.c +3052 -0
  141. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3019 -0
  142. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3354 -0
  143. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +344 -0
  144. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +29305 -0
  145. snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +381 -0
  146. snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.cpp +108 -0
  147. snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.hpp +47 -0
  148. snowflake/connector/_internal/nanoarrow_cpp/scripts/.clang-format +8 -0
  149. snowflake/connector/_internal/nanoarrow_cpp/scripts/format.sh +8 -0
  150. snowflake/connector/_internal/protobuf_gen/__init__.py +0 -0
  151. snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.py +408 -0
  152. snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.pyi +4487 -0
  153. snowflake/connector/_internal/protobuf_gen/database_driver_v1_services.py +2088 -0
  154. snowflake/connector/_internal/protobuf_gen/proto_exception.py +17 -0
  155. snowflake/connector/_internal/result_batch.py +150 -0
  156. snowflake/connector/_internal/snowflake_restful.py +222 -0
  157. snowflake/connector/_internal/snowpark_backcompat_helpers.py +31 -0
  158. snowflake/connector/_internal/sqlstate.py +11 -0
  159. snowflake/connector/_internal/statement_utils.py +207 -0
  160. snowflake/connector/_internal/text_utils.py +112 -0
  161. snowflake/connector/_internal/type_codes.py +139 -0
  162. snowflake/connector/_internal/utils.py +65 -0
  163. snowflake/connector/_internal/write_pandas_operation.py +657 -0
  164. snowflake/connector/aio/README.md +168 -0
  165. snowflake/connector/aio/__init__.py +37 -0
  166. snowflake/connector/aio/connection/__init__.py +17 -0
  167. snowflake/connector/aio/connection/_connection.py +506 -0
  168. snowflake/connector/aio/cursor/__init__.py +35 -0
  169. snowflake/connector/aio/cursor/_base.py +1034 -0
  170. snowflake/connector/aio/cursor/_dict_cursor.py +78 -0
  171. snowflake/connector/aio/cursor/_result_set_wrapper.py +35 -0
  172. snowflake/connector/aio/cursor/_snowflake_cursor.py +72 -0
  173. snowflake/connector/aio/pandas_tools.py +279 -0
  174. snowflake/connector/aio/result_batch.py +165 -0
  175. snowflake/connector/auth/__init__.py +0 -0
  176. snowflake/connector/auth/workload_identity.py +5 -0
  177. snowflake/connector/compat.py +22 -0
  178. snowflake/connector/config_manager.py +392 -0
  179. snowflake/connector/connection/__init__.py +30 -0
  180. snowflake/connector/connection/_connection.py +641 -0
  181. snowflake/connector/connection_config.py +517 -0
  182. snowflake/connector/constants.py +52 -0
  183. snowflake/connector/cursor/__init__.py +37 -0
  184. snowflake/connector/cursor/_base.py +1169 -0
  185. snowflake/connector/cursor/_chunked_download_reader.py +75 -0
  186. snowflake/connector/cursor/_dict_cursor.py +78 -0
  187. snowflake/connector/cursor/_result_set_wrapper.py +35 -0
  188. snowflake/connector/cursor/_snowflake_cursor.py +72 -0
  189. snowflake/connector/description.py +7 -0
  190. snowflake/connector/errors.py +492 -0
  191. snowflake/connector/network.py +71 -0
  192. snowflake/connector/pandas_tools.py +191 -0
  193. snowflake/connector/py.typed +0 -0
  194. snowflake/connector/result_batch.py +216 -0
  195. snowflake/connector/telemetry.py +40 -0
  196. snowflake/connector/time_util.py +11 -0
  197. snowflake/connector/types.py +134 -0
  198. snowflake/connector/util_text.py +3 -0
  199. snowflake/connector/version.py +23 -0
  200. snowflake_connector_python-5.2.0.dist-info/METADATA +190 -0
  201. snowflake_connector_python-5.2.0.dist-info/RECORD +202 -0
  202. snowflake_connector_python-5.2.0.dist-info/WHEEL +6 -0
@@ -0,0 +1,136 @@
1
+ """
2
+ PEP 249 Database API 2.0 Implementation
3
+
4
+ This module provides an empty implementation of the Python Database API Specification 2.0
5
+ as defined in PEP 249.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any
11
+
12
+ from . import util_text # noqa: F401 - backward compatibility re-exports
13
+ from ._internal.decorators import pep249
14
+ from ._internal.fips import FipsStatus, get_fips_status
15
+ from .connection import Connection, SnowflakeConnection
16
+ from .connection_config import ConnectionConfig
17
+ from .constants import QueryStatus, StatementParameterName
18
+ from .cursor import DictCursor, SnowflakeCursor
19
+ from .errors import (
20
+ DatabaseError,
21
+ DataError,
22
+ Error,
23
+ IntegrityError,
24
+ InterfaceError,
25
+ InternalError,
26
+ NotSupportedError,
27
+ OperationalError,
28
+ ProgrammingError,
29
+ Warning,
30
+ )
31
+ from .types import (
32
+ BINARY,
33
+ DATETIME,
34
+ NUMBER,
35
+ ROWID,
36
+ STRING,
37
+ Binary,
38
+ Date,
39
+ DateFromTicks,
40
+ Time,
41
+ TimeFromTicks,
42
+ Timestamp,
43
+ TimestampFromTicks,
44
+ )
45
+ from .version import __version__
46
+
47
+
48
+ # PEP 249 Module Interface Constants
49
+ apilevel = "2.0"
50
+ threadsafety = 2 # Threads may share the module and connections, but not cursors
51
+ paramstyle = "pyformat" # Default: %(name)s and %s placeholders (client-side interpolation)
52
+
53
+
54
+ # Sentinel to distinguish "not provided" from explicit values. Forwarding ``None``
55
+ # defaults would make ``@api_telemetry`` treat connection_name/config as passed.
56
+ _UNSET = object()
57
+
58
+
59
+ @pep249
60
+ def connect(
61
+ *,
62
+ connection_name: str | None | object = _UNSET,
63
+ connections_file_path: str | None | object = _UNSET,
64
+ config: ConnectionConfig | None | object = _UNSET,
65
+ **kwargs: Any,
66
+ ) -> Connection:
67
+ """
68
+ Create a connection to the database.
69
+
70
+ Args:
71
+ database: Database name
72
+ user: Username
73
+ password: Password
74
+ host: Host name
75
+ port: Port number
76
+ **kwargs: Additional connection parameters
77
+
78
+ Returns:
79
+ Connection: A Connection object
80
+ """
81
+ conn_kwargs = dict(kwargs)
82
+ if connection_name is not _UNSET:
83
+ conn_kwargs["connection_name"] = connection_name
84
+ if connections_file_path is not _UNSET:
85
+ conn_kwargs["connections_file_path"] = connections_file_path
86
+ if config is not _UNSET:
87
+ conn_kwargs["config"] = config
88
+ return Connection(**conn_kwargs)
89
+
90
+
91
+ # Export all public symbols
92
+ __all__ = [
93
+ # Version
94
+ "__version__",
95
+ # Module constants
96
+ "apilevel",
97
+ "threadsafety",
98
+ "paramstyle",
99
+ # Module functions
100
+ "connect",
101
+ "get_fips_status",
102
+ # Classes
103
+ "FipsStatus",
104
+ "ConnectionConfig",
105
+ "Connection",
106
+ "SnowflakeConnection",
107
+ "QueryStatus",
108
+ "StatementParameterName",
109
+ "DictCursor",
110
+ "SnowflakeCursor",
111
+ # Exceptions
112
+ "Warning",
113
+ "Error",
114
+ "InterfaceError",
115
+ "DatabaseError",
116
+ "DataError",
117
+ "OperationalError",
118
+ "IntegrityError",
119
+ "InternalError",
120
+ "ProgrammingError",
121
+ "NotSupportedError",
122
+ # Type constructors
123
+ "Date",
124
+ "Time",
125
+ "Timestamp",
126
+ "DateFromTicks",
127
+ "TimeFromTicks",
128
+ "TimestampFromTicks",
129
+ "Binary",
130
+ # Type objects
131
+ "STRING",
132
+ "BINARY",
133
+ "NUMBER",
134
+ "DATETIME",
135
+ "ROWID",
136
+ ]
File without changes
@@ -0,0 +1,134 @@
1
+ from __future__ import annotations
2
+
3
+ import functools
4
+ import importlib
5
+
6
+ from collections.abc import Callable
7
+ from importlib import metadata
8
+ from types import ModuleType
9
+ from typing import Any, TypeVar, cast
10
+
11
+ from snowflake.connector import errors
12
+ from snowflake.connector._internal.errorcode import ER_NO_NUMPY, ER_NO_PYARROW
13
+
14
+ from .._internal.logging import get_logger
15
+
16
+
17
+ F = TypeVar("F", bound=Callable[..., Any])
18
+
19
+ logger = get_logger(__name__)
20
+
21
+ DEP_PYARROW = "pyarrow"
22
+ DEP_PANDAS = "pandas"
23
+ DEP_NUMPY = "numpy"
24
+ DEP_TZLOCAL = "tzlocal"
25
+ DEP_SQLALCHEMY = "sqlalchemy"
26
+
27
+ """This module helps to manage optional dependencies.
28
+
29
+ It implements MissingOptionalDependency. If a module is unavailable an instance of this will be
30
+ returned. The point of this class is that if someone tries to use pyarrow code then by importing
31
+ pyarrow from this module if they did pyarrow.xxx then that would raise a MissingDependencyError.
32
+ """
33
+
34
+
35
+ class MissingOptionalDependency:
36
+ """A class to replace missing dependencies.
37
+
38
+ The only thing this class is supposed to do is raise a MissingDependencyError when __getattr__ is called.
39
+ This will be triggered whenever module.member is going to be called.
40
+
41
+ Supports two construction patterns:
42
+ - ``MissingOptionalDependency("pandas")`` — sets dep name from argument.
43
+ - No-arg subclass with a ``_dep_name`` class attribute (Snowpark pattern):
44
+ ``class MissingFoo(MissingOptionalDependency): _dep_name = "foo"``
45
+ """
46
+
47
+ _dep_name: str = "not set"
48
+
49
+ def __init__(self, dep: str | None = None) -> None:
50
+ if dep is not None:
51
+ self._dep_name = dep
52
+
53
+ def __getattr__(self, item: str) -> Any:
54
+ raise errors.MissingDependencyError(self._dep_name)
55
+
56
+ @property
57
+ def dep_name(self) -> str:
58
+ return self._dep_name
59
+
60
+
61
+ def _import_or_missing(module_name: str) -> ModuleType | MissingOptionalDependency:
62
+ """Try importing an optional dependency.
63
+
64
+ If available it returns the module. Otherwise, returns a MissingOptionalDependency stub.
65
+ """
66
+ try:
67
+ mod = importlib.import_module(module_name)
68
+ try:
69
+ version = metadata.version(module_name)
70
+ except metadata.PackageNotFoundError:
71
+ version = "unknown"
72
+ logger.info("%s is installed (version: %s)", module_name, version)
73
+ return mod
74
+ except ImportError:
75
+ logger.info("%s is not installed; %s-based features will be unavailable", module_name, module_name)
76
+ return MissingOptionalDependency(dep=module_name)
77
+
78
+
79
+ def check_dependency(module: ModuleType | MissingOptionalDependency) -> None:
80
+ """Raise ProgrammingError if optional dependency is not installed."""
81
+ if isinstance(module, MissingOptionalDependency):
82
+ if module.dep_name in (DEP_PYARROW, DEP_PANDAS):
83
+ msg = (
84
+ f"Optional dependency: '{module.dep_name}' is not installed, please see the following link for"
85
+ " install instructions: https://docs.snowflake.com/en/user-guide/python-connector-pandas.html#installation"
86
+ )
87
+ raise errors.ProgrammingError(msg=msg, errno=ER_NO_PYARROW)
88
+ elif module.dep_name == DEP_NUMPY:
89
+ msg = "Numpy module is not installed. Cannot fetch data as numpy"
90
+ raise errors.ProgrammingError(msg=msg, errno=ER_NO_NUMPY)
91
+ else:
92
+ raise errors.MissingDependencyError(module.dep_name)
93
+
94
+
95
+ def requires_dependency(*modules: ModuleType | MissingOptionalDependency) -> Callable[[F], F]:
96
+ """Raise ProgrammingError if any of the listed dependencies are not installed."""
97
+
98
+ def decorator(func: F) -> F:
99
+ @functools.wraps(func)
100
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
101
+ for mod in modules:
102
+ check_dependency(mod)
103
+ return func(*args, **kwargs)
104
+
105
+ return cast(F, wrapper)
106
+
107
+ return decorator
108
+
109
+
110
+ def _import_pandas() -> ModuleType | MissingOptionalDependency:
111
+ """Lazily import pandas, returning MissingOptionalDependency if not
112
+ installed.
113
+ """
114
+ result = _import_or_missing(DEP_PANDAS)
115
+ if not isinstance(result, MissingOptionalDependency):
116
+ # If relative imports without dots are enabled (Snowpark's case), this
117
+ # import can fail when run from certain test directories.
118
+ from pandas import DataFrame # noqa: F401
119
+ return result
120
+
121
+
122
+ pyarrow = _import_or_missing(DEP_PYARROW)
123
+ pandas = _import_pandas()
124
+ numpy = _import_or_missing(DEP_NUMPY)
125
+ tzlocal = _import_or_missing(DEP_TZLOCAL)
126
+ sqlalchemy = _import_or_missing(DEP_SQLALCHEMY)
127
+
128
+
129
+ # Snowpark imported these three names from ``snowflake.connector.options``
130
+ # (now this module). The Universal Driver does not use them itself.
131
+ ModuleLikeObject = ModuleType | MissingOptionalDependency
132
+
133
+ installed_pandas: bool = not isinstance(pandas, MissingOptionalDependency)
134
+ installed_pyarrow: bool = not isinstance(pyarrow, MissingOptionalDependency)
@@ -0,0 +1,221 @@
1
+ """In-band telemetry client that sends events to sf_core via protobuf RPC.
2
+
3
+ All methods are fire-and-forget: failures are logged at DEBUG level and never
4
+ propagate to the caller.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+
11
+ from enum import Enum, unique
12
+ from typing import TYPE_CHECKING, Any
13
+
14
+ from .._internal.api_client.client_api import async_core_driver, core_driver
15
+ from .._internal.backward_compatibility import install_backward_compatibility_getattr
16
+ from .._internal.decorators import backward_compatibility
17
+ from .._internal.logging import get_logger
18
+ from ..errors import InterfaceError
19
+
20
+
21
+ if TYPE_CHECKING:
22
+ from snowflake.connector._internal.protobuf_gen.database_driver_v1_services import (
23
+ ConnectionHandle,
24
+ )
25
+
26
+ logger = get_logger(__name__)
27
+
28
+
29
+ @backward_compatibility
30
+ @unique
31
+ class TelemetryField(Enum):
32
+ """Old-driver keys for telemetry message dicts."""
33
+
34
+ KEY_SOURCE = "source"
35
+ KEY_TYPE = "type"
36
+ KEY_SFQID = "query_id"
37
+
38
+
39
+ @backward_compatibility
40
+ class TelemetryData:
41
+ """Old-driver telemetry data holder, forwarded to :class:`TelemetryClient`."""
42
+
43
+ TRUE = "true"
44
+ FALSE = "false"
45
+
46
+ def __init__(self, message: Any = None, timestamp: int = 0) -> None:
47
+ self.message = message
48
+ self.timestamp = timestamp
49
+
50
+ @classmethod
51
+ def from_telemetry_data_dict(
52
+ cls,
53
+ from_dict: dict[str, Any],
54
+ timestamp: int,
55
+ connection: Any = None,
56
+ is_oob_telemetry: bool = False,
57
+ ) -> TelemetryData:
58
+ return cls(message=from_dict, timestamp=timestamp)
59
+
60
+ def to_dict(self) -> dict[str, Any]:
61
+ return {"message": self.message, "timestamp": str(self.timestamp)}
62
+
63
+
64
+ class TelemetryClient:
65
+ """Sends telemetry events to sf_core via protobuf RPC.
66
+
67
+ Wrapper identity is passed as part of ``connection_init``. This client only
68
+ sends runtime events — sf_core attaches the stored identity automatically.
69
+ """
70
+
71
+ def __init__(self, conn_handle: ConnectionHandle) -> None:
72
+ self._conn_handle = conn_handle
73
+ self._closed = False
74
+
75
+ def close(self) -> None:
76
+ self._closed = True
77
+
78
+ def send_api_usage(self, api_method: str, passed_arguments: list[str] | None = None) -> None:
79
+ """Record an API method call for telemetry.
80
+
81
+ ``passed_arguments`` lists the names of the arguments the caller
82
+ explicitly supplied (names only, no values, defaults omitted).
83
+ """
84
+ if self._closed:
85
+ return
86
+ try:
87
+ core_driver.telemetry_send_api_usage(
88
+ conn_handle=self._conn_handle,
89
+ api_method=api_method,
90
+ passed_arguments=passed_arguments or [],
91
+ )
92
+ except Exception:
93
+ logger.debug("Failed to send api_usage telemetry", exc_info=True)
94
+
95
+ def send_wrapper_error(self, exception_type: str, error_source: str) -> None:
96
+ """Record a wrapper error for telemetry."""
97
+ if self._closed:
98
+ return
99
+ try:
100
+ core_driver.telemetry_send_wrapper_error(
101
+ conn_handle=self._conn_handle,
102
+ exception_type=exception_type,
103
+ error_source=error_source,
104
+ )
105
+ except Exception:
106
+ logger.debug("Failed to send wrapper_error telemetry", exc_info=True)
107
+
108
+ def add_log_to_batch(self, telemetry_data: TelemetryData) -> None:
109
+ """Forward one caller-produced telemetry entry (e.g. Snowpark's) to sf_core.
110
+
111
+ Core owns batching, flush threshold, and ``/telemetry/send`` egress.
112
+ Raises :class:`~snowflake.connector.errors.InterfaceError` if the client
113
+ has been closed; use :meth:`try_add_log_to_batch` for the fire-and-forget
114
+ hot path.
115
+ """
116
+ if self._closed:
117
+ raise InterfaceError(
118
+ "Cannot add log to batch: TelemetryClient is closed. Obtain a fresh client from a new connection."
119
+ )
120
+ core_driver.telemetry_send_log(
121
+ conn_handle=self._conn_handle,
122
+ message_json=json.dumps(telemetry_data.message),
123
+ timestamp_ms=int(telemetry_data.timestamp),
124
+ )
125
+
126
+ def try_add_log_to_batch(self, telemetry_data: TelemetryData) -> None:
127
+ """Exception-swallowing wrapper over :meth:`add_log_to_batch` — the hot path."""
128
+ try:
129
+ self.add_log_to_batch(telemetry_data)
130
+ except Exception:
131
+ logger.debug("Failed to add log to telemetry", exc_info=True)
132
+
133
+ def send_batch(self) -> None:
134
+ """No-op: flush is owned by the Rust core (threshold + connection release).
135
+
136
+ Only an explicit close() or normal process exit (atexit) reliably
137
+ flushes buffered telemetry. Neither this driver nor the legacy
138
+ connector installs a signal handler, so a killed process (SIGTERM or
139
+ SIGKILL) loses in-buffer entries — atexit does not run on signals.
140
+ See ``tests/integ/telemetry/test_telemetry_crash_flush.py``.
141
+
142
+ Kept for snowflake-cli API compatibility (``_app/telemetry.py``).
143
+ """
144
+
145
+ @backward_compatibility
146
+ def send_log_batch(self) -> None:
147
+ """No-op: the new driver sends telemetry via RPC immediately; there is no batch to flush."""
148
+
149
+
150
+ class AsyncTelemetryClient:
151
+ """Async counterpart of :class:`TelemetryClient` for :class:`~snowflake.connector.aio.Connection`.
152
+
153
+ Uses :data:`~snowflake.connector._internal.api_client.client_api.async_core_driver`
154
+ so telemetry RPCs do not block the event loop.
155
+ """
156
+
157
+ def __init__(self, conn_handle: ConnectionHandle) -> None:
158
+ self._conn_handle = conn_handle
159
+ self._closed = False
160
+
161
+ def close(self) -> None:
162
+ self._closed = True
163
+
164
+ async def send_api_usage(self, api_method: str, passed_arguments: list[str] | None = None) -> None:
165
+ """Record an API method call for telemetry.
166
+
167
+ ``passed_arguments`` lists the names of the arguments the caller
168
+ explicitly supplied (names only, no values, defaults omitted).
169
+ """
170
+ if self._closed:
171
+ return
172
+ try:
173
+ await async_core_driver.telemetry_send_api_usage(
174
+ conn_handle=self._conn_handle,
175
+ api_method=api_method,
176
+ passed_arguments=passed_arguments or [],
177
+ )
178
+ except Exception:
179
+ logger.debug("Failed to send api_usage telemetry", exc_info=True)
180
+
181
+ async def send_wrapper_error(self, exception_type: str, error_source: str) -> None:
182
+ """Record a wrapper error for telemetry."""
183
+ if self._closed:
184
+ return
185
+ try:
186
+ await async_core_driver.telemetry_send_wrapper_error(
187
+ conn_handle=self._conn_handle,
188
+ exception_type=exception_type,
189
+ error_source=error_source,
190
+ )
191
+ except Exception:
192
+ logger.debug("Failed to send wrapper_error telemetry", exc_info=True)
193
+
194
+ async def add_log_to_batch(self, telemetry_data: TelemetryData) -> None:
195
+ """Forward one caller-produced telemetry entry (e.g. Snowpark's) to sf_core.
196
+
197
+ Core owns batching, flush threshold, and ``/telemetry/send`` egress.
198
+ Raises :class:`~snowflake.connector.errors.InterfaceError` if the client
199
+ has been closed; use :meth:`try_add_log_to_batch` for the fire-and-forget
200
+ hot path.
201
+ """
202
+ if self._closed:
203
+ raise InterfaceError(
204
+ "Cannot add log to batch: TelemetryClient is closed. Obtain a fresh client from a new connection."
205
+ )
206
+ await async_core_driver.telemetry_send_log(
207
+ conn_handle=self._conn_handle,
208
+ message_json=json.dumps(telemetry_data.message),
209
+ timestamp_ms=int(telemetry_data.timestamp),
210
+ )
211
+
212
+ async def try_add_log_to_batch(self, telemetry_data: TelemetryData) -> None:
213
+ """Exception-swallowing wrapper over :meth:`add_log_to_batch` — the hot path."""
214
+ try:
215
+ await self.add_log_to_batch(telemetry_data)
216
+ except Exception:
217
+ logger.debug("Failed to add log to telemetry", exc_info=True)
218
+
219
+
220
+ # Must be the last statement; see ``install_backward_compatibility_getattr``.
221
+ install_backward_compatibility_getattr(__name__)
@@ -0,0 +1,92 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from enum import Enum, unique
5
+
6
+ from .._internal.api_client.client_api import core_driver
7
+ from .._internal.decorators import snowpark_compat
8
+ from .._internal.errorcode import ER_INVALID_WIF_SETTINGS
9
+ from ..errors import ProgrammingError
10
+
11
+
12
+ # Kept for legacy API compatibility; the Rust core uses its own copy of this constant.
13
+ DEFAULT_ENTRA_SNOWFLAKE_RESOURCE = "api://fd3f753b-eed3-462c-b6a7-a4b5bb650aad"
14
+
15
+
16
+ @unique
17
+ class AttestationProvider(Enum):
18
+ """A WIF provider implementation that can produce an attestation."""
19
+
20
+ AWS = "AWS"
21
+ AZURE = "AZURE"
22
+ GCP = "GCP"
23
+ OIDC = "OIDC"
24
+
25
+ @staticmethod
26
+ def from_string(provider: str) -> AttestationProvider:
27
+ """Convert a string to a strongly-typed enum value of AttestationProvider."""
28
+ try:
29
+ return AttestationProvider[provider.upper()]
30
+ except KeyError:
31
+ allowed = ", ".join(AttestationProvider.all_string_values())
32
+ raise ProgrammingError(
33
+ msg=f"Unknown workload_identity_provider: '{provider}'. Expected one of: {allowed}",
34
+ errno=ER_INVALID_WIF_SETTINGS,
35
+ ) from None
36
+
37
+ @staticmethod
38
+ def all_string_values() -> list[str]:
39
+ """Return a list of all string values of the AttestationProvider enum."""
40
+ return [provider.value for provider in AttestationProvider]
41
+
42
+
43
+ @dataclass
44
+ class WorkloadIdentityAttestation:
45
+ provider: AttestationProvider
46
+ # repr=False: this is a bearer credential and must not leak into
47
+ # tracebacks, logs, or debugger output via the default dataclass repr.
48
+ credential: str = field(repr=False)
49
+ # Always empty; sf_core doesn't yet surface per-provider identifier metadata
50
+ # (AWS region/partition, GCP/Azure/OIDC iss/sub claims).
51
+ user_identifier_components: dict = field(default_factory=dict)
52
+
53
+
54
+ @snowpark_compat
55
+ def create_attestation(
56
+ provider: AttestationProvider,
57
+ entra_resource: str | None = None,
58
+ token: str | None = None,
59
+ impersonation_path: list[str] | None = None,
60
+ aws_use_outbound_token: bool | None = None,
61
+ wif_host: str | None = None,
62
+ ) -> WorkloadIdentityAttestation:
63
+ """Acquires a Workload Identity Federation attestation for the given provider.
64
+
65
+ Delegates to the Rust core's attestation logic (the same code path used by
66
+ the driver's own WIF login flow), independent of any active connection.
67
+
68
+ If an explicit entra_resource is provided it is forwarded to the Rust core;
69
+ otherwise the Rust core applies its own default for the Azure Entra resource.
70
+
71
+ `impersonation_path` is forwarded to the Rust core, which chains
72
+ `sts:AssumeRole` calls (AWS), delegate impersonation (GCP), or a
73
+ single-hop service-principal token exchange (Azure) exactly as the
74
+ driver's own WIF login flow does.
75
+
76
+ `wif_host` is forwarded as the AWS STS hostname override. Unset uses the
77
+ regional STS default.
78
+
79
+ Any other keyword argument raises `TypeError`.
80
+ """
81
+ response = core_driver.wif_create_attestation(
82
+ provider=provider.value,
83
+ entra_resource=entra_resource,
84
+ token=token,
85
+ impersonation_path=impersonation_path or [],
86
+ aws_use_outbound_token=aws_use_outbound_token,
87
+ wif_host=wif_host,
88
+ )
89
+ return WorkloadIdentityAttestation(
90
+ provider=AttestationProvider.from_string(response.provider),
91
+ credential=response.credential,
92
+ )
@@ -0,0 +1,79 @@
1
+ """Type stubs for the sf_core_python native extension (auto-generated)."""
2
+
3
+ def init(logger_callback: object) -> tuple[int, bool]:
4
+ """Initialize the core state: logging, tokio runtime, and transport.
5
+
6
+ Called by the Python connector at import time, before any API call.
7
+ Must be called before any other function.
8
+
9
+ Returns `(status, troubleshooting_enabled)` where:
10
+ - `status`: `0` = success, non-zero = failure
11
+ - `troubleshooting_enabled`: whether troubleshooting mode is active at init time
12
+
13
+ If already initialised, returns success with the current troubleshooting flag
14
+ without creating another [`Bridge`].
15
+ """
16
+ ...
17
+
18
+ def log_event(level: int, message: str, file: str, line: int, function: str, logger_name: str) -> int:
19
+ """Emit a wrapper-originated log event through the tracing pipeline.
20
+
21
+ Uses the same level encoding as the inbound wrapper log callback:
22
+ 0=ERROR, 1=WARN, 2=INFO, 3 or higher=DEBUG.
23
+
24
+ Returns `0` on success, `1` when the pipeline is uninitialised, and `2` if the body panics.
25
+ """
26
+ ...
27
+
28
+ def call_proto(api: str, method: str, request: bytes) -> tuple[int, bytes]:
29
+ """Synchronous proto API call. Releases the GIL and blocks until complete.
30
+
31
+ Returns `(status_code, response_bytes)` where status is:
32
+ - `0` — success
33
+ - `1` — application error (response holds the error payload)
34
+ - `2` — transport error (including panics / missing init caught at this boundary)
35
+ """
36
+ ...
37
+
38
+ async def call_proto_async(api: str, method: str, request: bytes) -> object:
39
+ """Async proto API call. Returns a Python awaitable → `(status_code, response)`.
40
+
41
+ Same contract as [`call_proto`]: always returns `(u32, bytes)`, never raises
42
+ for protocol-level failures.
43
+
44
+ Python cancel drops the awaitable which fires the CancellationToken.
45
+ """
46
+ ...
47
+
48
+ def perf_enabled() -> bool:
49
+ """Returns True if perf_timing feature is compiled in.
50
+ """
51
+ ...
52
+
53
+ def get_perf_data() -> tuple[int, int, int]:
54
+ """Read-and-reset perf counters. Returns (batch_wait_ns, chunk_download_ns, arrow_decode_ns).
55
+ """
56
+ ...
57
+
58
+ def reset_perf_metrics() -> None:
59
+ """Reset perf counters without reading.
60
+ """
61
+ ...
62
+
63
+ def native_arrow_enabled() -> bool:
64
+ """Returns True if the ``native-arrow`` Cargo feature is compiled in.
65
+ """
66
+ ...
67
+
68
+ def split_sql_script(sql: str, delimiter: str, remove_comments: bool) -> list[tuple[str, bool | None]]:
69
+ """Split a SQL script into statements.
70
+
71
+ Each item is the statement text and a PUT/GET flag: `True` for `PUT` and
72
+ `GET`, `False` for other statements and `!` commands, and `None` when the
73
+ text is empty or comment-only. The delimiter is rewritten as `;`.
74
+
75
+ An unterminated quote, block comment, or dollar quote keeps the rest of
76
+ the script in that statement. An empty delimiter raises `ValueError`.
77
+ """
78
+ ...
79
+
@@ -0,0 +1,6 @@
1
+ """Internal module for snowflake.ud_connector."""
2
+
3
+ from .decorators import internal_api
4
+
5
+
6
+ __all__ = ["internal_api"]