snowflake-connector-python 4.6.0__cp313-cp313-macosx_14_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 (292) hide show
  1. snowflake/connector/__init__.py +106 -0
  2. snowflake/connector/_connection_identifier_shape.py +136 -0
  3. snowflake/connector/_query_context_cache.py +276 -0
  4. snowflake/connector/_sql_util.py +48 -0
  5. snowflake/connector/_utils.py +375 -0
  6. snowflake/connector/aio/README.md +88 -0
  7. snowflake/connector/aio/__init__.py +163 -0
  8. snowflake/connector/aio/_azure_storage_client.py +227 -0
  9. snowflake/connector/aio/_bind_upload_agent.py +69 -0
  10. snowflake/connector/aio/_connection.py +1259 -0
  11. snowflake/connector/aio/_cursor.py +1401 -0
  12. snowflake/connector/aio/_description.py +5 -0
  13. snowflake/connector/aio/_direct_file_operation_utils.py +88 -0
  14. snowflake/connector/aio/_file_transfer_agent.py +316 -0
  15. snowflake/connector/aio/_gcs_storage_client.py +360 -0
  16. snowflake/connector/aio/_network.py +898 -0
  17. snowflake/connector/aio/_ocsp_asn1crypto.py +51 -0
  18. snowflake/connector/aio/_ocsp_snowflake.py +608 -0
  19. snowflake/connector/aio/_pandas_tools.py +561 -0
  20. snowflake/connector/aio/_result_batch.py +442 -0
  21. snowflake/connector/aio/_result_set.py +309 -0
  22. snowflake/connector/aio/_s3_storage_client.py +460 -0
  23. snowflake/connector/aio/_session_manager.py +579 -0
  24. snowflake/connector/aio/_storage_client.py +331 -0
  25. snowflake/connector/aio/_telemetry.py +97 -0
  26. snowflake/connector/aio/_time_util.py +57 -0
  27. snowflake/connector/aio/_wif_util.py +392 -0
  28. snowflake/connector/aio/auth/__init__.py +52 -0
  29. snowflake/connector/aio/auth/_auth.py +406 -0
  30. snowflake/connector/aio/auth/_by_plugin.py +131 -0
  31. snowflake/connector/aio/auth/_default.py +28 -0
  32. snowflake/connector/aio/auth/_idtoken.py +54 -0
  33. snowflake/connector/aio/auth/_keypair.py +60 -0
  34. snowflake/connector/aio/auth/_no_auth.py +31 -0
  35. snowflake/connector/aio/auth/_oauth.py +27 -0
  36. snowflake/connector/aio/auth/_oauth_code.py +117 -0
  37. snowflake/connector/aio/auth/_oauth_credentials.py +100 -0
  38. snowflake/connector/aio/auth/_okta.py +247 -0
  39. snowflake/connector/aio/auth/_pat.py +27 -0
  40. snowflake/connector/aio/auth/_usrpwdmfa.py +30 -0
  41. snowflake/connector/aio/auth/_webbrowser.py +405 -0
  42. snowflake/connector/aio/auth/_workload_identity.py +60 -0
  43. snowflake/connector/arrow_context.py +211 -0
  44. snowflake/connector/auth/__init__.py +53 -0
  45. snowflake/connector/auth/_auth.py +669 -0
  46. snowflake/connector/auth/_http_server.py +257 -0
  47. snowflake/connector/auth/_oauth_base.py +472 -0
  48. snowflake/connector/auth/by_plugin.py +219 -0
  49. snowflake/connector/auth/default.py +36 -0
  50. snowflake/connector/auth/idtoken.py +72 -0
  51. snowflake/connector/auth/keypair.py +255 -0
  52. snowflake/connector/auth/no_auth.py +39 -0
  53. snowflake/connector/auth/oauth.py +49 -0
  54. snowflake/connector/auth/oauth_code.py +490 -0
  55. snowflake/connector/auth/oauth_credentials.py +71 -0
  56. snowflake/connector/auth/okta.py +339 -0
  57. snowflake/connector/auth/pat.py +40 -0
  58. snowflake/connector/auth/usrpwdmfa.py +69 -0
  59. snowflake/connector/auth/webbrowser.py +514 -0
  60. snowflake/connector/auth/workload_identity.py +110 -0
  61. snowflake/connector/azure_storage_client.py +278 -0
  62. snowflake/connector/backoff_policies.py +141 -0
  63. snowflake/connector/bind_upload_agent.py +89 -0
  64. snowflake/connector/cache.py +696 -0
  65. snowflake/connector/compat.py +129 -0
  66. snowflake/connector/config_manager.py +562 -0
  67. snowflake/connector/connection.py +2761 -0
  68. snowflake/connector/connection_diagnostic.py +793 -0
  69. snowflake/connector/constants.py +460 -0
  70. snowflake/connector/converter.py +809 -0
  71. snowflake/connector/converter_issue23517.py +87 -0
  72. snowflake/connector/converter_null.py +14 -0
  73. snowflake/connector/converter_snowsql.py +205 -0
  74. snowflake/connector/crl.py +919 -0
  75. snowflake/connector/crl_cache.py +734 -0
  76. snowflake/connector/cursor.py +2095 -0
  77. snowflake/connector/dbapi.py +53 -0
  78. snowflake/connector/description.py +21 -0
  79. snowflake/connector/direct_file_operation_utils.py +88 -0
  80. snowflake/connector/encryption_util.py +220 -0
  81. snowflake/connector/errorcode.py +94 -0
  82. snowflake/connector/errors.py +666 -0
  83. snowflake/connector/externals_utils/__init__.py +0 -0
  84. snowflake/connector/externals_utils/externals_setup.py +30 -0
  85. snowflake/connector/feature.py +4 -0
  86. snowflake/connector/file_compression_type.py +118 -0
  87. snowflake/connector/file_lock.py +72 -0
  88. snowflake/connector/file_transfer_agent.py +1244 -0
  89. snowflake/connector/file_util.py +153 -0
  90. snowflake/connector/gcs_storage_client.py +476 -0
  91. snowflake/connector/gzip_decoder.py +85 -0
  92. snowflake/connector/interval_util.py +26 -0
  93. snowflake/connector/local_storage_client.py +90 -0
  94. snowflake/connector/log_configuration.py +62 -0
  95. snowflake/connector/logging_utils/__init__.py +0 -0
  96. snowflake/connector/logging_utils/filters.py +72 -0
  97. snowflake/connector/minicore/__init__.py +0 -0
  98. snowflake/connector/minicore/macos_aarch64/libsf_mini_core.dylib +0 -0
  99. snowflake/connector/nanoarrow_arrow_iterator.cpython-313-darwin.so +0 -0
  100. snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +60 -0
  101. snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
  102. snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +19 -0
  103. snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
  104. snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
  105. snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
  106. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +570 -0
  107. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +98 -0
  108. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +125 -0
  109. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +115 -0
  110. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +1140 -0
  111. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +138 -0
  112. snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +47 -0
  113. snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
  114. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +83 -0
  115. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
  116. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +97 -0
  117. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +72 -0
  118. snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +73 -0
  119. snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
  120. snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +30 -0
  121. snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
  122. snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
  123. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
  124. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +45 -0
  125. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +75 -0
  126. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +57 -0
  127. snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
  128. snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +75 -0
  129. snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
  130. snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +46 -0
  131. snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
  132. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
  133. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +95 -0
  134. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +57 -0
  135. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +36 -0
  136. snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +34 -0
  137. snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
  138. snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +19 -0
  139. snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
  140. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +36 -0
  141. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
  142. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +346 -0
  143. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +145 -0
  144. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
  145. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +67 -0
  146. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
  147. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +101 -0
  148. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +127 -0
  149. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
  150. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1908 -0
  151. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +215 -0
  152. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +125 -0
  153. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
  154. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +55 -0
  155. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +148 -0
  156. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
  157. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
  158. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
  159. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +162 -0
  160. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +97 -0
  161. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +239 -0
  162. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
  163. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +210 -0
  164. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +84 -0
  165. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +84 -0
  166. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
  167. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
  168. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +206 -0
  169. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +118 -0
  170. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
  171. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
  172. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
  173. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
  174. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
  175. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +162 -0
  176. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +898 -0
  177. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +190 -0
  178. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
  179. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
  180. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +3204 -0
  181. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3217 -0
  182. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3618 -0
  183. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +379 -0
  184. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +262 -0
  185. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +512 -0
  186. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +350 -0
  187. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +33273 -0
  188. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +397 -0
  189. snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +100 -0
  190. snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +49 -0
  191. snowflake/connector/network.py +1270 -0
  192. snowflake/connector/ocsp_asn1crypto.py +447 -0
  193. snowflake/connector/ocsp_snowflake.py +1913 -0
  194. snowflake/connector/options.py +179 -0
  195. snowflake/connector/os_details.py +88 -0
  196. snowflake/connector/pandas_tools.py +734 -0
  197. snowflake/connector/platform_detection.py +572 -0
  198. snowflake/connector/proxy.py +28 -0
  199. snowflake/connector/py.typed +0 -0
  200. snowflake/connector/result_batch.py +917 -0
  201. snowflake/connector/result_set.py +340 -0
  202. snowflake/connector/s3_storage_client.py +614 -0
  203. snowflake/connector/secret_detector.py +181 -0
  204. snowflake/connector/session_manager.py +650 -0
  205. snowflake/connector/sf_dirs.py +64 -0
  206. snowflake/connector/sfbinaryformat.py +35 -0
  207. snowflake/connector/sfdatetime.py +345 -0
  208. snowflake/connector/snow_logging.py +144 -0
  209. snowflake/connector/sqlstate.py +9 -0
  210. snowflake/connector/ssd_internal_keys.py +30 -0
  211. snowflake/connector/ssl_wrap_socket.py +281 -0
  212. snowflake/connector/storage_client.py +486 -0
  213. snowflake/connector/telemetry.py +270 -0
  214. snowflake/connector/telemetry_oob.py +544 -0
  215. snowflake/connector/test_util.py +30 -0
  216. snowflake/connector/time_util.py +159 -0
  217. snowflake/connector/token_cache.py +487 -0
  218. snowflake/connector/tool/__init__.py +0 -0
  219. snowflake/connector/tool/dump_certs.py +57 -0
  220. snowflake/connector/tool/dump_ocsp_response.py +139 -0
  221. snowflake/connector/tool/dump_ocsp_response_cache.py +194 -0
  222. snowflake/connector/tool/probe_connection.py +69 -0
  223. snowflake/connector/url_util.py +55 -0
  224. snowflake/connector/util_text.py +410 -0
  225. snowflake/connector/vendored/__init__.py +3 -0
  226. snowflake/connector/vendored/requests/LICENSE +175 -0
  227. snowflake/connector/vendored/requests/__init__.py +184 -0
  228. snowflake/connector/vendored/requests/__version__.py +14 -0
  229. snowflake/connector/vendored/requests/_internal_utils.py +50 -0
  230. snowflake/connector/vendored/requests/adapters.py +696 -0
  231. snowflake/connector/vendored/requests/api.py +157 -0
  232. snowflake/connector/vendored/requests/auth.py +314 -0
  233. snowflake/connector/vendored/requests/certs.py +17 -0
  234. snowflake/connector/vendored/requests/compat.py +106 -0
  235. snowflake/connector/vendored/requests/cookies.py +561 -0
  236. snowflake/connector/vendored/requests/exceptions.py +151 -0
  237. snowflake/connector/vendored/requests/help.py +134 -0
  238. snowflake/connector/vendored/requests/hooks.py +33 -0
  239. snowflake/connector/vendored/requests/models.py +1039 -0
  240. snowflake/connector/vendored/requests/packages.py +23 -0
  241. snowflake/connector/vendored/requests/sessions.py +831 -0
  242. snowflake/connector/vendored/requests/status_codes.py +128 -0
  243. snowflake/connector/vendored/requests/structures.py +99 -0
  244. snowflake/connector/vendored/requests/utils.py +1086 -0
  245. snowflake/connector/vendored/urllib3/LICENSE.txt +21 -0
  246. snowflake/connector/vendored/urllib3/__init__.py +211 -0
  247. snowflake/connector/vendored/urllib3/_base_connection.py +167 -0
  248. snowflake/connector/vendored/urllib3/_collections.py +486 -0
  249. snowflake/connector/vendored/urllib3/_request_methods.py +278 -0
  250. snowflake/connector/vendored/urllib3/_version.py +24 -0
  251. snowflake/connector/vendored/urllib3/connection.py +1108 -0
  252. snowflake/connector/vendored/urllib3/connectionpool.py +1191 -0
  253. snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
  254. snowflake/connector/vendored/urllib3/contrib/emscripten/__init__.py +17 -0
  255. snowflake/connector/vendored/urllib3/contrib/emscripten/connection.py +260 -0
  256. snowflake/connector/vendored/urllib3/contrib/emscripten/emscripten_fetch_worker.js +110 -0
  257. snowflake/connector/vendored/urllib3/contrib/emscripten/fetch.py +726 -0
  258. snowflake/connector/vendored/urllib3/contrib/emscripten/request.py +22 -0
  259. snowflake/connector/vendored/urllib3/contrib/emscripten/response.py +281 -0
  260. snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +563 -0
  261. snowflake/connector/vendored/urllib3/contrib/socks.py +228 -0
  262. snowflake/connector/vendored/urllib3/exceptions.py +335 -0
  263. snowflake/connector/vendored/urllib3/fields.py +341 -0
  264. snowflake/connector/vendored/urllib3/filepost.py +89 -0
  265. snowflake/connector/vendored/urllib3/http2/__init__.py +53 -0
  266. snowflake/connector/vendored/urllib3/http2/connection.py +356 -0
  267. snowflake/connector/vendored/urllib3/http2/probe.py +87 -0
  268. snowflake/connector/vendored/urllib3/poolmanager.py +653 -0
  269. snowflake/connector/vendored/urllib3/py.typed +2 -0
  270. snowflake/connector/vendored/urllib3/response.py +1493 -0
  271. snowflake/connector/vendored/urllib3/util/__init__.py +42 -0
  272. snowflake/connector/vendored/urllib3/util/connection.py +137 -0
  273. snowflake/connector/vendored/urllib3/util/proxy.py +43 -0
  274. snowflake/connector/vendored/urllib3/util/request.py +263 -0
  275. snowflake/connector/vendored/urllib3/util/response.py +101 -0
  276. snowflake/connector/vendored/urllib3/util/retry.py +557 -0
  277. snowflake/connector/vendored/urllib3/util/ssl_.py +477 -0
  278. snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +153 -0
  279. snowflake/connector/vendored/urllib3/util/ssltransport.py +271 -0
  280. snowflake/connector/vendored/urllib3/util/timeout.py +275 -0
  281. snowflake/connector/vendored/urllib3/util/url.py +469 -0
  282. snowflake/connector/vendored/urllib3/util/util.py +42 -0
  283. snowflake/connector/vendored/urllib3/util/wait.py +124 -0
  284. snowflake/connector/version.py +3 -0
  285. snowflake/connector/wif_util.py +520 -0
  286. snowflake_connector_python-4.6.0.dist-info/METADATA +1614 -0
  287. snowflake_connector_python-4.6.0.dist-info/RECORD +292 -0
  288. snowflake_connector_python-4.6.0.dist-info/WHEEL +5 -0
  289. snowflake_connector_python-4.6.0.dist-info/entry_points.txt +4 -0
  290. snowflake_connector_python-4.6.0.dist-info/licenses/LICENSE.txt +202 -0
  291. snowflake_connector_python-4.6.0.dist-info/licenses/NOTICE +8 -0
  292. snowflake_connector_python-4.6.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env python
2
+ # Python Db API v2
3
+ #
4
+ from __future__ import annotations
5
+
6
+ from functools import wraps
7
+
8
+ from ._utils import _core_loader
9
+
10
+ apilevel = "2.0"
11
+ threadsafety = 2
12
+ paramstyle = "pyformat"
13
+
14
+ import logging
15
+ from logging import NullHandler
16
+
17
+ from snowflake.connector.externals_utils.externals_setup import setup_external_libraries
18
+
19
+ from .connection import SnowflakeConnection
20
+ from .cursor import DictCursor
21
+ from .dbapi import (
22
+ BINARY,
23
+ DATETIME,
24
+ NUMBER,
25
+ ROWID,
26
+ STRING,
27
+ Binary,
28
+ Date,
29
+ DateFromTicks,
30
+ Time,
31
+ TimeFromTicks,
32
+ Timestamp,
33
+ TimestampFromTicks,
34
+ )
35
+ from .errors import (
36
+ DatabaseError,
37
+ DataError,
38
+ Error,
39
+ IntegrityError,
40
+ InterfaceError,
41
+ InternalError,
42
+ NotSupportedError,
43
+ OperationalError,
44
+ ProgrammingError,
45
+ _Warning,
46
+ )
47
+ from .log_configuration import EasyLoggingConfigPython
48
+ from .version import VERSION
49
+
50
+ # Load the core library - failures are captured in core_loader and don't prevent module loading
51
+ try:
52
+ _core_loader.load()
53
+ except Exception:
54
+ # Silently continue if core loading fails - the error is already captured in core_loader
55
+ # This ensures the connector module loads even if the minicore library is unavailable
56
+ pass
57
+
58
+ logging.getLogger(__name__).addHandler(NullHandler())
59
+ setup_external_libraries()
60
+
61
+
62
+ @wraps(SnowflakeConnection.__init__)
63
+ def Connect(**kwargs) -> SnowflakeConnection:
64
+ return SnowflakeConnection(**kwargs)
65
+
66
+
67
+ connect = Connect
68
+
69
+ SNOWFLAKE_CONNECTOR_VERSION = ".".join(str(v) for v in VERSION[0:3])
70
+ __version__ = SNOWFLAKE_CONNECTOR_VERSION
71
+
72
+ __all__ = [
73
+ "SnowflakeConnection",
74
+ # Error handling
75
+ "Error",
76
+ "_Warning",
77
+ "InterfaceError",
78
+ "DatabaseError",
79
+ "NotSupportedError",
80
+ "DataError",
81
+ "IntegrityError",
82
+ "ProgrammingError",
83
+ "OperationalError",
84
+ "InternalError",
85
+ # Extended cursor
86
+ "DictCursor",
87
+ # DBAPI PEP 249 required exports
88
+ "connect",
89
+ "apilevel",
90
+ "threadsafety",
91
+ "paramstyle",
92
+ "Date",
93
+ "Time",
94
+ "Timestamp",
95
+ "Binary",
96
+ "DateFromTicks",
97
+ "TimeFromTicks",
98
+ "TimestampFromTicks",
99
+ "STRING",
100
+ "BINARY",
101
+ "NUMBER",
102
+ "DATETIME",
103
+ "ROWID",
104
+ # Extended data type (experimental)
105
+ "EasyLoggingConfigPython",
106
+ ]
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env python
2
+ """Capture user-supplied connection-identifier provenance for in-band telemetry.
3
+
4
+ The shape captured here is consumed by ``SnowflakeConnection._log_connection_identifier_shape``
5
+ and emitted as a single ``client_connection_identifier_shape`` telemetry event
6
+ per successful login. The capture function inspects the raw kwargs passed to
7
+ ``SnowflakeConnection.__config`` before any normalization (host inference,
8
+ account stripping of ``.global``, region extraction from dotted account) runs,
9
+ so the shape reflects user intent rather than the final post-normalization
10
+ state of the connection.
11
+
12
+ Removal of this module and the emission it backs is tracked in SNOW-3548350
13
+ (target: 2026-11-30).
14
+ """
15
+ from __future__ import annotations
16
+
17
+ from dataclasses import dataclass
18
+ from typing import Any, Mapping
19
+
20
+ from .telemetry import TelemetryField
21
+
22
+
23
+ @dataclass(frozen=True)
24
+ class ConnectionIdentifierShape:
25
+ """Provenance of connection-identifier fields the user supplied.
26
+
27
+ All fields describe what the user supplied at the moment of input — they
28
+ reflect intent, not the final post-normalization state of the connection.
29
+
30
+ - ``account_provided``: the user explicitly set the ``account`` parameter
31
+ (via ``connect(account=...)``, kwargs, or ``connections.toml`` merged
32
+ into kwargs before ``__config`` runs).
33
+ - ``account_with_region``: the raw account string the user typed contained
34
+ a dot (e.g. ``"myacct.us-east-1"``), signaling the deprecated
35
+ ``account.region`` embedded form. Set only on the raw input.
36
+ - ``account_org_provided``: the raw account string carried a dash in its
37
+ account portion (e.g. ``"myorg-myacct"``), signaling the org-prefixed
38
+ form. Region-portion dashes (e.g. the ``-east-`` in
39
+ ``"myacct.us-east-1"``) are intentionally not counted; only the portion
40
+ before the first ``.`` is examined.
41
+ - ``region_provided``: the user explicitly set the ``region`` parameter as
42
+ a distinct kwarg. A region embedded inside a dotted account string is
43
+ NOT ``region_provided``; that's ``account_with_region``.
44
+ - ``host_provided``: the user explicitly set the ``host`` parameter.
45
+ """
46
+
47
+ account_provided: bool = False
48
+ account_with_region: bool = False
49
+ account_org_provided: bool = False
50
+ region_provided: bool = False
51
+ host_provided: bool = False
52
+
53
+
54
+ def _is_user_supplied_string(value: Any) -> bool:
55
+ """A kwarg counts as user-supplied iff it's a non-empty string. Non-string
56
+ truthy values (e.g. an accidentally-passed ``True`` / ``int``) are not
57
+ treated as provided here — the regular ``__config`` validation will warn
58
+ or error on them later, and shape capture is best kept conservative."""
59
+ return isinstance(value, str) and value != ""
60
+
61
+
62
+ def record_input_shape(kwargs: Mapping[str, Any]) -> ConnectionIdentifierShape:
63
+ """Capture the connection-identifier shape from the raw kwargs that
64
+ ``SnowflakeConnection.__config`` receives.
65
+
66
+ Must be invoked before any normalization (the ``setattr`` loop in
67
+ ``__config``, the ``construct_hostname`` call for host inference, or any
68
+ ``parse_account`` stripping) — otherwise inferred values are
69
+ indistinguishable from user-supplied ones and ``host_provided`` /
70
+ ``account_provided`` are no longer trustworthy.
71
+ """
72
+ account = kwargs.get("account")
73
+ region = kwargs.get("region")
74
+ host = kwargs.get("host")
75
+
76
+ account_provided = _is_user_supplied_string(account)
77
+ account_with_region = False
78
+ account_org_provided = False
79
+ if account_provided:
80
+ # Only a dot at position > 0 splits the string into account / region;
81
+ # a leading dot (pathological input like ``.us-east-1``) leaves the
82
+ # whole string as the account portion. Mirrors gosnowflake's
83
+ # ``recordAccountShape`` (internal/config/dsn.go), which gates on
84
+ # ``i > 0`` so the dash search runs against the full raw value when
85
+ # there is no real account/region split.
86
+ dot_index = account.find(".")
87
+ if dot_index > 0:
88
+ account_with_region = True
89
+ account_portion = account[:dot_index]
90
+ else:
91
+ account_portion = account
92
+ # ``Contains(accountPortion, "-")`` in Go — any dash anywhere in the
93
+ # account portion (including position 0) flips the flag. The
94
+ # region-tail dashes are excluded by virtue of being outside
95
+ # ``account_portion``, not by a position check.
96
+ account_org_provided = "-" in account_portion
97
+
98
+ return ConnectionIdentifierShape(
99
+ account_provided=account_provided,
100
+ account_with_region=account_with_region,
101
+ account_org_provided=account_org_provided,
102
+ region_provided=_is_user_supplied_string(region),
103
+ host_provided=_is_user_supplied_string(host),
104
+ )
105
+
106
+
107
+ def build_shape_telemetry_message(shape: ConnectionIdentifierShape) -> dict[str, str]:
108
+ """Build the wire-format payload for the ``client_connection_identifier_shape``
109
+ in-band telemetry event from a captured ``ConnectionIdentifierShape``.
110
+
111
+ Hoisted out of the sync / async ``_log_connection_identifier_shape``
112
+ emitters so both branches stay in lockstep — the five payload keys
113
+ (``account_provided``, ``account_with_region``, ``account_org_provided``,
114
+ ``region_provided``, ``host_provided``) and their stringified-lowercase
115
+ boolean values are byte-identical across sibling drivers and must remain
116
+ so. Changing this builder is the only place that affects the wire format.
117
+
118
+ Booleans are stringified as lowercase ``"true"`` / ``"false"`` (matching
119
+ JSON-style boolean text) for cross-driver parity with gosnowflake's
120
+ ``strconv.FormatBool`` and the JDBC / Node.js siblings.
121
+
122
+ TODO(SNOW-3548350): remove with the telemetry emission
123
+ (target: 2026-11-30).
124
+ """
125
+ return {
126
+ TelemetryField.KEY_TYPE.value: TelemetryField.CONNECTION_IDENTIFIER_SHAPE.value,
127
+ TelemetryField.KEY_ACCOUNT_PROVIDED.value: str(shape.account_provided).lower(),
128
+ TelemetryField.KEY_ACCOUNT_WITH_REGION.value: str(
129
+ shape.account_with_region
130
+ ).lower(),
131
+ TelemetryField.KEY_ACCOUNT_ORG_PROVIDED.value: str(
132
+ shape.account_org_provided
133
+ ).lower(),
134
+ TelemetryField.KEY_REGION_PROVIDED.value: str(shape.region_provided).lower(),
135
+ TelemetryField.KEY_HOST_PROVIDED.value: str(shape.host_provided).lower(),
136
+ }
@@ -0,0 +1,276 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import total_ordering
4
+ from hashlib import md5
5
+ from logging import getLogger
6
+ from threading import Lock
7
+ from typing import Any, Iterable
8
+
9
+ from sortedcontainers import SortedSet
10
+
11
+ logger = getLogger(__name__)
12
+
13
+
14
+ @total_ordering
15
+ class QueryContextElement:
16
+ def __init__(
17
+ self, id: int, read_timestamp: int, priority: int, context: str
18
+ ) -> None:
19
+ # entry with id = 0 is the main entry
20
+ self.id = id
21
+ self.read_timestamp = read_timestamp
22
+ # priority values are 0..N with 0 being the highest priority
23
+ self.priority = priority
24
+ # OpaqueContext field will be base64 encoded in GS, but it is opaque to client side. Client side should not do decoding/encoding and just store the raw data.
25
+ self.context = context
26
+
27
+ def __eq__(self, other: object) -> bool:
28
+ if not isinstance(other, QueryContextElement):
29
+ return False
30
+ return (
31
+ self.id == other.id
32
+ and self.read_timestamp == other.read_timestamp
33
+ and self.priority == other.priority
34
+ and self.context == other.context
35
+ )
36
+
37
+ def __lt__(self, other: Any) -> bool:
38
+ if not isinstance(other, QueryContextElement):
39
+ raise TypeError(
40
+ f"cannot compare QueryContextElement with object of type {type(other)}"
41
+ )
42
+ return self.priority < other.priority
43
+
44
+ def __hash__(self) -> int:
45
+ _hash = 31
46
+
47
+ _hash = _hash * 31 + self.id
48
+ _hash += (_hash * 31) + self.read_timestamp
49
+ _hash += (_hash * 31) + self.priority
50
+ if self.context:
51
+ _hash += (_hash * 31) + int.from_bytes(
52
+ md5(self.context.encode("utf-8")).digest(), "big"
53
+ )
54
+ return _hash
55
+
56
+ def __str__(self) -> str:
57
+ return f"({self.id}, {self.read_timestamp}, {self.priority})"
58
+
59
+
60
+ class QueryContextCache:
61
+ def __init__(self, capacity: int) -> None:
62
+ self.capacity = capacity
63
+ self._id_map: dict[int, QueryContextElement] = {}
64
+ self._priority_map: dict[int, QueryContextElement] = {}
65
+ self._intermediate_priority_map: dict[int, QueryContextElement] = {}
66
+
67
+ # stores elements sorted by priority. Element with
68
+ # least priority value has the highest priority
69
+ self._tree_set: set[QueryContextElement] = SortedSet()
70
+ self._lock = Lock()
71
+ self._data: str = None
72
+
73
+ def _add_qce(self, qce: QueryContextElement) -> None:
74
+ """Adds qce element in tree_set, id_map and intermediate_priority_map.
75
+ We still need to add _sync_priority_map after all the new qce have been merged
76
+ into the cache.
77
+ """
78
+ self._tree_set.add(qce)
79
+ self._id_map[qce.id] = qce
80
+ self._intermediate_priority_map[qce.priority] = qce
81
+
82
+ def _remove_qce(self, qce: QueryContextElement) -> None:
83
+ self._id_map.pop(qce.id)
84
+ self._priority_map.pop(qce.priority)
85
+ self._tree_set.remove(qce)
86
+
87
+ def _replace_qce(
88
+ self, old_qce: QueryContextElement, new_qce: QueryContextElement
89
+ ) -> None:
90
+ """This is just a convenience function to call a remove and add operation back-to-back"""
91
+ self._remove_qce(old_qce)
92
+ self._add_qce(new_qce)
93
+
94
+ def _sync_priority_map(self):
95
+ """
96
+ Sync the _intermediate_priority_map with the _priority_map at the end of the current round of inserts.
97
+ """
98
+ logger.debug(
99
+ f"sync_priority_map called priority_map size = {len(self._priority_map)}, new_priority_map size = {len(self._intermediate_priority_map)}"
100
+ )
101
+
102
+ self._priority_map.update(self._intermediate_priority_map)
103
+ # Clear the _intermediate_priority_map for the next round of QCC insert (a round consists of multiple entries)
104
+ self._intermediate_priority_map.clear()
105
+
106
+ def insert(self, id: int, read_timestamp: int, priority: int, context: str) -> None:
107
+ if id in self._id_map:
108
+ qce = self._id_map[id]
109
+ if (read_timestamp > qce.read_timestamp) or (
110
+ read_timestamp == qce.read_timestamp and priority != qce.priority
111
+ ):
112
+ # when id if found in cache and we are operating on a more recent timestamp. We do not update in-place here.
113
+ new_qce = QueryContextElement(id, read_timestamp, priority, context)
114
+ self._replace_qce(qce, new_qce)
115
+ else:
116
+ new_qce = QueryContextElement(id, read_timestamp, priority, context)
117
+ if priority in self._priority_map:
118
+ old_qce = self._priority_map[priority]
119
+ self._replace_qce(old_qce, new_qce)
120
+ else:
121
+ self._add_qce(new_qce)
122
+
123
+ def trim_cache(self) -> None:
124
+ logger.debug(
125
+ f"trim_cache() called. treeSet size is {len(self._tree_set)} and cache capacity is {self.capacity}"
126
+ )
127
+
128
+ while len(self) > self.capacity:
129
+ # remove the qce with highest priority value => element with least priority
130
+ qce = self._last()
131
+ self._remove_qce(qce)
132
+
133
+ logger.debug(
134
+ f"trim_cache() returns. treeSet size is {len(self._tree_set)} and cache capacity is {self.capacity}"
135
+ )
136
+
137
+ def clear_cache(self) -> None:
138
+ logger.debug("clear_cache() called")
139
+ self._id_map.clear()
140
+ self._priority_map.clear()
141
+ self._tree_set.clear()
142
+ self._intermediate_priority_map.clear()
143
+
144
+ def _get_elements(self) -> Iterable[QueryContextElement]:
145
+ return self._tree_set
146
+
147
+ def _last(self) -> QueryContextElement:
148
+ return self._tree_set[-1]
149
+
150
+ def serialize_to_dict(self) -> dict:
151
+ with self._lock:
152
+ logger.debug("serialize_to_dict() called")
153
+ self.log_cache_entries()
154
+
155
+ if len(self._tree_set) == 0:
156
+ return {} # we should return an empty dict
157
+
158
+ try:
159
+ data = {
160
+ "entries": [
161
+ {
162
+ "id": qce.id,
163
+ "timestamp": qce.read_timestamp,
164
+ "priority": qce.priority,
165
+ "context": (
166
+ {"base64Data": qce.context}
167
+ if qce.context is not None
168
+ else {}
169
+ ),
170
+ }
171
+ for qce in self._tree_set
172
+ ]
173
+ }
174
+ # Because on GS side, `context` field is an object with `base64Data` string member variable,
175
+ # we should serialize `context` field to an object instead of string directly to stay consistent with GS side.
176
+
177
+ logger.debug(f"serialize_to_dict(): data to send to server {data}")
178
+
179
+ # query context shoule be an object field of the HTTP request body JSON and on GS side. here we should only return a dict
180
+ # and let the outer HTTP request body to convert the entire big dict to a single JSON.
181
+ return data
182
+ except Exception as e:
183
+ logger.debug(f"serialize_to_dict(): Exception {e}")
184
+ return {}
185
+
186
+ def deserialize_json_dict(self, data: dict) -> None:
187
+ with self._lock:
188
+ logger.debug(f"deserialize_json_dict() called: data from server: {data}")
189
+ self.log_cache_entries()
190
+
191
+ if data is None or len(data) == 0:
192
+ self.clear_cache()
193
+ logger.debug("deserialize_json_dict() returns")
194
+ self.log_cache_entries()
195
+ return
196
+
197
+ try:
198
+ # Deserialize the entries. The first entry with priority 0 is the main entry. On python
199
+ # connector side, we save all entries into one list to simplify the logic. When python
200
+ # connector receives HTTP response, the data["queryContext"] field has been converted
201
+ # from JSON to dict type automatically, so for this function we deserialize from python
202
+ # dict directly. Below is an example QueryContext dict.
203
+ # {
204
+ # "entries": [
205
+ # {
206
+ # "id": 0,
207
+ # "read_timestamp": 123456789,
208
+ # "priority": 0,
209
+ # "context": "base64 encoded context"
210
+ # },
211
+ # {
212
+ # "id": 1,
213
+ # "read_timestamp": 123456789,
214
+ # "priority": 1,
215
+ # "context": "base64 encoded context"
216
+ # },
217
+ # {
218
+ # "id": 2,
219
+ # "read_timestamp": 123456789,
220
+ # "priority": 2,
221
+ # "context": "base64 encoded context"
222
+ # }
223
+ # ]
224
+ # }
225
+
226
+ # Deserialize entries
227
+ entries = data.get("entries", list())
228
+ for entry in entries:
229
+ logger.debug(f"deserialize {entry}")
230
+ if not isinstance(entry.get("id"), int):
231
+ logger.debug("id type error")
232
+ raise TypeError(
233
+ f"Invalid type for 'id' field: Expected int, got {type(entry['id'])}"
234
+ )
235
+ if not isinstance(entry.get("timestamp"), int):
236
+ logger.debug("timestamp type error")
237
+ raise TypeError(
238
+ f"Invalid type for 'timestamp' field: Expected int, got {type(entry['timestamp'])}"
239
+ )
240
+ if not isinstance(entry.get("priority"), int):
241
+ logger.debug("priority type error")
242
+ raise TypeError(
243
+ f"Invalid type for 'priority' field: Expected int, got {type(entry['priority'])}"
244
+ )
245
+
246
+ # OpaqueContext field currently is empty from GS side.
247
+ context = entry.get("context", None)
248
+ if context and not isinstance(entry.get("context"), str):
249
+ logger.debug("context type error")
250
+ raise TypeError(
251
+ f"Invalid type for 'context' field: Expected str, got {type(entry['context'])}"
252
+ )
253
+ self.insert(
254
+ entry.get("id"),
255
+ entry.get("timestamp"),
256
+ entry.get("priority"),
257
+ context,
258
+ )
259
+
260
+ # Sync the priority map at the end of for loop insert.
261
+ self._sync_priority_map()
262
+ except Exception as e:
263
+ logger.debug(f"deserialize_json_dict: Exception = {e}")
264
+ # clear cache due to incomplete insert
265
+ self.clear_cache()
266
+
267
+ self.trim_cache()
268
+ logger.debug("deserialize_json_dict() returns")
269
+ self.log_cache_entries()
270
+
271
+ def log_cache_entries(self) -> None:
272
+ for qce in self._tree_set:
273
+ logger.debug(f"Cache Entry: {str(qce)}")
274
+
275
+ def __len__(self) -> int:
276
+ return len(self._tree_set)
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+
5
+ from .constants import FileTransferType
6
+
7
+ COMMENT_START_SQL_RE = re.compile(
8
+ r"""
9
+ ^\s*(?:
10
+ /\*[\w\W]*?\*/
11
+ )""",
12
+ re.VERBOSE,
13
+ )
14
+
15
+ PUT_SQL_RE = re.compile(r"^\s*put", flags=re.IGNORECASE)
16
+ GET_SQL_RE = re.compile(r"^\s*get", flags=re.IGNORECASE)
17
+
18
+
19
+ def remove_starting_comments(sql: str) -> str:
20
+ """Remove all comments from the start of a SQL statement."""
21
+ commentless_sql = sql
22
+ while True:
23
+ start_comment = COMMENT_START_SQL_RE.match(commentless_sql)
24
+ if start_comment is None:
25
+ break
26
+ commentless_sql = commentless_sql[start_comment.end() :]
27
+ return commentless_sql
28
+
29
+
30
+ def get_file_transfer_type(sql: str) -> FileTransferType | None:
31
+ """Decide whether a SQL is a file transfer and return its type.
32
+
33
+ None is returned if the SQL isn't a file transfer so that this function can be
34
+ used in an if-statement.
35
+ """
36
+ commentless_sql = remove_starting_comments(sql)
37
+ if PUT_SQL_RE.match(commentless_sql):
38
+ return FileTransferType.PUT
39
+ elif GET_SQL_RE.match(commentless_sql):
40
+ return FileTransferType.GET
41
+
42
+
43
+ def is_put_statement(sql: str) -> bool:
44
+ return get_file_transfer_type(sql) == FileTransferType.PUT
45
+
46
+
47
+ def is_get_statement(sql: str) -> bool:
48
+ return get_file_transfer_type(sql) == FileTransferType.GET