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,127 @@
1
+ #!/usr/bin/env python
2
+ from __future__ import annotations
3
+
4
+ import collections.abc
5
+ import decimal
6
+ import html
7
+ import http.client
8
+ import os
9
+ import platform
10
+ import queue
11
+ import urllib.parse
12
+ import urllib.request
13
+ from typing import Any
14
+
15
+ from . import constants
16
+
17
+ IS_LINUX = platform.system() == "Linux"
18
+ IS_WINDOWS = platform.system() == "Windows"
19
+ IS_MACOS = platform.system() == "Darwin"
20
+
21
+ NUM_DATA_TYPES: tuple[type, ...] = ()
22
+ try:
23
+ import numpy
24
+
25
+ NUM_DATA_TYPES = (
26
+ numpy.int8,
27
+ numpy.int16,
28
+ numpy.int32,
29
+ numpy.int64,
30
+ numpy.float16,
31
+ numpy.float32,
32
+ numpy.float64,
33
+ numpy.uint8,
34
+ numpy.uint16,
35
+ numpy.uint32,
36
+ numpy.uint64,
37
+ numpy.bool_,
38
+ )
39
+ except (ImportError, AttributeError):
40
+ numpy = None
41
+
42
+ GET_CWD = os.getcwd
43
+ BASE_EXCEPTION_CLASS = Exception
44
+ TO_UNICODE = str
45
+ ITERATOR = collections.abc.Iterator
46
+ MAPPING = collections.abc.Mapping
47
+
48
+ urlsplit = urllib.parse.urlsplit
49
+ urlunsplit = urllib.parse.urlunsplit
50
+ parse_qs = urllib.parse.parse_qs
51
+ urlparse = urllib.parse.urlparse
52
+ urlunparse = urllib.parse.urlunparse
53
+
54
+ NUM_DATA_TYPES += (int, float, decimal.Decimal)
55
+
56
+
57
+ def PKCS5_UNPAD(v: bytes) -> bytes:
58
+ return v[0 : -v[-1]]
59
+
60
+
61
+ def PKCS5_OFFSET(v: bytes) -> int:
62
+ return v[-1]
63
+
64
+
65
+ def IS_BINARY(v: bytearray | bytes | str) -> bool:
66
+ return isinstance(v, (bytes, bytearray))
67
+
68
+
69
+ METHOD_NOT_ALLOWED = http.client.METHOD_NOT_ALLOWED
70
+ BAD_GATEWAY = http.client.BAD_GATEWAY
71
+ BAD_REQUEST = http.client.BAD_REQUEST
72
+ REQUEST_TIMEOUT = http.client.REQUEST_TIMEOUT
73
+ TOO_MANY_REQUESTS = http.client.TOO_MANY_REQUESTS
74
+ SERVICE_UNAVAILABLE = http.client.SERVICE_UNAVAILABLE
75
+ GATEWAY_TIMEOUT = http.client.GATEWAY_TIMEOUT
76
+ FORBIDDEN = http.client.FORBIDDEN
77
+ UNAUTHORIZED = http.client.UNAUTHORIZED
78
+ INTERNAL_SERVER_ERROR = http.client.INTERNAL_SERVER_ERROR
79
+ IncompleteRead = http.client.IncompleteRead
80
+ OK = http.client.OK
81
+ BadStatusLine = http.client.BadStatusLine
82
+
83
+ urlencode = urllib.parse.urlencode
84
+ unquote = urllib.parse.unquote
85
+ quote = urllib.parse.quote
86
+ unescape = html.unescape
87
+
88
+ EmptyQueue = queue.Empty
89
+ Queue = queue.Queue
90
+
91
+
92
+ def IS_BYTES(v: Any) -> bool:
93
+ return isinstance(v, bytes)
94
+
95
+
96
+ def IS_UNICODE(v: Any) -> bool:
97
+ return isinstance(v, str)
98
+
99
+
100
+ def IS_NUMERIC(v: Any) -> bool:
101
+ return isinstance(v, NUM_DATA_TYPES)
102
+
103
+
104
+ IS_STR = IS_UNICODE
105
+
106
+
107
+ def PKCS5_PAD(value: bytes, block_size: int) -> bytes:
108
+ return b"".join(
109
+ [
110
+ value,
111
+ (block_size - len(value) % block_size)
112
+ * chr(block_size - len(value) % block_size).encode(constants.UTF8),
113
+ ]
114
+ )
115
+
116
+
117
+ def PRINT(msg: str) -> None:
118
+ print(msg)
119
+
120
+
121
+ def INPUT(prompt: str) -> str:
122
+ return input(prompt)
123
+
124
+
125
+ def quote_url_piece(piece: str) -> str:
126
+ """Helper function to urlencode a string and turn it into bytes."""
127
+ return quote(piece)
@@ -0,0 +1,496 @@
1
+ from __future__ import annotations
2
+
3
+ import itertools
4
+ import logging
5
+ import os
6
+ import stat
7
+ import warnings
8
+ from collections.abc import Iterable
9
+ from operator import methodcaller
10
+ from pathlib import Path
11
+ from typing import Any, Callable, Literal, NamedTuple, TypeVar
12
+ from warnings import warn
13
+
14
+ import tomlkit
15
+ from tomlkit.items import Table
16
+
17
+ from snowflake.connector.compat import IS_WINDOWS
18
+ from snowflake.connector.constants import CONFIG_FILE, CONNECTIONS_FILE
19
+ from snowflake.connector.errors import (
20
+ ConfigManagerError,
21
+ ConfigSourceError,
22
+ Error,
23
+ MissingConfigOptionError,
24
+ )
25
+
26
+ _T = TypeVar("_T")
27
+
28
+ LOGGER = logging.getLogger(__name__)
29
+ READABLE_BY_OTHERS = stat.S_IRGRP | stat.S_IROTH
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
+ class ConfigOption:
46
+ """ConfigOption represents a flag/setting.
47
+
48
+ This class knows how to read the value out of all different sources and implements
49
+ order of precedence between them.
50
+
51
+ It also provides value parsing and verification.
52
+
53
+ Attributes:
54
+ name: Name of this ConfigOption.
55
+ parse_str: A function that can turn str to the desired type, useful
56
+ for reading value from environmental variable.
57
+ choices: An iterable of all possible values that are allowed for
58
+ this option.
59
+ env_name: Environmental variable value should be read from, if not
60
+ supplied, we'll construct this. False disables reading from
61
+ environmental variables, None uses the auto generated variable name
62
+ and explicitly provided string overwrites the default one.
63
+ default: The value we should resolve to when the option is not defined
64
+ in any of the sources. When it's None we treat that as there's no
65
+ default value.
66
+ _root_manager: Reference to the root manager. Used to efficiently
67
+ refer to cached config file. Is supplied by the parent
68
+ ConfigManager.
69
+ _nest_path: The names of the ConfigManagers that this option is
70
+ nested in. Used to be able to efficiently resolve where to retrieve
71
+ value out of the configuration file and construct environment
72
+ variable name. This is supplied by the parent ConfigManager.
73
+ """
74
+
75
+ def __init__(
76
+ self,
77
+ *,
78
+ name: str,
79
+ parse_str: Callable[[str], _T] | None = None,
80
+ choices: Iterable[Any] | None = None,
81
+ env_name: str | None | Literal[False] = None,
82
+ default: Any | None = None,
83
+ _root_manager: ConfigManager | None = None,
84
+ _nest_path: list[str] | None,
85
+ ) -> None:
86
+ """Create a config option that can read values from different sources.
87
+
88
+ Args:
89
+ name: Name to assign to this ConfigOption.
90
+ parse_str: String parser function for this instance.
91
+ choices: List of possible values for this instance.
92
+ env_name: Environmental variable name value should be read from.
93
+ Providing a string will use that environment variable, False disables
94
+ reading value from environmental variables and the default None generates
95
+ an environmental variable name for it using the _nest_path and name.
96
+ default: Default value for the option. Used in case the value is
97
+ is not defined in any of the sources.
98
+ _root_manager: Reference to the root manager. Should be supplied by
99
+ the parent ConfigManager.
100
+ _nest_path: The names of the ConfigManagers that this option is
101
+ nested in. This is supplied by the parent ConfigManager.
102
+ """
103
+ if _root_manager is None:
104
+ raise TypeError("_root_manager cannot be None")
105
+ if _nest_path is None:
106
+ raise TypeError("_nest_path cannot be None")
107
+ self.name = name
108
+ self.parse_str = parse_str
109
+ self.choices = choices
110
+ self._nest_path = _nest_path + [name]
111
+ self._root_manager: ConfigManager = _root_manager
112
+ self.env_name = env_name
113
+ self.default = default
114
+
115
+ def value(self) -> Any:
116
+ """Retrieve a value of option.
117
+
118
+ This function implements order of precedence between different sources.
119
+ """
120
+ source = "environment variable"
121
+ loaded_env, value = self._get_env()
122
+ if not loaded_env:
123
+ try:
124
+ value = self._get_config()
125
+ source = "configuration file"
126
+ except MissingConfigOptionError:
127
+ if self.default is not None:
128
+ source = "default_value"
129
+ value = self.default
130
+ else:
131
+ raise
132
+ if self.choices and value not in self.choices:
133
+ raise ConfigSourceError(
134
+ f"The value of {self.option_name} read from "
135
+ f"{source} is not part of {self.choices}"
136
+ )
137
+ return value
138
+
139
+ @property
140
+ def option_name(self) -> str:
141
+ """User-friendly name of the config option. Includes self._nest_path."""
142
+ return ".".join(self._nest_path[1:])
143
+
144
+ @property
145
+ def default_env_name(self) -> str:
146
+ """The default environmental variable name for this option."""
147
+ pieces = map(methodcaller("upper"), self._nest_path[1:])
148
+ return f"SNOWFLAKE_{'_'.join(pieces)}"
149
+
150
+ def _get_env(self) -> tuple[bool, str | _T | None]:
151
+ """Get value from environment variable if possible.
152
+
153
+ Returns whether it was able to load the data and the loaded value
154
+ itself.
155
+ """
156
+ if self.env_name is False:
157
+ return False, None
158
+ if self.env_name is not None:
159
+ env_name = self.env_name
160
+ else:
161
+ # Generate environment name if it was not explicitly supplied,
162
+ # and isn't disabled
163
+ env_name = self.default_env_name
164
+ env_var = os.environ.get(env_name)
165
+ if env_var is None:
166
+ return False, None
167
+ loaded_var: str | _T = env_var
168
+ if self.parse_str is not None:
169
+ loaded_var = self.parse_str(env_var)
170
+ if isinstance(loaded_var, (Table, tomlkit.TOMLDocument)):
171
+ # If we got a TOML table we probably want it in dictionary form
172
+ return True, loaded_var.value
173
+ return True, loaded_var
174
+
175
+ def _get_config(self) -> Any:
176
+ """Get value from the cached config file if possible.
177
+
178
+ Since this is the last resource for retrieving the value it raises
179
+ a MissingConfigOptionError if it's unable to find this option.
180
+ """
181
+ if (
182
+ self._root_manager.conf_file_cache is None
183
+ and self._root_manager.file_path is not None
184
+ ):
185
+ self._root_manager.read_config()
186
+ e = self._root_manager.conf_file_cache
187
+ if e is None:
188
+ raise ConfigManagerError(
189
+ f"Root manager '{self._root_manager.name}' is missing file_path",
190
+ )
191
+ for k in self._nest_path[1:]:
192
+ try:
193
+ e = e[k]
194
+ except tomlkit.exceptions.NonExistentKey:
195
+ raise MissingConfigOptionError( # TOOO: maybe a child Exception for missing option?
196
+ f"Configuration option '{self.option_name}' is not defined anywhere, "
197
+ "have you forgotten to set it in a configuration file, "
198
+ "or environmental variable?"
199
+ )
200
+
201
+ if isinstance(e, (Table, tomlkit.TOMLDocument)):
202
+ # If we got a TOML table we probably want it in dictionary form
203
+ return e.value
204
+ return e
205
+
206
+
207
+ class ConfigManager:
208
+ """Read a TOML configuration file with managed multi-source precedence.
209
+
210
+ Note that multi-source precedence is actually implemented by ConfigOption.
211
+ This is done to make sure that special handling can be done for special options.
212
+ As an example, think of not allowing to provide passwords by command line arguments.
213
+
214
+ This class is updatable at run-time, allowing other libraries to add their
215
+ own configuration options and sub-managers before resolution.
216
+
217
+ This class can simply be thought of as nestable containers for ConfigOptions.
218
+ It holds extra information necessary for efficient nesting purposes.
219
+
220
+ Sub-managers allow option groups to exist, e.g. the group "snowflake.cli.output"
221
+ could have 2 options in it: debug (boolean flag) and format (a string like "json",
222
+ or "csv").
223
+
224
+ When a ConfigManager tries to retrieve ConfigOptions' value the _root_manager
225
+ will read and cache the TOML file from the file it's pointing at, afterwards
226
+ updating the read cache can be forced by calling read_config.
227
+
228
+ Attributes:
229
+ name: The name of the ConfigManager. Used for nesting and emitting
230
+ useful error messages.
231
+ file_path: Path to the file where this and all child ConfigManagers
232
+ should read their values out of. Can be omitted for all child
233
+ managers. Root manager could also miss this value, but this will
234
+ result in an exception when a value is read that isn't available from
235
+ a preceding config source.
236
+ conf_file_cache: Cache to store what we read from the TOML file.
237
+ _sub_managers: List of ConfigManagers that are nested under the current manager.
238
+ _sub_parsers: Alias for the old name of _sub_managers in the first release, please use
239
+ the new name now, as this might get deprecated in the future.
240
+ _options: List of ConfigOptions that are under the current manager.
241
+ _root_manager: Reference to the root manager. Used to efficiently propagate to
242
+ child options.
243
+ _nest_path: The names of the ConfigManagers that this manager is nested
244
+ under. Used to efficiently propagate to child options.
245
+ _slices: List of config slices, where optional sections could be read from.
246
+ Note that this feature might become deprecated soon.
247
+ """
248
+
249
+ def __init__(
250
+ self,
251
+ *,
252
+ name: str,
253
+ file_path: Path | None = None,
254
+ _slices: list[ConfigSlice] | None = None,
255
+ ):
256
+ """Creates a new ConfigManager.
257
+
258
+ Args:
259
+ name: Name of this ConfigManager.
260
+ file_path: File this manager should read values from. Can be omitted
261
+ for all child managers.
262
+ _slices: List of ConfigSlices to consider. A configuration file's slice is a
263
+ section that can optionally reside in a different file. Note that this
264
+ feature might get deprecated soon.
265
+ """
266
+ if _slices is None:
267
+ _slices = list()
268
+ self.name = name
269
+ self.file_path = file_path
270
+ self._slices = _slices
271
+ # Objects holding sub-managers and options
272
+ self._options: dict[str, ConfigOption] = dict()
273
+ self._sub_managers: dict[str, ConfigManager] = dict()
274
+ # Dictionary to cache read in config file
275
+ self.conf_file_cache: tomlkit.TOMLDocument | None = None
276
+ # Information necessary to be able to nest elements
277
+ # and add options in O(1)
278
+ self._root_manager: ConfigManager = self
279
+ self._nest_path = [name]
280
+
281
+ @property
282
+ def _sub_parsers(self) -> dict[str, ConfigManager]:
283
+ """
284
+ Alias for the old name of ``_sub_managers``.
285
+
286
+ This used to be the original name in the first release, please use the
287
+ new name, as this might get deprecated in the future.
288
+ """
289
+ warnings.warn(
290
+ "_sub_parsers has been deprecated, use _sub_managers instead",
291
+ DeprecationWarning,
292
+ stacklevel=2,
293
+ )
294
+ return self._sub_managers
295
+
296
+ def read_config(
297
+ self,
298
+ ) -> None:
299
+ """Read and cache config file contents.
300
+
301
+ This function should be explicitly called if the ConfigManager's cache is
302
+ outdated. Most likely when someone's doing development and are interactively
303
+ adding new options to their configuration file.
304
+ """
305
+ if self.file_path is None:
306
+ raise ConfigManagerError(
307
+ "ConfigManager is trying to read config file, but it doesn't "
308
+ "have one"
309
+ )
310
+ read_config_file = tomlkit.TOMLDocument()
311
+
312
+ # Read in all of the config slices
313
+ for filep, sliceoptions, section in itertools.chain(
314
+ ((self.file_path, ConfigSliceOptions(), None),),
315
+ self._slices,
316
+ ):
317
+ if sliceoptions.only_in_slice:
318
+ del read_config_file[section]
319
+ try:
320
+ if not filep.exists():
321
+ continue
322
+ except PermissionError:
323
+ LOGGER.debug(
324
+ f"Fail to read configuration file from {str(filep)} due to no permission on its parent directory"
325
+ )
326
+ continue
327
+
328
+ if (
329
+ not IS_WINDOWS # Skip checking on Windows
330
+ and sliceoptions.check_permissions # Skip checking if this file couldn't hold sensitive information
331
+ # Same check as openssh does for permissions
332
+ # https://github.com/openssh/openssh-portable/blob/2709809fd616a0991dc18e3a58dea10fb383c3f0/readconf.c#LL2264C1-L2264C1
333
+ and filep.stat().st_mode & READABLE_BY_OTHERS != 0
334
+ or (
335
+ # Windows doesn't have getuid, skip checking
336
+ hasattr(os, "getuid")
337
+ and filep.stat().st_uid != 0
338
+ and filep.stat().st_uid != os.getuid()
339
+ )
340
+ ):
341
+ chmod_message = f'.\n * To change owner, run `chown $USER "{str(filep)}"`.\n * To restrict permissions, run `chmod 0600 "{str(filep)}"`.\n'
342
+
343
+ warn(f"Bad owner or permissions on {str(filep)}{chmod_message}")
344
+ LOGGER.debug(f"reading configuration file from {str(filep)}")
345
+ try:
346
+ read_config_piece = tomlkit.parse(filep.read_text())
347
+ except Exception as e:
348
+ raise ConfigSourceError(
349
+ "An unknown error happened while loading " f"'{str(filep)}'"
350
+ ) from e
351
+ if section is None:
352
+ read_config_file = read_config_piece
353
+ else:
354
+ read_config_file[section] = read_config_piece
355
+ self.conf_file_cache = read_config_file
356
+
357
+ def add_option(
358
+ self,
359
+ *,
360
+ option_cls: type[ConfigOption] = ConfigOption,
361
+ **kwargs,
362
+ ) -> None:
363
+ """Add a ConfigOption to this ConfigManager.
364
+
365
+ Args:
366
+ option_cls: The class that should be instantiated. This class
367
+ should be a child class of ConfigOption. Mainly useful for cases
368
+ where the default ConfigOption needs to be extended, for example
369
+ if a new configuration option source needs to be supported.
370
+ """
371
+ kwargs["_root_manager"] = self._root_manager
372
+ kwargs["_nest_path"] = self._nest_path
373
+ new_option = option_cls(
374
+ **kwargs,
375
+ )
376
+ self._check_child_conflict(new_option.name)
377
+ self._options[new_option.name] = new_option
378
+
379
+ def _check_child_conflict(self, name: str) -> None:
380
+ """Check if a sub-manager, or ConfigOption conflicts with given name.
381
+
382
+ Args:
383
+ name: Name to check against children.
384
+ """
385
+ if name in (self._options.keys() | self._sub_managers.keys()):
386
+ raise ConfigManagerError(
387
+ f"'{name}' sub-manager, or option conflicts with a child element of '{self.name}'"
388
+ )
389
+
390
+ def add_submanager(self, new_child: ConfigManager) -> None:
391
+ """Nest another ConfigManager under this one.
392
+
393
+ This function recursively updates _nest_path and _root_manager of all
394
+ children under new_child.
395
+
396
+ Args:
397
+ new_child: The ConfigManager to be nested under the current one.
398
+ Notes:
399
+ We currently don't support re-nesting a ConfigManager. Only nest a
400
+ manager under another one once.
401
+ """
402
+ self._check_child_conflict(new_child.name)
403
+ self._sub_managers[new_child.name] = new_child
404
+
405
+ def _root_setter_helper(node: ConfigManager):
406
+ # Deal with ConfigManagers
407
+ node._root_manager = self._root_manager
408
+ node._nest_path = self._nest_path + node._nest_path
409
+ for sub_manager in node._sub_managers.values():
410
+ _root_setter_helper(sub_manager)
411
+ # Deal with ConfigOptions
412
+ for option in node._options.values():
413
+ option._root_manager = self._root_manager
414
+ option._nest_path = self._nest_path + option._nest_path
415
+
416
+ _root_setter_helper(new_child)
417
+
418
+ def add_subparser(self, *args, **kwargs) -> None:
419
+ warnings.warn(
420
+ "add_subparser has been deprecated, use add_submanager instead",
421
+ DeprecationWarning,
422
+ stacklevel=2,
423
+ )
424
+ return self.add_submanager(*args, **kwargs)
425
+
426
+ def __getitem__(self, name: str) -> ConfigOption | ConfigManager:
427
+ """Get either sub-manager, or option in this manager with name.
428
+
429
+ If an option is retrieved, we call get() on it to return its value instead.
430
+
431
+ Args:
432
+ name: Name to retrieve.
433
+ """
434
+ if name in self._options:
435
+ return self._options[name].value()
436
+ if name not in self._sub_managers:
437
+ raise ConfigSourceError(
438
+ "No ConfigManager, or ConfigOption can be found"
439
+ f" with the name '{name}'"
440
+ )
441
+ return self._sub_managers[name]
442
+
443
+
444
+ CONFIG_MANAGER = ConfigManager(
445
+ name="CONFIG_MANAGER",
446
+ file_path=CONFIG_FILE,
447
+ _slices=[
448
+ ConfigSlice( # Optional connections file to read in connections from
449
+ CONNECTIONS_FILE,
450
+ ConfigSliceOptions(
451
+ check_permissions=True, # connections could live here, check permissions
452
+ ),
453
+ "connections",
454
+ ),
455
+ ],
456
+ )
457
+ CONFIG_MANAGER.add_option(
458
+ name="connections",
459
+ parse_str=tomlkit.parse,
460
+ default=dict(),
461
+ )
462
+ CONFIG_MANAGER.add_option(
463
+ name="default_connection_name",
464
+ default="default",
465
+ )
466
+
467
+
468
+ def _get_default_connection_params() -> dict[str, Any]:
469
+ def_connection_name = CONFIG_MANAGER["default_connection_name"]
470
+ connections = CONFIG_MANAGER["connections"]
471
+ if def_connection_name not in connections:
472
+ raise Error(
473
+ f"Default connection with name '{def_connection_name}' "
474
+ "cannot be found, known ones are "
475
+ f"{list(connections.keys())}"
476
+ )
477
+ return {**connections[def_connection_name]}
478
+
479
+
480
+ def __getattr__(name):
481
+ if name == "CONFIG_PARSER":
482
+ warnings.warn(
483
+ "CONFIG_PARSER has been deprecated, use CONFIG_MANAGER instead",
484
+ DeprecationWarning,
485
+ stacklevel=2,
486
+ )
487
+ return CONFIG_MANAGER
488
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
489
+
490
+
491
+ __all__ = [ # noqa: F822
492
+ "ConfigOption",
493
+ "ConfigManager",
494
+ "CONFIG_MANAGER",
495
+ "CONFIG_PARSER",
496
+ ]