snowflake-connector-python 3.16.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. snowflake/connector/__init__.py +96 -0
  2. snowflake/connector/_query_context_cache.py +276 -0
  3. snowflake/connector/_sql_util.py +48 -0
  4. snowflake/connector/_utils.py +70 -0
  5. snowflake/connector/arrow_context.py +203 -0
  6. snowflake/connector/auth/__init__.py +53 -0
  7. snowflake/connector/auth/_auth.py +586 -0
  8. snowflake/connector/auth/_http_server.py +220 -0
  9. snowflake/connector/auth/_oauth_base.py +400 -0
  10. snowflake/connector/auth/by_plugin.py +219 -0
  11. snowflake/connector/auth/default.py +36 -0
  12. snowflake/connector/auth/idtoken.py +72 -0
  13. snowflake/connector/auth/keypair.py +222 -0
  14. snowflake/connector/auth/no_auth.py +39 -0
  15. snowflake/connector/auth/oauth.py +49 -0
  16. snowflake/connector/auth/oauth_code.py +479 -0
  17. snowflake/connector/auth/oauth_credentials.py +66 -0
  18. snowflake/connector/auth/okta.py +335 -0
  19. snowflake/connector/auth/pat.py +39 -0
  20. snowflake/connector/auth/usrpwdmfa.py +69 -0
  21. snowflake/connector/auth/webbrowser.py +502 -0
  22. snowflake/connector/auth/workload_identity.py +94 -0
  23. snowflake/connector/azure_storage_client.py +276 -0
  24. snowflake/connector/backoff_policies.py +141 -0
  25. snowflake/connector/bind_upload_agent.py +89 -0
  26. snowflake/connector/cache.py +696 -0
  27. snowflake/connector/compat.py +127 -0
  28. snowflake/connector/config_manager.py +496 -0
  29. snowflake/connector/connection.py +2273 -0
  30. snowflake/connector/connection_diagnostic.py +776 -0
  31. snowflake/connector/constants.py +442 -0
  32. snowflake/connector/converter.py +785 -0
  33. snowflake/connector/converter_issue23517.py +87 -0
  34. snowflake/connector/converter_null.py +14 -0
  35. snowflake/connector/converter_snowsql.py +205 -0
  36. snowflake/connector/cursor.py +1951 -0
  37. snowflake/connector/dbapi.py +53 -0
  38. snowflake/connector/description.py +19 -0
  39. snowflake/connector/direct_file_operation_utils.py +88 -0
  40. snowflake/connector/encryption_util.py +220 -0
  41. snowflake/connector/errorcode.py +91 -0
  42. snowflake/connector/errors.py +615 -0
  43. snowflake/connector/externals_utils/__init__.py +0 -0
  44. snowflake/connector/externals_utils/externals_setup.py +27 -0
  45. snowflake/connector/feature.py +4 -0
  46. snowflake/connector/file_compression_type.py +118 -0
  47. snowflake/connector/file_lock.py +72 -0
  48. snowflake/connector/file_transfer_agent.py +1215 -0
  49. snowflake/connector/file_util.py +153 -0
  50. snowflake/connector/gcs_storage_client.py +474 -0
  51. snowflake/connector/gzip_decoder.py +85 -0
  52. snowflake/connector/local_storage_client.py +90 -0
  53. snowflake/connector/log_configuration.py +60 -0
  54. snowflake/connector/logging_utils/__init__.py +0 -0
  55. snowflake/connector/logging_utils/filters.py +72 -0
  56. snowflake/connector/nanoarrow_arrow_iterator.cp313-win_amd64.pyd +0 -0
  57. snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +60 -0
  58. snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
  59. snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +19 -0
  60. snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
  61. snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
  62. snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
  63. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +557 -0
  64. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +98 -0
  65. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +125 -0
  66. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +115 -0
  67. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +1005 -0
  68. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +127 -0
  69. snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +47 -0
  70. snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
  71. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +83 -0
  72. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
  73. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +97 -0
  74. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +72 -0
  75. snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +73 -0
  76. snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
  77. snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +30 -0
  78. snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
  79. snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
  80. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
  81. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +45 -0
  82. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +71 -0
  83. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +56 -0
  84. snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
  85. snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +75 -0
  86. snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
  87. snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +46 -0
  88. snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
  89. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
  90. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +95 -0
  91. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +57 -0
  92. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +36 -0
  93. snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +34 -0
  94. snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
  95. snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +19 -0
  96. snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
  97. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +36 -0
  98. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
  99. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +346 -0
  100. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +145 -0
  101. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
  102. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
  103. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
  104. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +101 -0
  105. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +127 -0
  106. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
  107. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1908 -0
  108. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +215 -0
  109. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +125 -0
  110. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
  111. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +55 -0
  112. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +148 -0
  113. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
  114. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
  115. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
  116. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +162 -0
  117. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +97 -0
  118. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +239 -0
  119. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
  120. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +210 -0
  121. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +84 -0
  122. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +84 -0
  123. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
  124. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
  125. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +206 -0
  126. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +118 -0
  127. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
  128. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
  129. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
  130. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
  131. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
  132. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +162 -0
  133. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +898 -0
  134. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +190 -0
  135. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
  136. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
  137. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +3204 -0
  138. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3217 -0
  139. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3618 -0
  140. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +379 -0
  141. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +256 -0
  142. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +512 -0
  143. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +350 -0
  144. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +33273 -0
  145. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +397 -0
  146. snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +100 -0
  147. snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +49 -0
  148. snowflake/connector/network.py +1297 -0
  149. snowflake/connector/ocsp_asn1crypto.py +447 -0
  150. snowflake/connector/ocsp_snowflake.py +1883 -0
  151. snowflake/connector/options.py +131 -0
  152. snowflake/connector/pandas_tools.py +732 -0
  153. snowflake/connector/proxy.py +43 -0
  154. snowflake/connector/py.typed +0 -0
  155. snowflake/connector/result_batch.py +786 -0
  156. snowflake/connector/result_set.py +319 -0
  157. snowflake/connector/s3_storage_client.py +605 -0
  158. snowflake/connector/secret_detector.py +181 -0
  159. snowflake/connector/sf_dirs.py +64 -0
  160. snowflake/connector/sfbinaryformat.py +35 -0
  161. snowflake/connector/sfdatetime.py +345 -0
  162. snowflake/connector/snow_logging.py +144 -0
  163. snowflake/connector/sqlstate.py +9 -0
  164. snowflake/connector/ssd_internal_keys.py +30 -0
  165. snowflake/connector/ssl_wrap_socket.py +134 -0
  166. snowflake/connector/storage_client.py +478 -0
  167. snowflake/connector/telemetry.py +249 -0
  168. snowflake/connector/telemetry_oob.py +543 -0
  169. snowflake/connector/test_util.py +30 -0
  170. snowflake/connector/time_util.py +159 -0
  171. snowflake/connector/token_cache.py +402 -0
  172. snowflake/connector/tool/__init__.py +0 -0
  173. snowflake/connector/tool/dump_certs.py +57 -0
  174. snowflake/connector/tool/dump_ocsp_response.py +139 -0
  175. snowflake/connector/tool/dump_ocsp_response_cache.py +194 -0
  176. snowflake/connector/tool/probe_connection.py +69 -0
  177. snowflake/connector/url_util.py +49 -0
  178. snowflake/connector/util_text.py +301 -0
  179. snowflake/connector/vendored/__init__.py +3 -0
  180. snowflake/connector/vendored/requests/LICENSE +175 -0
  181. snowflake/connector/vendored/requests/__init__.py +169 -0
  182. snowflake/connector/vendored/requests/__version__.py +14 -0
  183. snowflake/connector/vendored/requests/_internal_utils.py +50 -0
  184. snowflake/connector/vendored/requests/adapters.py +537 -0
  185. snowflake/connector/vendored/requests/api.py +157 -0
  186. snowflake/connector/vendored/requests/auth.py +315 -0
  187. snowflake/connector/vendored/requests/certs.py +17 -0
  188. snowflake/connector/vendored/requests/compat.py +79 -0
  189. snowflake/connector/vendored/requests/cookies.py +561 -0
  190. snowflake/connector/vendored/requests/exceptions.py +140 -0
  191. snowflake/connector/vendored/requests/help.py +134 -0
  192. snowflake/connector/vendored/requests/hooks.py +33 -0
  193. snowflake/connector/vendored/requests/models.py +1033 -0
  194. snowflake/connector/vendored/requests/sessions.py +833 -0
  195. snowflake/connector/vendored/requests/status_codes.py +128 -0
  196. snowflake/connector/vendored/requests/structures.py +99 -0
  197. snowflake/connector/vendored/requests/utils.py +1093 -0
  198. snowflake/connector/vendored/urllib3/LICENSE.txt +21 -0
  199. snowflake/connector/vendored/urllib3/__init__.py +85 -0
  200. snowflake/connector/vendored/urllib3/_collections.py +355 -0
  201. snowflake/connector/vendored/urllib3/_version.py +2 -0
  202. snowflake/connector/vendored/urllib3/connection.py +572 -0
  203. snowflake/connector/vendored/urllib3/connectionpool.py +1137 -0
  204. snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
  205. snowflake/connector/vendored/urllib3/contrib/_appengine_environ.py +36 -0
  206. snowflake/connector/vendored/urllib3/contrib/_securetransport/__init__.py +0 -0
  207. snowflake/connector/vendored/urllib3/contrib/_securetransport/bindings.py +519 -0
  208. snowflake/connector/vendored/urllib3/contrib/_securetransport/low_level.py +397 -0
  209. snowflake/connector/vendored/urllib3/contrib/appengine.py +314 -0
  210. snowflake/connector/vendored/urllib3/contrib/ntlmpool.py +130 -0
  211. snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +509 -0
  212. snowflake/connector/vendored/urllib3/contrib/securetransport.py +920 -0
  213. snowflake/connector/vendored/urllib3/contrib/socks.py +216 -0
  214. snowflake/connector/vendored/urllib3/exceptions.py +323 -0
  215. snowflake/connector/vendored/urllib3/fields.py +274 -0
  216. snowflake/connector/vendored/urllib3/filepost.py +98 -0
  217. snowflake/connector/vendored/urllib3/packages/__init__.py +0 -0
  218. snowflake/connector/vendored/urllib3/packages/backports/__init__.py +0 -0
  219. snowflake/connector/vendored/urllib3/packages/backports/makefile.py +51 -0
  220. snowflake/connector/vendored/urllib3/packages/backports/weakref_finalize.py +155 -0
  221. snowflake/connector/vendored/urllib3/packages/six.py +1076 -0
  222. snowflake/connector/vendored/urllib3/poolmanager.py +540 -0
  223. snowflake/connector/vendored/urllib3/request.py +191 -0
  224. snowflake/connector/vendored/urllib3/response.py +885 -0
  225. snowflake/connector/vendored/urllib3/util/__init__.py +49 -0
  226. snowflake/connector/vendored/urllib3/util/connection.py +156 -0
  227. snowflake/connector/vendored/urllib3/util/proxy.py +57 -0
  228. snowflake/connector/vendored/urllib3/util/queue.py +22 -0
  229. snowflake/connector/vendored/urllib3/util/request.py +146 -0
  230. snowflake/connector/vendored/urllib3/util/response.py +107 -0
  231. snowflake/connector/vendored/urllib3/util/retry.py +620 -0
  232. snowflake/connector/vendored/urllib3/util/ssl_.py +495 -0
  233. snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +159 -0
  234. snowflake/connector/vendored/urllib3/util/ssltransport.py +221 -0
  235. snowflake/connector/vendored/urllib3/util/timeout.py +271 -0
  236. snowflake/connector/vendored/urllib3/util/url.py +435 -0
  237. snowflake/connector/vendored/urllib3/util/wait.py +152 -0
  238. snowflake/connector/version.py +3 -0
  239. snowflake/connector/wif_util.py +407 -0
  240. snowflake_connector_python-3.16.0.dist-info/METADATA +1475 -0
  241. snowflake_connector_python-3.16.0.dist-info/RECORD +246 -0
  242. snowflake_connector_python-3.16.0.dist-info/WHEEL +5 -0
  243. snowflake_connector_python-3.16.0.dist-info/entry_points.txt +4 -0
  244. snowflake_connector_python-3.16.0.dist-info/licenses/LICENSE.txt +202 -0
  245. snowflake_connector_python-3.16.0.dist-info/licenses/NOTICE +8 -0
  246. snowflake_connector_python-3.16.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,615 @@
1
+ #!/usr/bin/env python
2
+ from __future__ import annotations
3
+
4
+ import logging
5
+ import os
6
+ import re
7
+ import traceback
8
+ from logging import getLogger
9
+ from typing import TYPE_CHECKING, Any
10
+
11
+ from .secret_detector import SecretDetector
12
+ from .telemetry import TelemetryData, TelemetryField
13
+ from .time_util import get_time_millis
14
+
15
+ if TYPE_CHECKING: # pragma: no cover
16
+ from .connection import SnowflakeConnection
17
+ from .cursor import SnowflakeCursor
18
+
19
+ logger = getLogger(__name__)
20
+ connector_base_path = os.path.join("snowflake", "connector")
21
+
22
+
23
+ RE_FORMATTED_ERROR = re.compile(r"^(\d{6,})(?: \((\S+)\))?:")
24
+
25
+
26
+ class Error(Exception):
27
+ """Base Snowflake exception class."""
28
+
29
+ def __init__(
30
+ self,
31
+ msg: str | None = None,
32
+ errno: int | None = None,
33
+ sqlstate: str | None = None,
34
+ sfqid: str | None = None,
35
+ query: str | None = None,
36
+ done_format_msg: bool | None = None,
37
+ connection: SnowflakeConnection | None = None,
38
+ cursor: SnowflakeCursor | None = None,
39
+ ) -> None:
40
+ super().__init__(msg)
41
+ self.msg = msg
42
+ self.raw_msg = msg
43
+ self.errno = errno or -1
44
+ self.sqlstate = sqlstate or "n/a"
45
+ self.sfqid = sfqid
46
+ self.query = query
47
+
48
+ if self.msg:
49
+ # TODO: If there's a message then check to see if errno (and maybe sqlstate)
50
+ # and if so then don't insert them again, this should eventually be removed
51
+ # and we should be explicitly set this at every call to create these
52
+ # Exceptions.
53
+ # However we shouldn't be creating them during normal execution so
54
+ # this should not affect performance to users and will make our error
55
+ # messages consistent.
56
+ already_formatted_msg = RE_FORMATTED_ERROR.match(msg)
57
+ else:
58
+ self.msg = "Unknown error"
59
+ already_formatted_msg = None
60
+
61
+ if self.errno != -1 and not done_format_msg:
62
+ if self.sqlstate != "n/a":
63
+ if not already_formatted_msg:
64
+ if logger.getEffectiveLevel() in (logging.INFO, logging.DEBUG):
65
+ self.msg = f"{self.errno:06d} ({self.sqlstate}): {self.sfqid}: {self.msg}"
66
+ else:
67
+ self.msg = f"{self.errno:06d} ({self.sqlstate}): {self.msg}"
68
+ else:
69
+ if not already_formatted_msg:
70
+ if logger.getEffectiveLevel() in (logging.INFO, logging.DEBUG):
71
+ self.msg = f"{self.errno:06d}: {self.errno}: {self.msg}"
72
+ else:
73
+ self.msg = f"{self.errno:06d}: {self.msg}"
74
+
75
+ # We want to skip the last frame/line in the traceback since it is the current frame
76
+ self.telemetry_traceback = self.generate_telemetry_stacktrace()
77
+ self.exception_telemetry(msg, cursor, connection)
78
+
79
+ def __repr__(self) -> str:
80
+ return self.__str__()
81
+
82
+ def __str__(self) -> str:
83
+ return self.msg
84
+
85
+ @staticmethod
86
+ def generate_telemetry_stacktrace() -> str:
87
+ # Get the current stack minus this function and the Error init function
88
+ stack_frames = traceback.extract_stack()[:-2]
89
+ filtered_frames = list()
90
+ for frame in stack_frames:
91
+ # Only add frames associated with the snowflake python connector to the telemetry stacktrace
92
+ if connector_base_path in frame.filename:
93
+ # Get the index to truncate the file path to hide any user path
94
+ safe_path_index = frame.filename.find(connector_base_path)
95
+ # Create a new frame with the truncated file name and without the line argument since that can
96
+ # output sensitive data
97
+ filtered_frames.append(
98
+ traceback.FrameSummary(
99
+ frame.filename[safe_path_index:],
100
+ frame.lineno,
101
+ frame.name,
102
+ line="",
103
+ )
104
+ )
105
+
106
+ return "".join(traceback.format_list(filtered_frames))
107
+
108
+ def telemetry_msg(self) -> str | None:
109
+ if self.sqlstate != "n/a":
110
+ return f"{self.errno:06d} ({self.sqlstate})"
111
+ elif self.errno != -1:
112
+ return f"{self.errno:06d}"
113
+ else:
114
+ return None
115
+
116
+ def generate_telemetry_exception_data(
117
+ self,
118
+ ) -> dict[str, tuple[bool, str, str] | str]:
119
+ """Generate the data to send through telemetry."""
120
+ telemetry_data_dict: dict[str, tuple[bool, str, str] | str] = {
121
+ TelemetryField.KEY_STACKTRACE.value: SecretDetector.mask_secrets(
122
+ self.telemetry_traceback
123
+ )
124
+ }
125
+ telemetry_msg = self.telemetry_msg()
126
+ if self.sfqid:
127
+ telemetry_data_dict[TelemetryField.KEY_SFQID.value] = self.sfqid
128
+ if self.sqlstate:
129
+ telemetry_data_dict[TelemetryField.KEY_SQLSTATE.value] = self.sqlstate
130
+ if telemetry_msg:
131
+ telemetry_data_dict[TelemetryField.KEY_REASON.value] = telemetry_msg
132
+ if self.errno:
133
+ telemetry_data_dict[TelemetryField.KEY_ERROR_NUMBER.value] = str(self.errno)
134
+
135
+ return telemetry_data_dict
136
+
137
+ def send_exception_telemetry(
138
+ self,
139
+ connection: SnowflakeConnection | None,
140
+ telemetry_data: dict[str, Any],
141
+ ) -> None:
142
+ """Send telemetry data by in-band telemetry if it is enabled, otherwise send through out-of-band telemetry."""
143
+
144
+ if (
145
+ connection is not None
146
+ and connection.telemetry_enabled
147
+ and not connection._telemetry.is_closed
148
+ ):
149
+ # Send with in-band telemetry
150
+ telemetry_data[TelemetryField.KEY_TYPE.value] = (
151
+ TelemetryField.SQL_EXCEPTION.value
152
+ )
153
+ telemetry_data[TelemetryField.KEY_SOURCE.value] = connection.application
154
+ telemetry_data[TelemetryField.KEY_EXCEPTION.value] = self.__class__.__name__
155
+ ts = get_time_millis()
156
+ try:
157
+ connection._log_telemetry(
158
+ TelemetryData.from_telemetry_data_dict(
159
+ from_dict=telemetry_data, timestamp=ts, connection=connection
160
+ )
161
+ )
162
+ except AttributeError:
163
+ logger.debug("Cursor failed to log to telemetry.", exc_info=True)
164
+
165
+ def exception_telemetry(
166
+ self,
167
+ msg: str,
168
+ cursor: SnowflakeCursor | None,
169
+ connection: SnowflakeConnection | None,
170
+ ) -> None:
171
+ """Main method to generate and send telemetry data for exceptions."""
172
+ try:
173
+ telemetry_data_dict = self.generate_telemetry_exception_data()
174
+ if cursor is not None:
175
+ self.send_exception_telemetry(
176
+ cursor.connection,
177
+ telemetry_data_dict,
178
+ )
179
+ elif connection is not None:
180
+ self.send_exception_telemetry(
181
+ connection,
182
+ telemetry_data_dict,
183
+ )
184
+ else:
185
+ self.send_exception_telemetry(None, telemetry_data_dict)
186
+ except Exception:
187
+ # Do nothing but log if sending telemetry fails
188
+ logger.debug("Sending exception telemetry failed")
189
+
190
+ @staticmethod
191
+ def default_errorhandler(
192
+ connection: SnowflakeConnection,
193
+ cursor: SnowflakeCursor,
194
+ error_class: type[Error],
195
+ error_value: dict[str, str],
196
+ ) -> None:
197
+ """Default error handler that raises an error.
198
+
199
+ Args:
200
+ connection: Connections in which the error happened.
201
+ cursor: Cursor in which the error happened.
202
+ error_class: Class of error that needs handling.
203
+ error_value: A dictionary of the error details.
204
+
205
+ Raises:
206
+ A Snowflake error.
207
+ """
208
+ errno = error_value.get("errno")
209
+ done_format_msg = error_value.get("done_format_msg")
210
+ raise error_class(
211
+ msg=error_value.get("msg"),
212
+ errno=None if errno is None else int(errno),
213
+ sqlstate=error_value.get("sqlstate"),
214
+ sfqid=error_value.get("sfqid"),
215
+ query=error_value.get("query"),
216
+ done_format_msg=(
217
+ None if done_format_msg is None else bool(done_format_msg)
218
+ ),
219
+ connection=connection,
220
+ cursor=cursor,
221
+ )
222
+
223
+ @staticmethod
224
+ def errorhandler_wrapper_from_cause(
225
+ connection: SnowflakeConnection,
226
+ cause: Error | Exception,
227
+ cursor: SnowflakeCursor | None = None,
228
+ ) -> None:
229
+ """Wrapper for errorhandler_wrapper, it is called with a cause instead of a dictionary.
230
+
231
+ The dictionary is first extracted from the cause and then it's given to errorhandler_wrapper
232
+
233
+ Args:
234
+ connection: Connections in which the error happened.
235
+ cursor: Cursor in which the error happened.
236
+ cause: Error instance that we want to handle.
237
+
238
+ Returns:
239
+ None if no exceptions are raised by the connection's and cursor's error handlers.
240
+
241
+ Raises:
242
+ A Snowflake error if connection and cursor are None.
243
+ """
244
+ return Error.errorhandler_wrapper(
245
+ connection,
246
+ cursor,
247
+ type(cause),
248
+ {
249
+ "msg": cause.msg,
250
+ "errno": cause.errno,
251
+ "sqlstate": cause.sqlstate,
252
+ "done_format_msg": True,
253
+ },
254
+ )
255
+
256
+ @staticmethod
257
+ def errorhandler_wrapper(
258
+ connection: SnowflakeConnection | None,
259
+ cursor: SnowflakeCursor | None,
260
+ error_class: type[Error] | type[Exception],
261
+ error_value: dict[str, Any],
262
+ ) -> None:
263
+ """Error handler wrapper that calls the errorhandler method.
264
+
265
+ Args:
266
+ connection: Connections in which the error happened.
267
+ cursor: Cursor in which the error happened.
268
+ error_class: Class of error that needs handling.
269
+ error_value: An optional dictionary of the error details.
270
+
271
+ Returns:
272
+ None if no exceptions are raised by the connection's and cursor's error handlers.
273
+
274
+ Raises:
275
+ A Snowflake error if connection, or cursor are None. Otherwise it gives the
276
+ exception to the first handler in that order.
277
+ """
278
+
279
+ handed_over = Error.hand_to_other_handler(
280
+ connection,
281
+ cursor,
282
+ error_class,
283
+ error_value,
284
+ )
285
+ if not handed_over:
286
+ raise Error.errorhandler_make_exception(
287
+ error_class,
288
+ error_value,
289
+ )
290
+
291
+ @staticmethod
292
+ def errorhandler_wrapper_from_ready_exception(
293
+ connection: SnowflakeConnection | None,
294
+ cursor: SnowflakeCursor | None,
295
+ error_exc: Error | Exception,
296
+ ) -> None:
297
+ """Like errorhandler_wrapper, but it takes a ready to go Exception."""
298
+ if isinstance(error_exc, Error):
299
+ error_value = {
300
+ "msg": error_exc.msg,
301
+ "errno": error_exc.errno,
302
+ "sqlstate": error_exc.sqlstate,
303
+ "sfqid": error_exc.sfqid,
304
+ }
305
+ else:
306
+ error_value = error_exc.args
307
+
308
+ handed_over = Error.hand_to_other_handler(
309
+ connection,
310
+ cursor,
311
+ type(error_exc),
312
+ error_value,
313
+ )
314
+ if not handed_over:
315
+ raise error_exc
316
+
317
+ @staticmethod
318
+ def hand_to_other_handler(
319
+ connection: SnowflakeConnection | None,
320
+ cursor: SnowflakeCursor | None,
321
+ error_class: type[Error] | type[Exception],
322
+ error_value: dict[str, str | bool],
323
+ ) -> bool:
324
+ """If possible give error to a higher error handler in connection, or cursor.
325
+
326
+ Returns:
327
+ Whether it error was successfully given to a handler.
328
+ """
329
+ error_value.setdefault("done_format_msg", False)
330
+ if connection is not None:
331
+ connection.messages.append((error_class, error_value))
332
+ if cursor is not None:
333
+ cursor.messages.append((error_class, error_value))
334
+ cursor.errorhandler(connection, cursor, error_class, error_value)
335
+ return True
336
+ elif connection is not None:
337
+ connection.errorhandler(connection, cursor, error_class, error_value)
338
+ return True
339
+ return False
340
+
341
+ @staticmethod
342
+ def errorhandler_make_exception(
343
+ error_class: type[Error] | type[Exception],
344
+ error_value: dict[str, str | bool],
345
+ ) -> Error | Exception:
346
+ """Helper function to errorhandler_wrapper that creates the exception."""
347
+ error_value.setdefault("done_format_msg", False)
348
+
349
+ if issubclass(error_class, Error):
350
+ return error_class(
351
+ msg=error_value["msg"],
352
+ errno=error_value.get("errno"),
353
+ sqlstate=error_value.get("sqlstate"),
354
+ sfqid=error_value.get("sfqid"),
355
+ )
356
+ return error_class(error_value)
357
+
358
+
359
+ class _Warning(Exception):
360
+ """Exception for important warnings."""
361
+
362
+ pass
363
+
364
+
365
+ class InterfaceError(Error):
366
+ """Exception for errors related to the interface."""
367
+
368
+ pass
369
+
370
+
371
+ class DatabaseError(Error):
372
+ """Exception for errors related to the database."""
373
+
374
+ pass
375
+
376
+
377
+ class InternalError(DatabaseError):
378
+ """Exception for errors internal database errors."""
379
+
380
+ pass
381
+
382
+
383
+ class OperationalError(DatabaseError):
384
+ """Exception for errors related to the database's operation."""
385
+
386
+ pass
387
+
388
+
389
+ class ProgrammingError(DatabaseError):
390
+ """Exception for errors programming errors."""
391
+
392
+ pass
393
+
394
+
395
+ class IntegrityError(DatabaseError):
396
+ """Exception for errors regarding relational integrity."""
397
+
398
+ pass
399
+
400
+
401
+ class DataError(DatabaseError):
402
+ """Exception for errors reporting problems with processed data."""
403
+
404
+ pass
405
+
406
+
407
+ class NotSupportedError(DatabaseError):
408
+ """Exception for errors when an unsupported database feature was used."""
409
+
410
+ # Not supported errors do not have any PII in their
411
+ def telemetry_msg(self) -> str:
412
+ return self.msg
413
+
414
+
415
+ class RevocationCheckError(OperationalError):
416
+ """Exception for errors during certificate revocation check."""
417
+
418
+ # We already send OCSP exception events
419
+ def exception_telemetry(self, msg, cursor, connection) -> None:
420
+ pass
421
+
422
+
423
+ # internal errors
424
+ class InternalServerError(Error):
425
+ """Exception for 500 HTTP code for retry."""
426
+
427
+ def __init__(self, **kwargs) -> None:
428
+ Error.__init__(
429
+ self,
430
+ msg=kwargs.get("msg") or "HTTP 500: Internal Server Error",
431
+ errno=kwargs.get("errno"),
432
+ sqlstate=kwargs.get("sqlstate"),
433
+ sfqid=kwargs.get("sfqid"),
434
+ )
435
+
436
+
437
+ class ServiceUnavailableError(Error):
438
+ """Exception for 503 HTTP code for retry."""
439
+
440
+ def __init__(self, **kwargs) -> None:
441
+ Error.__init__(
442
+ self,
443
+ msg=kwargs.get("msg") or "HTTP 503: Service Unavailable",
444
+ errno=kwargs.get("errno"),
445
+ sqlstate=kwargs.get("sqlstate"),
446
+ sfqid=kwargs.get("sfqid"),
447
+ )
448
+
449
+
450
+ class GatewayTimeoutError(Error):
451
+ """Exception for 504 HTTP error for retry."""
452
+
453
+ def __init__(self, **kwargs) -> None:
454
+ Error.__init__(
455
+ self,
456
+ msg=kwargs.get("msg") or "HTTP 504: Gateway Timeout",
457
+ errno=kwargs.get("errno"),
458
+ sqlstate=kwargs.get("sqlstate"),
459
+ sfqid=kwargs.get("sfqid"),
460
+ )
461
+
462
+
463
+ class ForbiddenError(Error):
464
+ """Exception for 403 HTTP error for retry."""
465
+
466
+ def __init__(self, **kwargs) -> None:
467
+ Error.__init__(
468
+ self,
469
+ msg=kwargs.get("msg") or "HTTP 403: Forbidden",
470
+ errno=kwargs.get("errno"),
471
+ sqlstate=kwargs.get("sqlstate"),
472
+ sfqid=kwargs.get("sfqid"),
473
+ )
474
+
475
+
476
+ class RequestTimeoutError(Error):
477
+ """Exception for 408 HTTP error for retry."""
478
+
479
+ def __init__(self, **kwargs) -> None:
480
+ Error.__init__(
481
+ self,
482
+ msg=kwargs.get("msg") or "HTTP 408: Request Timeout",
483
+ errno=kwargs.get("errno"),
484
+ sqlstate=kwargs.get("sqlstate"),
485
+ sfqid=kwargs.get("sfqid"),
486
+ )
487
+
488
+
489
+ class BadRequest(Error):
490
+ """Exception for 400 HTTP error for retry."""
491
+
492
+ def __init__(self, **kwargs) -> None:
493
+ Error.__init__(
494
+ self,
495
+ msg=kwargs.get("msg") or "HTTP 400: Bad Request",
496
+ errno=kwargs.get("errno"),
497
+ sqlstate=kwargs.get("sqlstate"),
498
+ sfqid=kwargs.get("sfqid"),
499
+ )
500
+
501
+
502
+ class BadGatewayError(Error):
503
+ """Exception for 502 HTTP error for retry."""
504
+
505
+ def __init__(self, **kwargs) -> None:
506
+ Error.__init__(
507
+ self,
508
+ msg=kwargs.get("msg") or "HTTP 502: Bad Gateway",
509
+ errno=kwargs.get("errno"),
510
+ sqlstate=kwargs.get("sqlstate"),
511
+ sfqid=kwargs.get("sfqid"),
512
+ )
513
+
514
+
515
+ class MethodNotAllowed(Error):
516
+ """Exception for 405 HTTP error for retry."""
517
+
518
+ def __init__(self, **kwargs) -> None:
519
+ Error.__init__(
520
+ self,
521
+ msg=kwargs.get("msg") or "HTTP 405: Method not allowed",
522
+ errno=kwargs.get("errno"),
523
+ sqlstate=kwargs.get("sqlstate"),
524
+ sfqid=kwargs.get("sfqid"),
525
+ )
526
+
527
+
528
+ class TooManyRequests(Error):
529
+ """Exception for 429 HTTP error for retry."""
530
+
531
+ def __init__(self, **kwargs) -> None:
532
+ Error.__init__(
533
+ self,
534
+ msg=kwargs.get("msg") or "HTTP 429: Too Many Requests",
535
+ errno=kwargs.get("errno"),
536
+ sqlstate=kwargs.get("sqlstate"),
537
+ sfqid=kwargs.get("sfqid"),
538
+ )
539
+
540
+
541
+ class RefreshTokenError(Error):
542
+ def __init__(self, **kwargs) -> None:
543
+ Error.__init__(
544
+ self,
545
+ msg=kwargs.get("msg") or "Token Refresh Required",
546
+ errno=kwargs.get("errno"),
547
+ sqlstate=kwargs.get("sqlstate"),
548
+ sfqid=kwargs.get("sfqid"),
549
+ )
550
+
551
+
552
+ class OtherHTTPRetryableError(Error):
553
+ """Exception for other HTTP error for retry."""
554
+
555
+ def __init__(self, **kwargs) -> None:
556
+ code = kwargs.get("code", "n/a")
557
+ Error.__init__(
558
+ self,
559
+ msg=kwargs.get("msg") or f"HTTP {code}",
560
+ errno=kwargs.get("errno"),
561
+ sqlstate=kwargs.get("sqlstate"),
562
+ sfqid=kwargs.get("sfqid"),
563
+ )
564
+
565
+
566
+ class MissingDependencyError(Error):
567
+ """Exception for missing extras dependencies."""
568
+
569
+ def __init__(self, dependency: str) -> None:
570
+ super().__init__(msg=f"Missing optional dependency: {dependency}")
571
+
572
+
573
+ class BindUploadError(Error):
574
+ """Exception for bulk array binding stage optimization fails."""
575
+
576
+ pass
577
+
578
+
579
+ class RequestExceedMaxRetryError(Error):
580
+ """Exception for REST call to remote storage API exceeding maximum retries with transient errors."""
581
+
582
+ pass
583
+
584
+
585
+ class TokenExpiredError(Error):
586
+ """Exception for REST call to remote storage API failed because of expired authentication token."""
587
+
588
+ pass
589
+
590
+
591
+ class PresignedUrlExpiredError(Error):
592
+ """Exception for REST call to remote storage API failed because of expired presigned URL."""
593
+
594
+ pass
595
+
596
+
597
+ class ConfigSourceError(Error):
598
+ """Configuration source related errors.
599
+
600
+ Examples are environmental variable and configuration file.
601
+ """
602
+
603
+
604
+ class MissingConfigOptionError(ConfigSourceError):
605
+ """When a configuration option is missing from the final, resolved configurations.
606
+
607
+ This is a special-case of ConfigSourceError.
608
+ """
609
+
610
+
611
+ class ConfigManagerError(Error):
612
+ """Configuration manager related errors.
613
+
614
+ This means that ConfigManager is misused by a developer.
615
+ """
File without changes
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ from snowflake.connector.logging_utils.filters import (
4
+ SecretMaskingFilter,
5
+ add_filter_to_logger_and_children,
6
+ )
7
+
8
+ MODULES_TO_MASK_LOGS_NAMES = [
9
+ "snowflake.connector.vendored.urllib3",
10
+ "botocore",
11
+ "boto3",
12
+ ]
13
+ # TODO: after migration to the external urllib3 from the vendored one (SNOW-2041970),
14
+ # we should change filters here immediately to the below module's logger:
15
+ # MODULES_TO_MASK_LOGS_NAMES = [ "urllib3", ... ]
16
+
17
+
18
+ def add_filters_to_external_loggers():
19
+ for module_name in MODULES_TO_MASK_LOGS_NAMES:
20
+ add_filter_to_logger_and_children(module_name, SecretMaskingFilter())
21
+
22
+
23
+ def setup_external_libraries():
24
+ """
25
+ Assures proper setup and injections before any external libraries are used.
26
+ """
27
+ add_filters_to_external_loggers()
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env python
2
+ # Feature flags
3
+
4
+ feature_use_pyopenssl = True # use pyopenssl API or openssl command