snowflake-connector-python 5.2.0__cp315-cp315-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.
Files changed (204) hide show
  1. snowflake/connector/__init__.py +148 -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.cp315-win_amd64.pyd +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.cp311-win_amd64.pyd +0 -0
  17. snowflake/connector/_internal/arrow_stream_iterator.cp312-win_amd64.pyd +0 -0
  18. snowflake/connector/_internal/arrow_stream_iterator.cp313-win_amd64.pyd +0 -0
  19. snowflake/connector/_internal/arrow_stream_iterator.cp314-win_amd64.pyd +0 -0
  20. snowflake/connector/_internal/arrow_stream_iterator.cp314t-win_amd64.pyd +0 -0
  21. snowflake/connector/_internal/arrow_stream_iterator.cp315-win_amd64.pyd +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 +13278 -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/DELVEWHEEL +2 -0
  201. snowflake_connector_python-5.2.0.dist-info/METADATA +190 -0
  202. snowflake_connector_python-5.2.0.dist-info/RECORD +204 -0
  203. snowflake_connector_python-5.2.0.dist-info/WHEEL +4 -0
  204. snowflake_connector_python.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
@@ -0,0 +1,392 @@
1
+ """
2
+ ConfigManager implementation that wraps the Rust sf_core config management API.
3
+
4
+ This module provides backward compatibility with the old Python Snowflake driver's
5
+ ConfigManager while using the Rust core for actual configuration management.
6
+ All file I/O, TOML parsing, and permission checks are performed by sf_core.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ import os
13
+
14
+ from collections.abc import Callable, Iterable
15
+ from pathlib import Path
16
+ from typing import Any, Literal, NamedTuple, TypeVar
17
+
18
+ import tomlkit
19
+
20
+ from ._internal.api_client.client_api import core_driver
21
+ from ._internal.logging import get_logger
22
+ from ._internal.protobuf_gen.proto_exception import ProtoApplicationException
23
+ from .errors import ConfigManagerError, ConfigSourceError, MissingConfigOptionError
24
+ from .errors import Error as DriverError
25
+
26
+
27
+ _T = TypeVar("_T")
28
+
29
+ LOGGER = get_logger(__name__)
30
+
31
+
32
+ class ConfigSliceOptions(NamedTuple):
33
+ """Class that defines settings individual configuration files."""
34
+
35
+ check_permissions: bool = True
36
+ only_in_slice: bool = False
37
+
38
+
39
+ class ConfigSlice(NamedTuple):
40
+ path: Path
41
+ options: ConfigSliceOptions
42
+ section: str
43
+
44
+
45
+ def _dict_to_tomlkit_container(data: dict[str, Any]) -> Any:
46
+ """Wrap a nested plain dict in tomlkit types for CLI backward compatibility."""
47
+ doc = tomlkit.document()
48
+ _populate_tomlkit(doc, data)
49
+ return doc
50
+
51
+
52
+ def _populate_tomlkit(target: Any, source: dict[str, Any]) -> None:
53
+ """Recursively copy *source* into a tomlkit container *target*."""
54
+ for key, value in source.items():
55
+ if value is None:
56
+ continue
57
+ if isinstance(value, dict):
58
+ table = tomlkit.table()
59
+ _populate_tomlkit(table, value)
60
+ target.add(key, table)
61
+ elif isinstance(value, bytes):
62
+ target.add(key, value.decode("utf-8", errors="replace"))
63
+ else:
64
+ target.add(key, value)
65
+
66
+
67
+ def _extract_error_msg(exc: Exception) -> str:
68
+ """Extract the raw error message from a proto or PEP 249 exception."""
69
+ if hasattr(exc, "message"):
70
+ return str(exc.message)
71
+ if hasattr(exc, "raw_msg"):
72
+ return str(exc.raw_msg)
73
+ return str(exc)
74
+
75
+
76
+ def _translate_core_error(
77
+ exc: Exception,
78
+ file_path: Path | None = None,
79
+ ) -> DriverError:
80
+ """Translate a Rust core DriverException into the appropriate Python error.
81
+
82
+ Maps sf_core error messages to backward-compatible Python exception types.
83
+ Accepts both raw ``ProtoApplicationException`` and PEP 249 ``Error``
84
+ subclasses (produced by the error_handler in the generated client).
85
+ """
86
+ msg = _extract_error_msg(exc)
87
+
88
+ if "parse TOML" in msg or "Failed to parse" in msg or "Failed to read config file" in msg:
89
+ display_path = str(file_path) if file_path else "unknown"
90
+ return ConfigSourceError(f"An unknown error happened while loading '{display_path}'")
91
+
92
+ return ConfigManagerError(msg)
93
+
94
+
95
+ class ConfigOption:
96
+ """ConfigOption represents a flag/setting.
97
+
98
+ This class is backward compatible with the old Python driver's ConfigOption
99
+ but uses the Rust core for actual configuration retrieval.
100
+ """
101
+
102
+ def __init__(
103
+ self,
104
+ *,
105
+ name: str,
106
+ parse_str: Callable[[str], _T] | None = None,
107
+ choices: Iterable[Any] | None = None,
108
+ env_name: str | None | Literal[False] = None,
109
+ default: Any | None = None,
110
+ _root_manager: ConfigManager | None = None,
111
+ _nest_path: list[str] | None = None,
112
+ ) -> None:
113
+ if _root_manager is None:
114
+ raise TypeError("_root_manager cannot be None")
115
+ if _nest_path is None:
116
+ raise TypeError("_nest_path cannot be None")
117
+
118
+ self.name = name
119
+ self.parse_str = parse_str
120
+ self.choices = choices
121
+ self._nest_path = _nest_path + [name]
122
+ self._root_manager: ConfigManager = _root_manager
123
+ self.env_name = env_name
124
+ self.default = default
125
+
126
+ def value(self) -> Any:
127
+ """Retrieve a value of option.
128
+
129
+ Priority: Custom Environment Variable > Config File > Default
130
+ """
131
+ source = "configuration file"
132
+ value = None
133
+
134
+ if self.env_name is not False:
135
+ env_name = self.env_name or self.default_env_name
136
+ if env_name:
137
+ env_var = os.environ.get(env_name)
138
+ if env_var is not None:
139
+ source = "environment variable"
140
+ value = self.parse_str(env_var) if self.parse_str else env_var
141
+
142
+ if value is None:
143
+ try:
144
+ value = self._get_config()
145
+ source = "configuration file"
146
+ except MissingConfigOptionError:
147
+ if self.default is not None:
148
+ source = "default_value"
149
+ value = self.default
150
+ else:
151
+ raise
152
+
153
+ if self.choices and value not in self.choices:
154
+ raise ConfigSourceError(f"The value of {self.option_name} read from {source} is not part of {self.choices}")
155
+
156
+ return value
157
+
158
+ @property
159
+ def option_name(self) -> str:
160
+ return ".".join(self._nest_path[1:])
161
+
162
+ @property
163
+ def default_env_name(self) -> str:
164
+ pieces = [p.upper() for p in self._nest_path[1:]]
165
+ return f"SNOWFLAKE_{'_'.join(pieces)}"
166
+
167
+ def _get_config(self) -> Any:
168
+ """Get value from the nested cached configuration loaded by sf_core.
169
+
170
+ Dict values that contain sub-dicts are wrapped in tomlkit types so
171
+ that the CLI's ``isinstance(section, Container)`` / ``Table`` gates
172
+ work for environment-variable merging.
173
+ """
174
+ nested_config = self._root_manager._get_cached_config()
175
+
176
+ if not nested_config:
177
+ raise MissingConfigOptionError(
178
+ f"Configuration option '{self.option_name}' is not defined anywhere, "
179
+ "have you forgotten to set it in a configuration file, or "
180
+ "environmental variable?"
181
+ )
182
+
183
+ path_parts = self._nest_path[1:]
184
+ current = nested_config
185
+ for part in path_parts:
186
+ try:
187
+ current = current[part]
188
+ except (KeyError, TypeError) as err:
189
+ raise MissingConfigOptionError(
190
+ f"Configuration option '{self.option_name}' is not defined anywhere, "
191
+ "have you forgotten to set it in a configuration file, or "
192
+ "environmental variable?"
193
+ ) from err
194
+
195
+ return _dict_to_tomlkit_container(current) if isinstance(current, dict) else current
196
+
197
+
198
+ class ConfigManager:
199
+ """Read a TOML configuration file with managed multi-source precedence.
200
+
201
+ This class provides backward compatibility with the old Python driver's
202
+ ConfigManager while using the Rust sf_core for actual file I/O,
203
+ TOML parsing, and permission checks.
204
+ """
205
+
206
+ def __init__(
207
+ self,
208
+ *,
209
+ name: str,
210
+ file_path: Path | None = None,
211
+ _slices: list[ConfigSlice] | None = None,
212
+ ):
213
+ if _slices is None:
214
+ _slices = list()
215
+
216
+ self.name = name
217
+ self.file_path = file_path
218
+ self._slices = _slices
219
+
220
+ self._options: dict[str, ConfigOption] = dict()
221
+ self._sub_managers: dict[str, ConfigManager] = dict()
222
+
223
+ self.conf_file_cache: dict[str, Any] | None = None
224
+
225
+ self._root_manager: ConfigManager = self
226
+ self._nest_path = [name]
227
+
228
+ def read_config(
229
+ self,
230
+ skip_file_permissions_check: bool = False,
231
+ ) -> None:
232
+ """Read and cache config file contents from sf_core.
233
+
234
+ Passes file_path and slice paths to the Rust core so it reads
235
+ the correct files. Translates core errors to Python exceptions.
236
+
237
+ When ``skip_file_permissions_check`` is ``True``, file-permission checks
238
+ on ``config.toml`` and ``connections.toml`` are bypassed (mirrors the
239
+ ``unsafe_skip_config_file_permissions_check`` connection parameter).
240
+ """
241
+ if self.file_path is None:
242
+ raise ConfigManagerError("ConfigManager is trying to read config file, but it doesn't have one")
243
+
244
+ connections_file = self._get_connections_file_path()
245
+
246
+ try:
247
+ response = core_driver.config_load_all_sections(
248
+ config_file=str(self.file_path),
249
+ connections_file=str(connections_file) if connections_file is not None else None,
250
+ skip_permissions=skip_file_permissions_check,
251
+ )
252
+ except (ProtoApplicationException, DriverError) as e:
253
+ msg = _extract_error_msg(e)
254
+ if "permission denied" in msg.lower():
255
+ # OS-level read failure (e.g. restrictive parent-directory permissions).
256
+ # Silently return empty cache — the process simply can't see this file.
257
+ LOGGER.debug(
258
+ "Config file '%s' could not be read due to no permission on its parent directory",
259
+ self.file_path,
260
+ )
261
+ self.conf_file_cache = {}
262
+ return
263
+ raise _translate_core_error(e, self.file_path) from e
264
+
265
+ nested_config: dict[str, Any] = json.loads(response.config_json) if response.config_json else {}
266
+
267
+ for slice_info in self._slices:
268
+ _slice_path, slice_options, slice_section = slice_info
269
+ if slice_options.only_in_slice:
270
+ nested_config.pop(slice_section, None)
271
+
272
+ self.conf_file_cache = nested_config
273
+
274
+ def _get_connections_file_path(self) -> Path | None:
275
+ """Extract connections file path from slices configuration."""
276
+ for slice_info in self._slices:
277
+ slice_path, _slice_options, slice_section = slice_info
278
+ if slice_section == "connections":
279
+ return slice_path
280
+ return None
281
+
282
+ def _get_cached_config(self) -> dict[str, Any]:
283
+ """Get cached config, loading from sf_core if cache is empty."""
284
+ if self.conf_file_cache is None:
285
+ if self.file_path is None:
286
+ return {}
287
+ self.read_config()
288
+ return self.conf_file_cache or {}
289
+
290
+ def clear_cache(self) -> None:
291
+ self.conf_file_cache = None
292
+
293
+ def add_option(
294
+ self,
295
+ *,
296
+ option_cls: type[ConfigOption] = ConfigOption,
297
+ **kwargs: Any,
298
+ ) -> None:
299
+ kwargs["_root_manager"] = self._root_manager
300
+ kwargs["_nest_path"] = self._nest_path
301
+ new_option = option_cls(**kwargs)
302
+ self._check_child_conflict(new_option.name)
303
+ self._options[new_option.name] = new_option
304
+
305
+ def _check_child_conflict(self, name: str) -> None:
306
+ if name in (self._options.keys() | self._sub_managers.keys()):
307
+ raise ConfigManagerError(f"'{name}' sub-manager, or option conflicts with a child element of '{self.name}'")
308
+
309
+ def add_submanager(self, new_child: ConfigManager) -> None:
310
+ self._check_child_conflict(new_child.name)
311
+ self._sub_managers[new_child.name] = new_child
312
+
313
+ def _root_setter_helper(node: ConfigManager) -> None:
314
+ node._root_manager = self._root_manager
315
+ node._nest_path = self._nest_path + node._nest_path
316
+ for sub_manager in node._sub_managers.values():
317
+ _root_setter_helper(sub_manager)
318
+ for option in node._options.values():
319
+ option._root_manager = self._root_manager
320
+ option._nest_path = self._nest_path + option._nest_path
321
+
322
+ _root_setter_helper(new_child)
323
+
324
+ def __getitem__(self, name: str) -> ConfigOption | ConfigManager | Any:
325
+ self._root_manager._get_cached_config()
326
+ if name in self._options:
327
+ return self._options[name].value()
328
+ if name in self._sub_managers:
329
+ return self._sub_managers[name]
330
+ raise ConfigSourceError(f"No ConfigManager, or ConfigOption can be found with the name '{name}'")
331
+
332
+
333
+ def _get_config_paths_from_core() -> tuple[Path, Path]:
334
+ """Retrieve config file paths from sf_core via protobuf."""
335
+ response = core_driver.config_get_paths()
336
+ return Path(response.config_file), Path(response.connections_file)
337
+
338
+
339
+ # TODO: These paths are resolved at import time via an RPC to sf_core, which
340
+ # introduces I/O during module import. This can fail or hang if the native
341
+ # transport isn't available yet. Consider lazily resolving paths on first access
342
+ # (e.g., via a module-level getter or descriptor) with a safe fallback.
343
+ CONFIG_FILE, CONNECTIONS_FILE = _get_config_paths_from_core()
344
+
345
+ CONFIG_MANAGER = ConfigManager(
346
+ name="CONFIG_MANAGER",
347
+ file_path=CONFIG_FILE,
348
+ _slices=[
349
+ ConfigSlice(
350
+ CONNECTIONS_FILE,
351
+ ConfigSliceOptions(
352
+ check_permissions=True,
353
+ ),
354
+ "connections",
355
+ ),
356
+ ],
357
+ )
358
+
359
+ CONFIG_MANAGER.add_option(
360
+ name="connections",
361
+ parse_str=tomlkit.parse,
362
+ default=dict(),
363
+ )
364
+
365
+ CONFIG_MANAGER.add_option(
366
+ name="default_connection_name",
367
+ default="default",
368
+ )
369
+
370
+
371
+ def _get_default_connection_params() -> dict[str, Any]:
372
+ """Get default connection parameters from configuration."""
373
+ from snowflake.connector.errors import Error
374
+
375
+ def_connection_name = str(CONFIG_MANAGER["default_connection_name"])
376
+ connections: dict[str, Any] = CONFIG_MANAGER["connections"] # type: ignore[assignment]
377
+
378
+ if def_connection_name not in connections:
379
+ raise Error(
380
+ f"Default connection with name '{def_connection_name}' "
381
+ "cannot be found, known ones are "
382
+ f"{list(connections.keys())}"
383
+ )
384
+
385
+ return dict(connections[def_connection_name])
386
+
387
+
388
+ __all__ = [
389
+ "ConfigOption",
390
+ "ConfigManager",
391
+ "CONFIG_MANAGER",
392
+ ]
@@ -0,0 +1,30 @@
1
+ """
2
+ PEP 249 Database API 2.0 Connection Objects
3
+
4
+ This package defines the Connection class as specified in PEP 249.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from .._internal.connection.constants import (
10
+ APPLICATION_NAME as _APPLICATION_NAME,
11
+ )
12
+ from .._internal.connection.constants import (
13
+ CLIENT_NAME,
14
+ DEFAULT_CONFIGURATION,
15
+ LOG_MAX_QUERY_LENGTH,
16
+ )
17
+ from ..connection_config import ConnectionConfig, OptionsModifier
18
+ from ._connection import Connection, SnowflakeConnection
19
+
20
+
21
+ __all__ = [
22
+ "CLIENT_NAME",
23
+ "Connection",
24
+ "ConnectionConfig",
25
+ "DEFAULT_CONFIGURATION",
26
+ "LOG_MAX_QUERY_LENGTH",
27
+ "OptionsModifier",
28
+ "SnowflakeConnection",
29
+ "_APPLICATION_NAME",
30
+ ]