snowflake-connector-python 3.18.0__tar.gz → 4.1.0__tar.gz

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 (261) hide show
  1. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/DESCRIPTION.md +29 -2
  2. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/PKG-INFO +45 -14
  3. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/setup.cfg +12 -11
  4. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/setup.py +26 -4
  5. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/_auth.py +39 -3
  6. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/_http_server.py +44 -7
  7. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/_oauth_base.py +16 -2
  8. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/oauth_code.py +8 -3
  9. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/oauth_credentials.py +5 -0
  10. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/okta.py +1 -0
  11. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/webbrowser.py +17 -8
  12. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/workload_identity.py +6 -0
  13. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/azure_storage_client.py +4 -4
  14. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/config_manager.py +13 -1
  15. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/connection.py +276 -9
  16. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/connection_diagnostic.py +2 -2
  17. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/constants.py +6 -0
  18. snowflake_connector_python-4.1.0/src/snowflake/connector/crl.py +794 -0
  19. snowflake_connector_python-4.1.0/src/snowflake/connector/crl_cache.py +643 -0
  20. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/cursor.py +88 -43
  21. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +2 -0
  22. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/network.py +34 -6
  23. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/ocsp_snowflake.py +78 -62
  24. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/options.py +23 -0
  25. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/pandas_tools.py +1 -1
  26. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/platform_detection.py +169 -68
  27. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/result_batch.py +11 -5
  28. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/s3_storage_client.py +12 -3
  29. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/session_manager.py +120 -49
  30. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/ssl_wrap_socket.py +64 -9
  31. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/storage_client.py +5 -3
  32. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/telemetry.py +4 -4
  33. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/telemetry_oob.py +1 -1
  34. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/token_cache.py +37 -0
  35. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/util_text.py +4 -2
  36. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/version.py +1 -1
  37. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/wif_util.py +133 -22
  38. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake_connector_python.egg-info/PKG-INFO +45 -14
  39. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake_connector_python.egg-info/SOURCES.txt +2 -0
  40. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake_connector_python.egg-info/requires.txt +15 -11
  41. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/CONTRIBUTING.md +0 -0
  42. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/LICENSE.txt +0 -0
  43. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/MANIFEST.in +0 -0
  44. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/NOTICE +0 -0
  45. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/README.md +0 -0
  46. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/SECURITY.md +0 -0
  47. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/pyproject.toml +0 -0
  48. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/__init__.py +0 -0
  49. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/_query_context_cache.py +0 -0
  50. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/_sql_util.py +0 -0
  51. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/_utils.py +0 -0
  52. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/arrow_context.py +0 -0
  53. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/__init__.py +0 -0
  54. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/by_plugin.py +0 -0
  55. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/default.py +0 -0
  56. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/idtoken.py +0 -0
  57. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/keypair.py +0 -0
  58. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/no_auth.py +0 -0
  59. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/oauth.py +0 -0
  60. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/pat.py +0 -0
  61. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/auth/usrpwdmfa.py +0 -0
  62. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/backoff_policies.py +0 -0
  63. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/bind_upload_agent.py +0 -0
  64. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/cache.py +0 -0
  65. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/compat.py +0 -0
  66. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/converter.py +0 -0
  67. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/converter_issue23517.py +0 -0
  68. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/converter_null.py +0 -0
  69. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/converter_snowsql.py +0 -0
  70. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/dbapi.py +0 -0
  71. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/description.py +0 -0
  72. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/direct_file_operation_utils.py +0 -0
  73. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/encryption_util.py +0 -0
  74. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/errorcode.py +0 -0
  75. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/errors.py +0 -0
  76. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/externals_utils/__init__.py +0 -0
  77. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/externals_utils/externals_setup.py +0 -0
  78. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/feature.py +0 -0
  79. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/file_compression_type.py +0 -0
  80. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/file_lock.py +0 -0
  81. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/file_transfer_agent.py +0 -0
  82. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/file_util.py +0 -0
  83. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/gcs_storage_client.py +0 -0
  84. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/gzip_decoder.py +0 -0
  85. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/interval_util.py +0 -0
  86. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/local_storage_client.py +0 -0
  87. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/log_configuration.py +0 -0
  88. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/logging_utils/__init__.py +0 -0
  89. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/logging_utils/filters.py +0 -0
  90. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +0 -0
  91. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +0 -0
  92. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +0 -0
  93. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +0 -0
  94. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +0 -0
  95. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +0 -0
  96. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +0 -0
  97. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +0 -0
  98. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +0 -0
  99. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +0 -0
  100. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +0 -0
  101. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +0 -0
  102. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +0 -0
  103. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +0 -0
  104. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +0 -0
  105. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +0 -0
  106. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +0 -0
  107. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +0 -0
  108. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +0 -0
  109. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +0 -0
  110. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +0 -0
  111. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +0 -0
  112. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +0 -0
  113. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +0 -0
  114. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +0 -0
  115. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +0 -0
  116. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +0 -0
  117. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +0 -0
  118. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +0 -0
  119. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +0 -0
  120. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +0 -0
  121. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +0 -0
  122. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +0 -0
  123. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +0 -0
  124. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +0 -0
  125. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +0 -0
  126. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +0 -0
  127. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +0 -0
  128. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +0 -0
  129. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +0 -0
  130. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +0 -0
  131. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +0 -0
  132. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +0 -0
  133. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +0 -0
  134. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +0 -0
  135. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +0 -0
  136. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +0 -0
  137. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +0 -0
  138. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +0 -0
  139. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +0 -0
  140. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +0 -0
  141. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +0 -0
  142. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +0 -0
  143. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +0 -0
  144. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +0 -0
  145. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +0 -0
  146. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +0 -0
  147. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +0 -0
  148. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +0 -0
  149. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +0 -0
  150. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +0 -0
  151. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +0 -0
  152. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +0 -0
  153. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +0 -0
  154. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +0 -0
  155. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +0 -0
  156. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +0 -0
  157. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +0 -0
  158. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +0 -0
  159. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +0 -0
  160. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +0 -0
  161. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +0 -0
  162. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +0 -0
  163. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +0 -0
  164. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +0 -0
  165. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +0 -0
  166. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +0 -0
  167. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +0 -0
  168. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +0 -0
  169. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +0 -0
  170. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +0 -0
  171. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +0 -0
  172. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +0 -0
  173. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +0 -0
  174. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +0 -0
  175. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +0 -0
  176. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +0 -0
  177. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +0 -0
  178. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +0 -0
  179. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +0 -0
  180. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/ocsp_asn1crypto.py +0 -0
  181. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/proxy.py +0 -0
  182. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/py.typed +0 -0
  183. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/result_set.py +0 -0
  184. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/secret_detector.py +0 -0
  185. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/sf_dirs.py +0 -0
  186. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/sfbinaryformat.py +0 -0
  187. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/sfdatetime.py +0 -0
  188. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/snow_logging.py +0 -0
  189. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/sqlstate.py +0 -0
  190. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/ssd_internal_keys.py +0 -0
  191. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/test_util.py +0 -0
  192. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/time_util.py +0 -0
  193. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/tool/__init__.py +0 -0
  194. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/tool/dump_certs.py +0 -0
  195. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/tool/dump_ocsp_response.py +0 -0
  196. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/tool/dump_ocsp_response_cache.py +0 -0
  197. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/tool/probe_connection.py +0 -0
  198. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/url_util.py +0 -0
  199. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/__init__.py +0 -0
  200. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/LICENSE +0 -0
  201. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/__init__.py +0 -0
  202. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/__version__.py +0 -0
  203. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/_internal_utils.py +0 -0
  204. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/adapters.py +0 -0
  205. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/api.py +0 -0
  206. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/auth.py +0 -0
  207. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/certs.py +0 -0
  208. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/compat.py +0 -0
  209. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/cookies.py +0 -0
  210. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/exceptions.py +0 -0
  211. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/help.py +0 -0
  212. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/hooks.py +0 -0
  213. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/models.py +0 -0
  214. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/packages.py +0 -0
  215. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/sessions.py +0 -0
  216. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/status_codes.py +0 -0
  217. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/structures.py +0 -0
  218. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/requests/utils.py +0 -0
  219. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/LICENSE.txt +0 -0
  220. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/__init__.py +0 -0
  221. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/_base_connection.py +0 -0
  222. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/_collections.py +0 -0
  223. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/_request_methods.py +0 -0
  224. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/_version.py +0 -0
  225. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/connection.py +0 -0
  226. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/connectionpool.py +0 -0
  227. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
  228. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/__init__.py +0 -0
  229. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/connection.py +0 -0
  230. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/emscripten_fetch_worker.js +0 -0
  231. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/fetch.py +0 -0
  232. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/request.py +0 -0
  233. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/response.py +0 -0
  234. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +0 -0
  235. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/contrib/socks.py +0 -0
  236. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/exceptions.py +0 -0
  237. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/fields.py +0 -0
  238. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/filepost.py +0 -0
  239. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/http2/__init__.py +0 -0
  240. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/http2/connection.py +0 -0
  241. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/http2/probe.py +0 -0
  242. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/poolmanager.py +0 -0
  243. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/py.typed +0 -0
  244. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/response.py +0 -0
  245. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/__init__.py +0 -0
  246. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/connection.py +0 -0
  247. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/proxy.py +0 -0
  248. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/request.py +0 -0
  249. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/response.py +0 -0
  250. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/retry.py +0 -0
  251. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/ssl_.py +0 -0
  252. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +0 -0
  253. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/ssltransport.py +0 -0
  254. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/timeout.py +0 -0
  255. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/url.py +0 -0
  256. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/util.py +0 -0
  257. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake/connector/vendored/urllib3/util/wait.py +0 -0
  258. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake_connector_python.egg-info/dependency_links.txt +0 -0
  259. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake_connector_python.egg-info/entry_points.txt +0 -0
  260. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake_connector_python.egg-info/not-zip-safe +0 -0
  261. {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.1.0}/src/snowflake_connector_python.egg-info/top_level.txt +0 -0
@@ -7,8 +7,34 @@ https://docs.snowflake.com/
7
7
  Source code is also available at: https://github.com/snowflakedb/snowflake-connector-python
8
8
 
9
9
  # Release Notes
10
- - v3.19.0(TBD)
11
- - N/A
10
+ - v4.1.0(November 18,2025)
11
+ - Added the `SNOWFLAKE_AUTH_FORCE_SERVER` environment variable to force the use of the local-listening server when using the `externalbrowser` auth method.
12
+ - This allows headless environments (like Docker or Airflow) running locally to auth via a browser URL.
13
+ - Fix compilation error when building from sources with libc++.
14
+ - Pin lower versions of dependencies to oldest version without vulnerabilities.
15
+ - Added no_proxy parameter for proxy configuration without using environmental variables.
16
+ - Added OAUTH_AUTHORIZATION_CODE and OAUTH_CLIENT_CREDENTIALS to list of authenticators that don't require user to be set
17
+ - Added `oauth_socket_uri` connection parameter allowing to separate server and redirect URIs for local OAuth server.
18
+ - Made platform_detection logs silent and improved its timeout handling. Added support for ENV_VAR_DISABLE_PLATFORM_DETECTION environment variable.
19
+ - Fixed FIPS environments md5 hash issues with multipart upload on Azure.
20
+
21
+ - v4.0.0(October 09,2025)
22
+ - Added support for checking certificates revocation using revocation lists (CRLs)
23
+ - Added `CERT_REVOCATION_CHECK_MODE` to `CLIENT_ENVIRONMENT`
24
+ - Added the `workload_identity_impersonation_path` parameter to support service account impersonation for Workload Identity Federation on GCP and AWS workloads only
25
+ - Fixed `get_results_from_sfqid` when using `DictCursor` and executing multiple statements at once
26
+ - Added the `oauth_credentials_in_body` parameter supporting an option to send the oauth client credentials in the request body
27
+ - Fix retry behavior for `ECONNRESET` error
28
+ - Added an option to exclude `botocore` and `boto3` dependencies by setting `SNOWFLAKE_NO_BOTO` environment variable during installation
29
+ - Revert changing exception type in case of token expired scenario for `Oauth` authenticator back to `DatabaseError`
30
+ - Enhanced configuration file security checks with stricter permission validation.
31
+ - Configuration files writable by group or others now raise a `ConfigSourceError` with detailed permission information, preventing potential credential tampering.
32
+ - Fixed the return type of `SnowflakeConnection.cursor(cursor_class)` to match the type of `cursor_class`
33
+ - Constrained the types of `fetchone`, `fetchmany`, `fetchall`
34
+ - As part of this fix, `DictCursor` is no longer a subclass of `SnowflakeCursor`; use `SnowflakeCursorBase` as a superclass of both.
35
+ - Fix "No AWS region was found" error if AWS region was set in `AWS_DEFAULT_REGION` variable instead of `AWS_REGION` for `WORKLOAD_IDENTITY` authenticator
36
+ - Add `ocsp_root_certs_dict_lock_timeout` connection parameter to set the timeout (in seconds) for acquiring the lock on the OCSP root certs dictionary. Default value for this parameter is -1 which indicates no timeout.
37
+ - Fixed behaviour of trying S3 Transfer Accelerate endpoint by default for internal stages, and always getting HTTP403 due to permissions missing on purpose. Now /accelerate is not attempted.
12
38
 
13
39
  - v3.18.0(October 03,2025)
14
40
  - Added support for pandas conversion for Day-time and Year-Month Interval types
@@ -16,6 +42,7 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
16
42
  - v3.17.4(September 22,2025)
17
43
  - Added support for intermediate certificates as roots when they are stored in the trust store
18
44
  - Bumped up vendored `urllib3` to `2.5.0` and `requests` to `v2.32.5`
45
+ - Dropped support for OpenSSL versions older than 1.1.1
19
46
 
20
47
  - v3.17.3(September 02,2025)
21
48
  - Enhanced configuration file permission warning messages.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snowflake-connector-python
3
- Version: 3.18.0
3
+ Version: 4.1.0
4
4
  Summary: Snowflake Connector for Python
5
5
  Home-page: https://www.snowflake.com/
6
6
  Author: Snowflake, Inc
@@ -39,24 +39,26 @@ Description-Content-Type: text/markdown
39
39
  License-File: LICENSE.txt
40
40
  License-File: NOTICE
41
41
  Requires-Dist: asn1crypto<2.0.0,>0.24.0
42
- Requires-Dist: boto3>=1.24
43
- Requires-Dist: botocore>=1.24
44
- Requires-Dist: cffi<2.0.0,>=1.9
45
- Requires-Dist: cryptography>=3.1.0
46
- Requires-Dist: pyOpenSSL<26.0.0,>=22.0.0
47
- Requires-Dist: pyjwt<3.0.0
42
+ Requires-Dist: cryptography>=44.0.1
43
+ Requires-Dist: pyOpenSSL<26.0.0,>=24.0.0
44
+ Requires-Dist: pyjwt<3.0.0,>=2.10.1
48
45
  Requires-Dist: pytz
49
- Requires-Dist: requests<3.0.0
46
+ Requires-Dist: requests<3.0.0,>=2.32.4
50
47
  Requires-Dist: packaging
51
48
  Requires-Dist: charset_normalizer<4,>=2
52
- Requires-Dist: idna<4,>=2.5
53
- Requires-Dist: urllib3<2.0.0,>=1.21.1; python_version < "3.10"
54
- Requires-Dist: certifi>=2017.4.17
49
+ Requires-Dist: idna<4,>=3.7
50
+ Requires-Dist: urllib3<2.0.0,>=1.26.5; python_version < "3.10"
51
+ Requires-Dist: certifi>=2024.7.4
55
52
  Requires-Dist: typing_extensions<5,>=4.3
56
53
  Requires-Dist: filelock<4,>=3.5
57
54
  Requires-Dist: sortedcontainers>=2.4.0
58
55
  Requires-Dist: platformdirs<5.0.0,>=2.6.0
59
56
  Requires-Dist: tomlkit
57
+ Requires-Dist: boto3>=1.24
58
+ Requires-Dist: botocore>=1.24
59
+ Provides-Extra: boto
60
+ Requires-Dist: boto3>=1.24; extra == "boto"
61
+ Requires-Dist: botocore>=1.24; extra == "boto"
60
62
  Provides-Extra: development
61
63
  Requires-Dist: Cython; extra == "development"
62
64
  Requires-Dist: coverage; extra == "development"
@@ -70,12 +72,14 @@ Requires-Dist: pytest-rerunfailures<16.0; extra == "development"
70
72
  Requires-Dist: pytest-timeout; extra == "development"
71
73
  Requires-Dist: pytest-xdist; extra == "development"
72
74
  Requires-Dist: pytzdata; extra == "development"
75
+ Requires-Dist: responses; extra == "development"
73
76
  Provides-Extra: pandas
74
77
  Requires-Dist: pandas<3.0.0,>=2.1.2; extra == "pandas"
75
- Requires-Dist: pyarrow; extra == "pandas"
78
+ Requires-Dist: pyarrow>=14.0.1; extra == "pandas"
76
79
  Provides-Extra: secure-local-storage
77
80
  Requires-Dist: keyring<26.0.0,>=23.1.0; extra == "secure-local-storage"
78
81
  Dynamic: license-file
82
+ Dynamic: requires-dist
79
83
 
80
84
  This package includes the Snowflake Connector for Python, which conforms to the Python DB API 2.0 specification:
81
85
  https://www.python.org/dev/peps/pep-0249/
@@ -86,8 +90,34 @@ https://docs.snowflake.com/
86
90
  Source code is also available at: https://github.com/snowflakedb/snowflake-connector-python
87
91
 
88
92
  # Release Notes
89
- - v3.19.0(TBD)
90
- - N/A
93
+ - v4.1.0(November 18,2025)
94
+ - Added the `SNOWFLAKE_AUTH_FORCE_SERVER` environment variable to force the use of the local-listening server when using the `externalbrowser` auth method.
95
+ - This allows headless environments (like Docker or Airflow) running locally to auth via a browser URL.
96
+ - Fix compilation error when building from sources with libc++.
97
+ - Pin lower versions of dependencies to oldest version without vulnerabilities.
98
+ - Added no_proxy parameter for proxy configuration without using environmental variables.
99
+ - Added OAUTH_AUTHORIZATION_CODE and OAUTH_CLIENT_CREDENTIALS to list of authenticators that don't require user to be set
100
+ - Added `oauth_socket_uri` connection parameter allowing to separate server and redirect URIs for local OAuth server.
101
+ - Made platform_detection logs silent and improved its timeout handling. Added support for ENV_VAR_DISABLE_PLATFORM_DETECTION environment variable.
102
+ - Fixed FIPS environments md5 hash issues with multipart upload on Azure.
103
+
104
+ - v4.0.0(October 09,2025)
105
+ - Added support for checking certificates revocation using revocation lists (CRLs)
106
+ - Added `CERT_REVOCATION_CHECK_MODE` to `CLIENT_ENVIRONMENT`
107
+ - Added the `workload_identity_impersonation_path` parameter to support service account impersonation for Workload Identity Federation on GCP and AWS workloads only
108
+ - Fixed `get_results_from_sfqid` when using `DictCursor` and executing multiple statements at once
109
+ - Added the `oauth_credentials_in_body` parameter supporting an option to send the oauth client credentials in the request body
110
+ - Fix retry behavior for `ECONNRESET` error
111
+ - Added an option to exclude `botocore` and `boto3` dependencies by setting `SNOWFLAKE_NO_BOTO` environment variable during installation
112
+ - Revert changing exception type in case of token expired scenario for `Oauth` authenticator back to `DatabaseError`
113
+ - Enhanced configuration file security checks with stricter permission validation.
114
+ - Configuration files writable by group or others now raise a `ConfigSourceError` with detailed permission information, preventing potential credential tampering.
115
+ - Fixed the return type of `SnowflakeConnection.cursor(cursor_class)` to match the type of `cursor_class`
116
+ - Constrained the types of `fetchone`, `fetchmany`, `fetchall`
117
+ - As part of this fix, `DictCursor` is no longer a subclass of `SnowflakeCursor`; use `SnowflakeCursorBase` as a superclass of both.
118
+ - Fix "No AWS region was found" error if AWS region was set in `AWS_DEFAULT_REGION` variable instead of `AWS_REGION` for `WORKLOAD_IDENTITY` authenticator
119
+ - Add `ocsp_root_certs_dict_lock_timeout` connection parameter to set the timeout (in seconds) for acquiring the lock on the OCSP root certs dictionary. Default value for this parameter is -1 which indicates no timeout.
120
+ - Fixed behaviour of trying S3 Transfer Accelerate endpoint by default for internal stages, and always getting HTTP403 due to permissions missing on purpose. Now /accelerate is not attempted.
91
121
 
92
122
  - v3.18.0(October 03,2025)
93
123
  - Added support for pandas conversion for Day-time and Year-Month Interval types
@@ -95,6 +125,7 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
95
125
  - v3.17.4(September 22,2025)
96
126
  - Added support for intermediate certificates as roots when they are stored in the trust store
97
127
  - Bumped up vendored `urllib3` to `2.5.0` and `requests` to `v2.32.5`
128
+ - Dropped support for OpenSSL versions older than 1.1.1
98
129
 
99
130
  - v3.17.3(September 02,2025)
100
131
  - Enhanced configuration file permission warning messages.
@@ -44,19 +44,16 @@ python_requires = >=3.9
44
44
  packages = find_namespace:
45
45
  install_requires =
46
46
  asn1crypto>0.24.0,<2.0.0
47
- boto3>=1.24
48
- botocore>=1.24
49
- cffi>=1.9,<2.0.0
50
- cryptography>=3.1.0
51
- pyOpenSSL>=22.0.0,<26.0.0
52
- pyjwt<3.0.0
47
+ cryptography>=44.0.1
48
+ pyOpenSSL>=24.0.0,<26.0.0
49
+ pyjwt>=2.10.1,<3.0.0
53
50
  pytz
54
- requests<3.0.0
51
+ requests>=2.32.4,<3.0.0
55
52
  packaging
56
53
  charset_normalizer>=2,<4
57
- idna>=2.5,<4
58
- urllib3>=1.21.1,<2.0.0; python_version < '3.10'
59
- certifi>=2017.4.17
54
+ idna>=3.7,<4
55
+ urllib3>=1.26.5,<2.0.0; python_version < '3.10'
56
+ certifi>=2024.7.4
60
57
  typing_extensions>=4.3,<5
61
58
  filelock>=3.5,<4
62
59
  sortedcontainers>=2.4.0
@@ -79,6 +76,9 @@ console_scripts =
79
76
  snowflake-dump-certs = snowflake.connector.tool.dump_certs:main
80
77
 
81
78
  [options.extras_require]
79
+ boto =
80
+ boto3>=1.24
81
+ botocore>=1.24
82
82
  development =
83
83
  Cython
84
84
  coverage
@@ -92,9 +92,10 @@ development =
92
92
  pytest-timeout
93
93
  pytest-xdist
94
94
  pytzdata
95
+ responses
95
96
  pandas =
96
97
  pandas>=2.1.2,<3.0.0
97
- pyarrow
98
+ pyarrow>=14.0.1
98
99
  secure-local-storage =
99
100
  keyring>=23.1.0,<26.0.0
100
101
 
@@ -5,6 +5,7 @@ import sys
5
5
  import warnings
6
6
 
7
7
  from setuptools import Extension, setup
8
+ from setuptools.command.egg_info import egg_info
8
9
 
9
10
  CONNECTOR_SRC_DIR = os.path.join("src", "snowflake", "connector")
10
11
  NANOARROW_SRC_DIR = os.path.join(CONNECTOR_SRC_DIR, "nanoarrow_cpp", "ArrowIterator")
@@ -38,9 +39,14 @@ for flag in options_def:
38
39
  extensions = None
39
40
  cmd_class = {}
40
41
 
41
- SNOWFLAKE_DISABLE_COMPILE_ARROW_EXTENSIONS = os.environ.get(
42
- "SNOWFLAKE_DISABLE_COMPILE_ARROW_EXTENSIONS", "false"
43
- ).lower() in ("y", "yes", "t", "true", "1", "on")
42
+ _POSITIVE_VALUES = ("y", "yes", "t", "true", "1", "on")
43
+ SNOWFLAKE_DISABLE_COMPILE_ARROW_EXTENSIONS = (
44
+ os.environ.get("SNOWFLAKE_DISABLE_COMPILE_ARROW_EXTENSIONS", "false").lower()
45
+ in _POSITIVE_VALUES
46
+ )
47
+ SNOWFLAKE_NO_BOTO = (
48
+ os.environ.get("SNOWFLAKE_NO_BOTO", "false").lower() in _POSITIVE_VALUES
49
+ )
44
50
 
45
51
  try:
46
52
  from Cython.Build import cythonize
@@ -88,7 +94,7 @@ if _ABLE_TO_COMPILE_EXTENSIONS and not SNOWFLAKE_DISABLE_COMPILE_ARROW_EXTENSION
88
94
  ext.sources += [
89
95
  os.path.join(
90
96
  NANOARROW_ARROW_ITERATOR_SRC_DIR,
91
- *((file,) if isinstance(file, str) else file)
97
+ *((file,) if isinstance(file, str) else file),
92
98
  )
93
99
  for file in {
94
100
  "ArrayConverter.cpp",
@@ -174,6 +180,22 @@ if _ABLE_TO_COMPILE_EXTENSIONS and not SNOWFLAKE_DISABLE_COMPILE_ARROW_EXTENSION
174
180
 
175
181
  cmd_class = {"build_ext": MyBuildExt}
176
182
 
183
+
184
+ class SetDefaultInstallationExtras(egg_info):
185
+ """Adds AWS extra unless SNOWFLAKE_NO_BOTO is specified."""
186
+
187
+ def finalize_options(self):
188
+ super().finalize_options()
189
+
190
+ # if not explicitly excluded, add boto dependencies to install_requires
191
+ if not SNOWFLAKE_NO_BOTO:
192
+ boto_extras = self.distribution.extras_require.get("boto", [])
193
+ self.distribution.install_requires += boto_extras
194
+
195
+
196
+ # Update command classes
197
+ cmd_class["egg_info"] = SetDefaultInstallationExtras
198
+
177
199
  setup(
178
200
  version=version,
179
201
  ext_modules=extensions,
@@ -53,11 +53,14 @@ from ..network import (
53
53
  ReauthenticationRequest,
54
54
  )
55
55
  from ..platform_detection import detect_platforms
56
- from ..session_manager import SessionManager
56
+ from ..session_manager import BaseHttpConfig, HttpConfig
57
+ from ..session_manager import SessionManager as SyncSessionManager
58
+ from ..session_manager import SessionManagerFactory
57
59
  from ..sqlstate import SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED
58
60
  from ..token_cache import TokenCache, TokenKey, TokenType
59
61
  from ..version import VERSION
60
62
  from .no_auth import AuthNoAuth
63
+ from .oauth import AuthByOAuth
61
64
 
62
65
  if TYPE_CHECKING:
63
66
  from . import AuthByPlugin
@@ -100,12 +103,22 @@ class Auth:
100
103
  internal_application_name,
101
104
  internal_application_version,
102
105
  ocsp_mode,
106
+ cert_revocation_check_mode,
103
107
  login_timeout: int | None = None,
104
108
  network_timeout: int | None = None,
105
109
  socket_timeout: int | None = None,
106
110
  platform_detection_timeout_seconds: float | None = None,
107
- session_manager: SessionManager | None = None,
111
+ session_manager: SyncSessionManager | None = None,
112
+ http_config: BaseHttpConfig | None = None,
108
113
  ):
114
+ # Create sync SessionManager for platform detection if config is provided
115
+ # Platform detection runs in threads and uses sync SessionManager
116
+ if http_config is not None and session_manager is None:
117
+ # Extract base fields (automatically excludes subclass-specific fields)
118
+ # Note: It won't be possible to pass adapter_factory from outer async-code to this part of code
119
+ sync_config = HttpConfig(**http_config.to_base_dict())
120
+ session_manager = SessionManagerFactory.get_manager(config=sync_config)
121
+
109
122
  return {
110
123
  "data": {
111
124
  "CLIENT_APP_ID": internal_application_name,
@@ -122,6 +135,7 @@ class Auth:
122
135
  "PYTHON_RUNTIME": IMPLEMENTATION,
123
136
  "PYTHON_COMPILER": COMPILER,
124
137
  "OCSP_MODE": ocsp_mode.name,
138
+ "CERT_REVOCATION_CHECK_MODE": cert_revocation_check_mode,
125
139
  "TRACING": logger.getEffectiveLevel(),
126
140
  "LOGIN_TIMEOUT": login_timeout,
127
141
  "NETWORK_TIMEOUT": network_timeout,
@@ -182,6 +196,7 @@ class Auth:
182
196
  self._rest._connection._internal_application_name,
183
197
  self._rest._connection._internal_application_version,
184
198
  self._rest._connection._ocsp_mode(),
199
+ self._rest._connection.cert_revocation_check_mode,
185
200
  self._rest._connection.login_timeout,
186
201
  self._rest._connection._network_timeout,
187
202
  self._rest._connection._socket_timeout,
@@ -373,7 +388,11 @@ class Auth:
373
388
  sqlstate=SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED,
374
389
  )
375
390
  )
376
- elif errno == OAUTH_ACCESS_TOKEN_EXPIRED_GS_CODE:
391
+ elif (errno == OAUTH_ACCESS_TOKEN_EXPIRED_GS_CODE) and (
392
+ # SNOW-2329031: OAuth v1.0 does not support token renewal,
393
+ # for backward compatibility, we do not raise an exception here
394
+ not isinstance(auth_instance, AuthByOAuth)
395
+ ):
377
396
  raise ReauthenticationRequest(
378
397
  ProgrammingError(
379
398
  msg=ret["message"],
@@ -495,6 +514,16 @@ class Auth:
495
514
  user: str,
496
515
  session_parameters: dict[str, Any],
497
516
  ) -> None:
517
+ """Attempt to load cached credentials to skip interactive authentication.
518
+
519
+ SSO (ID_TOKEN): If present, avoids opening browser for external authentication.
520
+ Controlled by client_store_temporary_credential parameter.
521
+
522
+ MFA (MFA_TOKEN): If present, skips MFA prompt on next connection.
523
+ Controlled by client_request_mfa_token parameter.
524
+
525
+ If cached tokens are expired/invalid, they're deleted and normal auth proceeds.
526
+ """
498
527
  if session_parameters.get(PARAMETER_CLIENT_STORE_TEMPORARY_CREDENTIAL, False):
499
528
  self._rest.id_token = self._read_temporary_credential(
500
529
  host,
@@ -530,6 +559,13 @@ class Auth:
530
559
  session_parameters: dict[str, Any],
531
560
  response: dict[str, Any],
532
561
  ) -> None:
562
+ """Cache credentials received from successful authentication for future use.
563
+
564
+ Tokens are only cached if:
565
+ 1. Server returned the token in response (server-side caching must be enabled)
566
+ 2. Client has caching enabled via session parameters
567
+ 3. User consented to caching (consent_cache_id_token for ID tokens)
568
+ """
533
569
  if (
534
570
  self._rest._connection.auth_class.consent_cache_id_token
535
571
  and session_parameters.get(
@@ -70,8 +70,10 @@ class AuthHttpServer:
70
70
  self,
71
71
  uri: str,
72
72
  buf_size: int = 16384,
73
+ redirect_uri: str | None = None,
73
74
  ) -> None:
74
75
  parsed_uri = urllib.parse.urlparse(uri)
76
+ parsed_redirect = urllib.parse.urlparse(redirect_uri) if redirect_uri else None
75
77
  self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
76
78
  self.buf_size = buf_size
77
79
  if os.getenv("SNOWFLAKE_AUTH_SOCKET_REUSE_PORT", "False").lower() == "true":
@@ -82,30 +84,34 @@ class AuthHttpServer:
82
84
  else:
83
85
  self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
84
86
 
85
- port = parsed_uri.port or 0
87
+ if parsed_redirect and self._is_local_uri(parsed_redirect):
88
+ server_port = parsed_redirect.port or 0
89
+ else:
90
+ server_port = parsed_uri.port or 0
91
+
86
92
  for attempt in range(1, self.DEFAULT_MAX_ATTEMPTS + 1):
87
93
  try:
88
94
  self._socket.bind(
89
95
  (
90
96
  parsed_uri.hostname,
91
- port,
97
+ server_port,
92
98
  )
93
99
  )
94
100
  break
95
101
  except socket.gaierror as ex:
96
102
  logger.error(
97
- f"Failed to bind authorization callback server to port {port}: {ex}"
103
+ f"Failed to bind authorization callback server to port {server_port}: {ex}"
98
104
  )
99
105
  raise
100
106
  except OSError as ex:
101
107
  if attempt == self.DEFAULT_MAX_ATTEMPTS:
102
108
  logger.error(
103
- f"Failed to bind authorization callback server to port {port}: {ex}"
109
+ f"Failed to bind authorization callback server to port {server_port}: {ex}"
104
110
  )
105
111
  raise
106
112
  logger.warning(
107
113
  f"Attempt {attempt}/{self.DEFAULT_MAX_ATTEMPTS}. "
108
- f"Failed to bind authorization callback server to port {port}: {ex}"
114
+ f"Failed to bind authorization callback server to port {server_port}: {ex}"
109
115
  )
110
116
  time.sleep(self.PORT_BIND_TIMEOUT / self.PORT_BIND_MAX_ATTEMPTS)
111
117
  try:
@@ -114,16 +120,47 @@ class AuthHttpServer:
114
120
  logger.error(f"Failed to start listening for auth callback: {ex}")
115
121
  self.close()
116
122
  raise
117
- port = self._socket.getsockname()[1]
123
+
124
+ server_port = self._socket.getsockname()[1]
118
125
  self._uri = urllib.parse.ParseResult(
119
126
  scheme=parsed_uri.scheme,
120
- netloc=parsed_uri.hostname + ":" + str(port),
127
+ netloc=parsed_uri.hostname + ":" + str(server_port),
121
128
  path=parsed_uri.path,
122
129
  params=parsed_uri.params,
123
130
  query=parsed_uri.query,
124
131
  fragment=parsed_uri.fragment,
125
132
  )
126
133
 
134
+ if parsed_redirect:
135
+ if (
136
+ self._is_local_uri(parsed_redirect)
137
+ and server_port != parsed_redirect.port
138
+ ):
139
+ logger.debug(
140
+ f"Updating redirect port {parsed_redirect.port} to match the server port {server_port}."
141
+ )
142
+ self._redirect_uri = urllib.parse.ParseResult(
143
+ scheme=parsed_redirect.scheme,
144
+ netloc=parsed_redirect.hostname + ":" + str(server_port),
145
+ path=parsed_redirect.path,
146
+ params=parsed_redirect.params,
147
+ query=parsed_redirect.query,
148
+ fragment=parsed_redirect.fragment,
149
+ )
150
+ else:
151
+ self._redirect_uri = parsed_redirect
152
+ else:
153
+ # For backwards compatibility
154
+ self._redirect_uri = self._uri
155
+
156
+ @staticmethod
157
+ def _is_local_uri(uri):
158
+ return uri.hostname in ("localhost", "127.0.0.1")
159
+
160
+ @property
161
+ def redirect_uri(self) -> str | None:
162
+ return self._redirect_uri.geturl()
163
+
127
164
  @property
128
165
  def url(self) -> str:
129
166
  return self._uri.geturl()
@@ -35,6 +35,14 @@ logger = logging.getLogger(__name__)
35
35
 
36
36
 
37
37
  class _OAuthTokensMixin:
38
+ """Manages OAuth token caching to avoid repeated browser authentication flows.
39
+
40
+ Access tokens: Short-lived (typically 10 minutes), cached to avoid immediate re-auth.
41
+ Refresh tokens: Long-lived (hours/days), used to obtain new access tokens silently.
42
+
43
+ Tokens are cached per (user, IDP host) to support multiple OAuth providers/accounts.
44
+ """
45
+
38
46
  def __init__(
39
47
  self,
40
48
  token_cache: TokenCache | None,
@@ -77,12 +85,18 @@ class _OAuthTokensMixin:
77
85
  return self._token_cache.retrieve(key)
78
86
 
79
87
  def _pop_cached_access_token(self) -> bool:
80
- """Retrieves OAuth access token from the token cache if enabled"""
88
+ """Retrieves OAuth access token from the token cache if enabled, available and still valid.
89
+
90
+ Returns True if cached token found, allowing authentication to skip OAuth flow.
91
+ """
81
92
  self._access_token = self._pop_cached_token(self._get_access_token_cache_key())
82
93
  return self._access_token is not None
83
94
 
84
95
  def _pop_cached_refresh_token(self) -> bool:
85
- """Retrieves OAuth refresh token from the token cache if enabled"""
96
+ """Retrieves OAuth refresh token from the token cache (if enabled) to silently obtain new access token.
97
+
98
+ Returns True if refresh token found, enabling automatic token renewal without user interaction.
99
+ """
86
100
  if self._refresh_token_enabled:
87
101
  self._refresh_token = self._pop_cached_token(
88
102
  self._get_refresh_token_cache_key()
@@ -65,6 +65,7 @@ class AuthByOauthCode(AuthByOAuthBase):
65
65
  external_browser_timeout: int | None = None,
66
66
  enable_single_use_refresh_tokens: bool = False,
67
67
  connection: SnowflakeConnection | None = None,
68
+ uri: str | None = None,
68
69
  **kwargs,
69
70
  ) -> None:
70
71
  authentication_url, redirect_uri = self._validate_oauth_code_uris(
@@ -92,6 +93,7 @@ class AuthByOauthCode(AuthByOAuthBase):
92
93
  self._origin: str | None = None
93
94
  self._authentication_url = authentication_url
94
95
  self._redirect_uri = redirect_uri
96
+ self._uri = uri
95
97
  self._state = secrets.token_urlsafe(43)
96
98
  logger.debug("chose oauth state: %s", "".join("*" for _ in self._state))
97
99
  self._protocol = "http"
@@ -117,7 +119,10 @@ class AuthByOauthCode(AuthByOAuthBase):
117
119
  ) -> (str | None, str | None):
118
120
  """Web Browser based Authentication."""
119
121
  logger.debug("authenticating with OAuth authorization code flow")
120
- with AuthHttpServer(self._redirect_uri) as callback_server:
122
+ with AuthHttpServer(
123
+ redirect_uri=self._redirect_uri,
124
+ uri=self._uri or self._redirect_uri, # for backward compatibility
125
+ ) as callback_server:
121
126
  code = self._do_authorization_request(callback_server, conn)
122
127
  return self._do_token_request(code, callback_server, conn)
123
128
 
@@ -260,7 +265,7 @@ You can close this window now and go back where you started from.
260
265
  connection: SnowflakeConnection,
261
266
  ) -> str | None:
262
267
  authorization_request = self._construct_authorization_request(
263
- callback_server.url
268
+ callback_server.redirect_uri
264
269
  )
265
270
  logger.debug("step 1: going to open authorization URL")
266
271
  print(
@@ -315,7 +320,7 @@ You can close this window now and go back where you started from.
315
320
  fields = {
316
321
  "grant_type": "authorization_code",
317
322
  "code": code,
318
- "redirect_uri": callback_server.url,
323
+ "redirect_uri": callback_server.redirect_uri,
319
324
  }
320
325
  if self._enable_single_use_refresh_tokens:
321
326
  fields["enable_single_use_refresh_tokens"] = "true"
@@ -27,6 +27,7 @@ class AuthByOauthCredentials(AuthByOAuthBase):
27
27
  token_request_url: str,
28
28
  scope: str,
29
29
  connection: SnowflakeConnection | None = None,
30
+ credentials_in_body: bool = False,
30
31
  **kwargs,
31
32
  ) -> None:
32
33
  self._validate_client_credentials_present(client_id, client_secret, connection)
@@ -40,6 +41,7 @@ class AuthByOauthCredentials(AuthByOAuthBase):
40
41
  **kwargs,
41
42
  )
42
43
  self._application = application
44
+ self._credentials_in_body = credentials_in_body
43
45
  self._origin: str | None = None
44
46
 
45
47
  def _get_oauth_type_id(self) -> str:
@@ -60,4 +62,7 @@ class AuthByOauthCredentials(AuthByOAuthBase):
60
62
  "grant_type": "client_credentials",
61
63
  "scope": self._scope,
62
64
  }
65
+ if self._credentials_in_body:
66
+ fields["client_id"] = self._client_id
67
+ fields["client_secret"] = self._client_secret
63
68
  return self._get_request_token_response(conn, fields)
@@ -166,6 +166,7 @@ class AuthByOkta(AuthByPlugin):
166
166
  conn._internal_application_name,
167
167
  conn._internal_application_version,
168
168
  conn._ocsp_mode(),
169
+ conn.cert_revocation_check_mode,
169
170
  conn.login_timeout,
170
171
  conn.network_timeout,
171
172
  conn.socket_timeout,
@@ -165,15 +165,26 @@ class AuthByWebBrowser(AuthByPlugin):
165
165
  return
166
166
 
167
167
  print(
168
- "Initiating login request with your identity provider. A "
169
- "browser window should have opened for you to complete the "
170
- "login. If you can't see it, check existing browser windows, "
171
- "or your OS settings. Press CTRL+C to abort and try again..."
168
+ "Initiating login request with your identity provider. Press CTRL+C to abort and try again..."
172
169
  )
173
170
 
174
171
  logger.debug("step 2: open a browser")
175
172
  print(f"Going to open: {sso_url} to authenticate...")
176
- if not self._webbrowser.open_new(sso_url):
173
+ browser_opened = self._webbrowser.open_new(sso_url)
174
+ if browser_opened:
175
+ print(
176
+ "A browser window should have opened for you to complete the "
177
+ "login. If you can't see it, check existing browser windows, "
178
+ "or your OS settings."
179
+ )
180
+
181
+ if (
182
+ browser_opened
183
+ or os.getenv("SNOWFLAKE_AUTH_FORCE_SERVER", "False").lower() == "true"
184
+ ):
185
+ logger.debug("step 3: accept SAML token")
186
+ self._receive_saml_token(conn, socket_connection)
187
+ else:
177
188
  print(
178
189
  "We were unable to open a browser window for you, "
179
190
  "please open the url above manually then paste the "
@@ -195,9 +206,6 @@ class AuthByWebBrowser(AuthByPlugin):
195
206
  },
196
207
  )
197
208
  return
198
- else:
199
- logger.debug("step 3: accept SAML token")
200
- self._receive_saml_token(conn, socket_connection)
201
209
  finally:
202
210
  socket_connection.close()
203
211
 
@@ -460,6 +468,7 @@ You can close this window now and go back where you started from.
460
468
  conn._internal_application_name,
461
469
  conn._internal_application_version,
462
470
  conn._ocsp_mode(),
471
+ conn.cert_revocation_check_mode,
463
472
  conn.login_timeout,
464
473
  conn.network_timeout,
465
474
  conn.socket_timeout,
@@ -55,12 +55,14 @@ class AuthByWorkloadIdentity(AuthByPlugin):
55
55
  provider: AttestationProvider | None = None,
56
56
  token: str | None = None,
57
57
  entra_resource: str | None = None,
58
+ impersonation_path: list[str] | None = None,
58
59
  **kwargs,
59
60
  ) -> None:
60
61
  super().__init__(**kwargs)
61
62
  self.provider = provider
62
63
  self.token = token
63
64
  self.entra_resource = entra_resource
65
+ self.impersonation_path = impersonation_path
64
66
 
65
67
  self.attestation: WorkloadIdentityAttestation | None = None
66
68
 
@@ -76,6 +78,9 @@ class AuthByWorkloadIdentity(AuthByPlugin):
76
78
  self.attestation
77
79
  ).value
78
80
  body["data"]["TOKEN"] = self.attestation.credential
81
+ body["data"].setdefault("CLIENT_ENVIRONMENT", {})[
82
+ "WORKLOAD_IDENTITY_IMPERSONATION_PATH_LENGTH"
83
+ ] = len(self.impersonation_path or [])
79
84
 
80
85
  def prepare(
81
86
  self, *, conn: SnowflakeConnection | None, **kwargs: typing.Any
@@ -85,6 +90,7 @@ class AuthByWorkloadIdentity(AuthByPlugin):
85
90
  self.provider,
86
91
  self.entra_resource,
87
92
  self.token,
93
+ self.impersonation_path,
88
94
  session_manager=(
89
95
  conn._session_manager.clone(max_retries=0) if conn else None
90
96
  ),