snowflake-connector-python 3.18.0__tar.gz → 4.0.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.
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/DESCRIPTION.md +20 -2
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/PKG-INFO +28 -6
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/setup.cfg +4 -3
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/setup.py +26 -4
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/_auth.py +9 -1
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/oauth_credentials.py +5 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/okta.py +1 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/webbrowser.py +1 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/workload_identity.py +6 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/config_manager.py +13 -1
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/connection.py +171 -5
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/constants.py +3 -0
- snowflake_connector_python-4.0.0/src/snowflake/connector/crl.py +703 -0
- snowflake_connector_python-4.0.0/src/snowflake/connector/crl_cache.py +643 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/cursor.py +88 -43
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/network.py +22 -1
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/ocsp_snowflake.py +73 -58
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/options.py +23 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/platform_detection.py +16 -3
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/s3_storage_client.py +12 -3
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/session_manager.py +1 -1
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/ssl_wrap_socket.py +57 -6
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/version.py +1 -1
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/wif_util.py +131 -20
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake_connector_python.egg-info/PKG-INFO +28 -6
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake_connector_python.egg-info/SOURCES.txt +2 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake_connector_python.egg-info/requires.txt +7 -3
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/CONTRIBUTING.md +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/LICENSE.txt +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/MANIFEST.in +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/NOTICE +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/README.md +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/SECURITY.md +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/pyproject.toml +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/_query_context_cache.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/_sql_util.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/_utils.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/arrow_context.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/_http_server.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/_oauth_base.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/by_plugin.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/default.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/idtoken.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/keypair.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/no_auth.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/oauth.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/oauth_code.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/pat.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/auth/usrpwdmfa.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/azure_storage_client.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/backoff_policies.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/bind_upload_agent.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/cache.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/compat.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/connection_diagnostic.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/converter.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/converter_issue23517.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/converter_null.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/converter_snowsql.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/dbapi.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/description.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/direct_file_operation_utils.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/encryption_util.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/errorcode.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/errors.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/externals_utils/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/externals_utils/externals_setup.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/feature.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/file_compression_type.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/file_lock.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/file_transfer_agent.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/file_util.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/gcs_storage_client.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/gzip_decoder.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/interval_util.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/local_storage_client.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/log_configuration.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/logging_utils/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/logging_utils/filters.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/ocsp_asn1crypto.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/pandas_tools.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/proxy.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/py.typed +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/result_batch.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/result_set.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/secret_detector.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/sf_dirs.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/sfbinaryformat.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/sfdatetime.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/snow_logging.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/sqlstate.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/ssd_internal_keys.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/storage_client.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/telemetry.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/telemetry_oob.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/test_util.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/time_util.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/token_cache.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/tool/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/tool/dump_certs.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/tool/dump_ocsp_response.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/tool/dump_ocsp_response_cache.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/tool/probe_connection.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/url_util.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/util_text.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/LICENSE +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/__version__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/_internal_utils.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/adapters.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/api.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/auth.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/certs.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/compat.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/cookies.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/exceptions.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/help.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/hooks.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/models.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/packages.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/sessions.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/status_codes.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/structures.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/requests/utils.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/LICENSE.txt +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/_base_connection.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/_collections.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/_request_methods.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/_version.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/connection.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/connectionpool.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/connection.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/emscripten_fetch_worker.js +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/fetch.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/request.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/contrib/emscripten/response.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/contrib/socks.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/exceptions.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/fields.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/filepost.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/http2/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/http2/connection.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/http2/probe.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/poolmanager.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/py.typed +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/response.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/__init__.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/connection.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/proxy.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/request.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/response.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/retry.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/ssl_.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/ssltransport.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/timeout.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/url.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/util.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake/connector/vendored/urllib3/util/wait.py +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake_connector_python.egg-info/dependency_links.txt +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake_connector_python.egg-info/entry_points.txt +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake_connector_python.egg-info/not-zip-safe +0 -0
- {snowflake_connector_python-3.18.0 → snowflake_connector_python-4.0.0}/src/snowflake_connector_python.egg-info/top_level.txt +0 -0
|
@@ -7,8 +7,25 @@ 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
|
-
-
|
|
11
|
-
|
|
10
|
+
- v4.1.0(TBD)
|
|
11
|
+
|
|
12
|
+
- v4.0.0(October 09,2025)
|
|
13
|
+
- Added support for checking certificates revocation using revocation lists (CRLs)
|
|
14
|
+
- Added `CERT_REVOCATION_CHECK_MODE` to `CLIENT_ENVIRONMENT`
|
|
15
|
+
- Added the `workload_identity_impersonation_path` parameter to support service account impersonation for Workload Identity Federation on GCP and AWS workloads only
|
|
16
|
+
- Fixed `get_results_from_sfqid` when using `DictCursor` and executing multiple statements at once
|
|
17
|
+
- Added the `oauth_credentials_in_body` parameter supporting an option to send the oauth client credentials in the request body
|
|
18
|
+
- Fix retry behavior for `ECONNRESET` error
|
|
19
|
+
- Added an option to exclude `botocore` and `boto3` dependencies by setting `SNOWFLAKE_NO_BOTO` environment variable during installation
|
|
20
|
+
- Revert changing exception type in case of token expired scenario for `Oauth` authenticator back to `DatabaseError`
|
|
21
|
+
- Enhanced configuration file security checks with stricter permission validation.
|
|
22
|
+
- Configuration files writable by group or others now raise a `ConfigSourceError` with detailed permission information, preventing potential credential tampering.
|
|
23
|
+
- Fixed the return type of `SnowflakeConnection.cursor(cursor_class)` to match the type of `cursor_class`
|
|
24
|
+
- Constrained the types of `fetchone`, `fetchmany`, `fetchall`
|
|
25
|
+
- As part of this fix, `DictCursor` is no longer a subclass of `SnowflakeCursor`; use `SnowflakeCursorBase` as a superclass of both.
|
|
26
|
+
- 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
|
|
27
|
+
- 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.
|
|
28
|
+
- 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
29
|
|
|
13
30
|
- v3.18.0(October 03,2025)
|
|
14
31
|
- Added support for pandas conversion for Day-time and Year-Month Interval types
|
|
@@ -16,6 +33,7 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
|
|
|
16
33
|
- v3.17.4(September 22,2025)
|
|
17
34
|
- Added support for intermediate certificates as roots when they are stored in the trust store
|
|
18
35
|
- Bumped up vendored `urllib3` to `2.5.0` and `requests` to `v2.32.5`
|
|
36
|
+
- Dropped support for OpenSSL versions older than 1.1.1
|
|
19
37
|
|
|
20
38
|
- v3.17.3(September 02,2025)
|
|
21
39
|
- 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
|
+
Version: 4.0.0
|
|
4
4
|
Summary: Snowflake Connector for Python
|
|
5
5
|
Home-page: https://www.snowflake.com/
|
|
6
6
|
Author: Snowflake, Inc
|
|
@@ -39,9 +39,6 @@ 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
42
|
Requires-Dist: cryptography>=3.1.0
|
|
46
43
|
Requires-Dist: pyOpenSSL<26.0.0,>=22.0.0
|
|
47
44
|
Requires-Dist: pyjwt<3.0.0
|
|
@@ -57,6 +54,11 @@ 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
78
|
Requires-Dist: pyarrow; 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,25 @@ 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
|
-
-
|
|
90
|
-
|
|
93
|
+
- v4.1.0(TBD)
|
|
94
|
+
|
|
95
|
+
- v4.0.0(October 09,2025)
|
|
96
|
+
- Added support for checking certificates revocation using revocation lists (CRLs)
|
|
97
|
+
- Added `CERT_REVOCATION_CHECK_MODE` to `CLIENT_ENVIRONMENT`
|
|
98
|
+
- Added the `workload_identity_impersonation_path` parameter to support service account impersonation for Workload Identity Federation on GCP and AWS workloads only
|
|
99
|
+
- Fixed `get_results_from_sfqid` when using `DictCursor` and executing multiple statements at once
|
|
100
|
+
- Added the `oauth_credentials_in_body` parameter supporting an option to send the oauth client credentials in the request body
|
|
101
|
+
- Fix retry behavior for `ECONNRESET` error
|
|
102
|
+
- Added an option to exclude `botocore` and `boto3` dependencies by setting `SNOWFLAKE_NO_BOTO` environment variable during installation
|
|
103
|
+
- Revert changing exception type in case of token expired scenario for `Oauth` authenticator back to `DatabaseError`
|
|
104
|
+
- Enhanced configuration file security checks with stricter permission validation.
|
|
105
|
+
- Configuration files writable by group or others now raise a `ConfigSourceError` with detailed permission information, preventing potential credential tampering.
|
|
106
|
+
- Fixed the return type of `SnowflakeConnection.cursor(cursor_class)` to match the type of `cursor_class`
|
|
107
|
+
- Constrained the types of `fetchone`, `fetchmany`, `fetchall`
|
|
108
|
+
- As part of this fix, `DictCursor` is no longer a subclass of `SnowflakeCursor`; use `SnowflakeCursorBase` as a superclass of both.
|
|
109
|
+
- 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
|
|
110
|
+
- 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.
|
|
111
|
+
- 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
112
|
|
|
92
113
|
- v3.18.0(October 03,2025)
|
|
93
114
|
- Added support for pandas conversion for Day-time and Year-Month Interval types
|
|
@@ -95,6 +116,7 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
|
|
|
95
116
|
- v3.17.4(September 22,2025)
|
|
96
117
|
- Added support for intermediate certificates as roots when they are stored in the trust store
|
|
97
118
|
- Bumped up vendored `urllib3` to `2.5.0` and `requests` to `v2.32.5`
|
|
119
|
+
- Dropped support for OpenSSL versions older than 1.1.1
|
|
98
120
|
|
|
99
121
|
- v3.17.3(September 02,2025)
|
|
100
122
|
- Enhanced configuration file permission warning messages.
|
|
@@ -44,9 +44,6 @@ 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
47
|
cryptography>=3.1.0
|
|
51
48
|
pyOpenSSL>=22.0.0,<26.0.0
|
|
52
49
|
pyjwt<3.0.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,6 +92,7 @@ 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
98
|
pyarrow
|
|
@@ -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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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,
|
|
@@ -58,6 +58,7 @@ from ..sqlstate import SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED
|
|
|
58
58
|
from ..token_cache import TokenCache, TokenKey, TokenType
|
|
59
59
|
from ..version import VERSION
|
|
60
60
|
from .no_auth import AuthNoAuth
|
|
61
|
+
from .oauth import AuthByOAuth
|
|
61
62
|
|
|
62
63
|
if TYPE_CHECKING:
|
|
63
64
|
from . import AuthByPlugin
|
|
@@ -100,6 +101,7 @@ class Auth:
|
|
|
100
101
|
internal_application_name,
|
|
101
102
|
internal_application_version,
|
|
102
103
|
ocsp_mode,
|
|
104
|
+
cert_revocation_check_mode,
|
|
103
105
|
login_timeout: int | None = None,
|
|
104
106
|
network_timeout: int | None = None,
|
|
105
107
|
socket_timeout: int | None = None,
|
|
@@ -122,6 +124,7 @@ class Auth:
|
|
|
122
124
|
"PYTHON_RUNTIME": IMPLEMENTATION,
|
|
123
125
|
"PYTHON_COMPILER": COMPILER,
|
|
124
126
|
"OCSP_MODE": ocsp_mode.name,
|
|
127
|
+
"CERT_REVOCATION_CHECK_MODE": cert_revocation_check_mode,
|
|
125
128
|
"TRACING": logger.getEffectiveLevel(),
|
|
126
129
|
"LOGIN_TIMEOUT": login_timeout,
|
|
127
130
|
"NETWORK_TIMEOUT": network_timeout,
|
|
@@ -182,6 +185,7 @@ class Auth:
|
|
|
182
185
|
self._rest._connection._internal_application_name,
|
|
183
186
|
self._rest._connection._internal_application_version,
|
|
184
187
|
self._rest._connection._ocsp_mode(),
|
|
188
|
+
self._rest._connection.cert_revocation_check_mode,
|
|
185
189
|
self._rest._connection.login_timeout,
|
|
186
190
|
self._rest._connection._network_timeout,
|
|
187
191
|
self._rest._connection._socket_timeout,
|
|
@@ -373,7 +377,11 @@ class Auth:
|
|
|
373
377
|
sqlstate=SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED,
|
|
374
378
|
)
|
|
375
379
|
)
|
|
376
|
-
elif errno == OAUTH_ACCESS_TOKEN_EXPIRED_GS_CODE
|
|
380
|
+
elif (errno == OAUTH_ACCESS_TOKEN_EXPIRED_GS_CODE) and (
|
|
381
|
+
# SNOW-2329031: OAuth v1.0 does not support token renewal,
|
|
382
|
+
# for backward compatibility, we do not raise an exception here
|
|
383
|
+
not isinstance(auth_instance, AuthByOAuth)
|
|
384
|
+
):
|
|
377
385
|
raise ReauthenticationRequest(
|
|
378
386
|
ProgrammingError(
|
|
379
387
|
msg=ret["message"],
|
|
@@ -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)
|
|
@@ -460,6 +460,7 @@ You can close this window now and go back where you started from.
|
|
|
460
460
|
conn._internal_application_name,
|
|
461
461
|
conn._internal_application_version,
|
|
462
462
|
conn._ocsp_mode(),
|
|
463
|
+
conn.cert_revocation_check_mode,
|
|
463
464
|
conn.login_timeout,
|
|
464
465
|
conn.network_timeout,
|
|
465
466
|
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
|
),
|
|
@@ -27,7 +27,7 @@ _T = TypeVar("_T")
|
|
|
27
27
|
|
|
28
28
|
LOGGER = logging.getLogger(__name__)
|
|
29
29
|
READABLE_BY_OTHERS = stat.S_IRGRP | stat.S_IROTH
|
|
30
|
-
|
|
30
|
+
WRITABLE_BY_OTHERS = stat.S_IWGRP | stat.S_IWOTH
|
|
31
31
|
|
|
32
32
|
SKIP_WARNING_ENV_VAR = "SF_SKIP_WARNING_FOR_READ_PERMISSIONS_ON_CONFIG_FILE"
|
|
33
33
|
|
|
@@ -337,6 +337,18 @@ class ConfigManager:
|
|
|
337
337
|
)
|
|
338
338
|
continue
|
|
339
339
|
|
|
340
|
+
# Check for writable by others - this should raise an error
|
|
341
|
+
if (
|
|
342
|
+
not IS_WINDOWS # Skip checking on Windows
|
|
343
|
+
and sliceoptions.check_permissions # Skip checking if this file couldn't hold sensitive information
|
|
344
|
+
and filep.stat().st_mode & WRITABLE_BY_OTHERS != 0
|
|
345
|
+
):
|
|
346
|
+
file_stat = filep.stat()
|
|
347
|
+
file_permissions = oct(file_stat.st_mode)[-3:]
|
|
348
|
+
raise ConfigSourceError(
|
|
349
|
+
f"file '{str(filep)}' is writable by group or others — this poses a security risk because it allows unauthorized users to modify sensitive settings. Your Permission: {file_permissions}"
|
|
350
|
+
)
|
|
351
|
+
|
|
340
352
|
# Check for readable by others or wrong ownership - this should warn
|
|
341
353
|
if (
|
|
342
354
|
not IS_WINDOWS # Skip checking on Windows
|
|
@@ -8,6 +8,7 @@ import pathlib
|
|
|
8
8
|
import re
|
|
9
9
|
import sys
|
|
10
10
|
import traceback
|
|
11
|
+
import typing
|
|
11
12
|
import uuid
|
|
12
13
|
import warnings
|
|
13
14
|
import weakref
|
|
@@ -20,7 +21,16 @@ from io import StringIO
|
|
|
20
21
|
from logging import getLogger
|
|
21
22
|
from threading import Lock
|
|
22
23
|
from types import TracebackType
|
|
23
|
-
from typing import
|
|
24
|
+
from typing import (
|
|
25
|
+
Any,
|
|
26
|
+
Callable,
|
|
27
|
+
Generator,
|
|
28
|
+
Iterable,
|
|
29
|
+
Iterator,
|
|
30
|
+
NamedTuple,
|
|
31
|
+
Sequence,
|
|
32
|
+
TypeVar,
|
|
33
|
+
)
|
|
24
34
|
from uuid import UUID
|
|
25
35
|
|
|
26
36
|
from cryptography.hazmat.backends import default_backend
|
|
@@ -60,6 +70,7 @@ from .constants import (
|
|
|
60
70
|
_DOMAIN_NAME_MAP,
|
|
61
71
|
_OAUTH_DEFAULT_SCOPE,
|
|
62
72
|
ENV_VAR_PARTNER,
|
|
73
|
+
OCSP_ROOT_CERTS_DICT_LOCK_TIMEOUT_DEFAULT_NO_TIMEOUT,
|
|
63
74
|
PARAMETER_AUTOCOMMIT,
|
|
64
75
|
PARAMETER_CLIENT_PREFETCH_THREADS,
|
|
65
76
|
PARAMETER_CLIENT_REQUEST_MFA_TOKEN,
|
|
@@ -76,7 +87,8 @@ from .constants import (
|
|
|
76
87
|
QueryStatus,
|
|
77
88
|
)
|
|
78
89
|
from .converter import SnowflakeConverter
|
|
79
|
-
from .
|
|
90
|
+
from .crl import CRLConfig
|
|
91
|
+
from .cursor import LOG_MAX_QUERY_LENGTH, SnowflakeCursor, SnowflakeCursorBase
|
|
80
92
|
from .description import (
|
|
81
93
|
CLIENT_NAME,
|
|
82
94
|
CLIENT_VERSION,
|
|
@@ -125,6 +137,11 @@ from .url_util import extract_top_level_domain_from_hostname
|
|
|
125
137
|
from .util_text import construct_hostname, parse_account, split_statements
|
|
126
138
|
from .wif_util import AttestationProvider
|
|
127
139
|
|
|
140
|
+
if sys.version_info >= (3, 13) or typing.TYPE_CHECKING:
|
|
141
|
+
CursorCls = TypeVar("CursorCls", bound=SnowflakeCursorBase, default=SnowflakeCursor)
|
|
142
|
+
else:
|
|
143
|
+
CursorCls = TypeVar("CursorCls", bound=SnowflakeCursorBase)
|
|
144
|
+
|
|
128
145
|
DEFAULT_CLIENT_PREFETCH_THREADS = 4
|
|
129
146
|
MAX_CLIENT_PREFETCH_THREADS = 10
|
|
130
147
|
MAX_CLIENT_FETCH_THREADS = 1024
|
|
@@ -214,6 +231,7 @@ DEFAULT_CONFIGURATION: dict[str, tuple[Any, type | tuple[type, ...]]] = {
|
|
|
214
231
|
"authenticator": (DEFAULT_AUTHENTICATOR, (type(None), str)),
|
|
215
232
|
"workload_identity_provider": (None, (type(None), AttestationProvider)),
|
|
216
233
|
"workload_identity_entra_resource": (None, (type(None), str)),
|
|
234
|
+
"workload_identity_impersonation_path": (None, (type(None), list[str])),
|
|
217
235
|
"mfa_callback": (None, (type(None), Callable)),
|
|
218
236
|
"password_callback": (None, (type(None), Callable)),
|
|
219
237
|
"auth_class": (None, (type(None), AuthByPlugin)),
|
|
@@ -226,6 +244,10 @@ DEFAULT_CONFIGURATION: dict[str, tuple[Any, type | tuple[type, ...]]] = {
|
|
|
226
244
|
"internal_application_version": (CLIENT_VERSION, (type(None), str)),
|
|
227
245
|
"disable_ocsp_checks": (False, bool),
|
|
228
246
|
"ocsp_fail_open": (True, bool), # fail open on ocsp issues, default true
|
|
247
|
+
"ocsp_root_certs_dict_lock_timeout": (
|
|
248
|
+
OCSP_ROOT_CERTS_DICT_LOCK_TIMEOUT_DEFAULT_NO_TIMEOUT, # no timeout
|
|
249
|
+
int,
|
|
250
|
+
),
|
|
229
251
|
"inject_client_pause": (0, int), # snowflake internal
|
|
230
252
|
"session_parameters": (None, (type(None), dict)), # snowflake session parameters
|
|
231
253
|
"autocommit": (None, (type(None), bool)), # snowflake
|
|
@@ -337,6 +359,11 @@ DEFAULT_CONFIGURATION: dict[str, tuple[Any, type | tuple[type, ...]]] = {
|
|
|
337
359
|
(type(None), str),
|
|
338
360
|
# SNOW-1825621: OAUTH implementation
|
|
339
361
|
),
|
|
362
|
+
"oauth_credentials_in_body": (
|
|
363
|
+
False,
|
|
364
|
+
bool,
|
|
365
|
+
# SNOW-2300649: Option to send client credentials in body
|
|
366
|
+
),
|
|
340
367
|
"oauth_authorization_url": (
|
|
341
368
|
"https://{host}:{port}/oauth/authorize",
|
|
342
369
|
str,
|
|
@@ -392,6 +419,43 @@ DEFAULT_CONFIGURATION: dict[str, tuple[Any, type | tuple[type, ...]]] = {
|
|
|
392
419
|
False,
|
|
393
420
|
bool,
|
|
394
421
|
),
|
|
422
|
+
# CRL (Certificate Revocation List) configuration parameters
|
|
423
|
+
# The default setup is specified in CRLConfig class
|
|
424
|
+
"cert_revocation_check_mode": (
|
|
425
|
+
None,
|
|
426
|
+
(type(None), str),
|
|
427
|
+
), # CRL revocation check mode: DISABLED, ENABLED, ADVISORY
|
|
428
|
+
"allow_certificates_without_crl_url": (
|
|
429
|
+
None,
|
|
430
|
+
(type(None), bool),
|
|
431
|
+
), # Allow certificates without CRL distribution points
|
|
432
|
+
"crl_connection_timeout_ms": (
|
|
433
|
+
None,
|
|
434
|
+
(type(None), int),
|
|
435
|
+
), # Connection timeout for CRL downloads in milliseconds
|
|
436
|
+
"crl_read_timeout_ms": (
|
|
437
|
+
None,
|
|
438
|
+
(type(None), int),
|
|
439
|
+
), # Read timeout for CRL downloads in milliseconds
|
|
440
|
+
"crl_cache_validity_hours": (
|
|
441
|
+
None,
|
|
442
|
+
(type(None), float),
|
|
443
|
+
), # CRL cache validity time in hours
|
|
444
|
+
"enable_crl_cache": (None, (type(None), bool)), # Enable CRL caching
|
|
445
|
+
"enable_crl_file_cache": (None, (type(None), bool)), # Enable file-based CRL cache
|
|
446
|
+
"crl_cache_dir": (None, (type(None), str)), # Directory for CRL file cache
|
|
447
|
+
"crl_cache_removal_delay_days": (
|
|
448
|
+
None,
|
|
449
|
+
(type(None), int),
|
|
450
|
+
), # Days to keep expired CRL files before removal
|
|
451
|
+
"crl_cache_cleanup_interval_hours": (
|
|
452
|
+
None,
|
|
453
|
+
(type(None), int),
|
|
454
|
+
), # CRL cache cleanup interval in hours
|
|
455
|
+
"crl_cache_start_cleanup": (
|
|
456
|
+
None,
|
|
457
|
+
(type(None), bool),
|
|
458
|
+
), # Run CRL cache cleanup in the background
|
|
395
459
|
}
|
|
396
460
|
|
|
397
461
|
APPLICATION_RE = re.compile(r"[\w\d_]+")
|
|
@@ -422,6 +486,7 @@ class SnowflakeConnection:
|
|
|
422
486
|
validates the TLS certificate but doesn't check revocation status with OCSP provider.
|
|
423
487
|
ocsp_fail_open: Whether or not the connection is in fail open mode. Fail open mode decides if TLS certificates
|
|
424
488
|
continue to be validated. Revoked certificates are blocked. Any other exceptions are disregarded.
|
|
489
|
+
ocsp_root_certs_dict_lock_timeout: Timeout for the OCSP root certs dict lock in seconds. Default value is -1, which means no timeout.
|
|
425
490
|
session_id: The session ID of the connection.
|
|
426
491
|
user: The user name used in the connection.
|
|
427
492
|
host: The host name the connection attempts to connect to.
|
|
@@ -528,6 +593,7 @@ class SnowflakeConnection:
|
|
|
528
593
|
|
|
529
594
|
# Placeholder attributes; will be initialized in connect()
|
|
530
595
|
self._http_config: HttpConfig | None = None
|
|
596
|
+
self._crl_config: CRLConfig | None = None
|
|
531
597
|
self._session_manager: SessionManager | None = None
|
|
532
598
|
self._rest: SnowflakeRestful | None = None
|
|
533
599
|
|
|
@@ -620,6 +686,86 @@ class SnowflakeConnection:
|
|
|
620
686
|
else:
|
|
621
687
|
return OCSPMode.FAIL_CLOSED
|
|
622
688
|
|
|
689
|
+
# CRL (Certificate Revocation List) configuration properties
|
|
690
|
+
@property
|
|
691
|
+
def cert_revocation_check_mode(self) -> str | None:
|
|
692
|
+
"""Certificate revocation check mode: DISABLED, ENABLED, or ADVISORY."""
|
|
693
|
+
if not self._crl_config:
|
|
694
|
+
return self._cert_revocation_check_mode
|
|
695
|
+
return self._crl_config.cert_revocation_check_mode.value
|
|
696
|
+
|
|
697
|
+
@property
|
|
698
|
+
def allow_certificates_without_crl_url(self) -> bool | None:
|
|
699
|
+
"""Whether to allow certificates without CRL distribution points."""
|
|
700
|
+
if not self._crl_config:
|
|
701
|
+
return self._allow_certificates_without_crl_url
|
|
702
|
+
return self._crl_config.allow_certificates_without_crl_url
|
|
703
|
+
|
|
704
|
+
@property
|
|
705
|
+
def crl_connection_timeout_ms(self) -> int | None:
|
|
706
|
+
"""Connection timeout for CRL downloads in milliseconds."""
|
|
707
|
+
if not self._crl_config:
|
|
708
|
+
return self._crl_connection_timeout_ms
|
|
709
|
+
return self._crl_config.connection_timeout_ms
|
|
710
|
+
|
|
711
|
+
@property
|
|
712
|
+
def crl_read_timeout_ms(self) -> int | None:
|
|
713
|
+
"""Read timeout for CRL downloads in milliseconds."""
|
|
714
|
+
if not self._crl_config:
|
|
715
|
+
return self._crl_read_timeout_ms
|
|
716
|
+
return self._crl_config.read_timeout_ms
|
|
717
|
+
|
|
718
|
+
@property
|
|
719
|
+
def crl_cache_validity_hours(self) -> float | None:
|
|
720
|
+
"""CRL cache validity time in hours."""
|
|
721
|
+
if not self._crl_config:
|
|
722
|
+
return self._crl_cache_validity_hours
|
|
723
|
+
return self._crl_config.cache_validity_time.total_seconds() / 3600
|
|
724
|
+
|
|
725
|
+
@property
|
|
726
|
+
def enable_crl_cache(self) -> bool | None:
|
|
727
|
+
"""Whether CRL caching is enabled."""
|
|
728
|
+
if not self._crl_config:
|
|
729
|
+
return self._enable_crl_cache
|
|
730
|
+
return self._crl_config.enable_crl_cache
|
|
731
|
+
|
|
732
|
+
@property
|
|
733
|
+
def enable_crl_file_cache(self) -> bool | None:
|
|
734
|
+
"""Whether file-based CRL cache is enabled."""
|
|
735
|
+
if not self._crl_config:
|
|
736
|
+
return self._enable_crl_file_cache
|
|
737
|
+
return self._crl_config.enable_crl_file_cache
|
|
738
|
+
|
|
739
|
+
@property
|
|
740
|
+
def crl_cache_dir(self) -> str | None:
|
|
741
|
+
"""Directory for CRL file cache."""
|
|
742
|
+
if not self._crl_config:
|
|
743
|
+
return self._crl_cache_dir
|
|
744
|
+
if not self._crl_config.crl_cache_dir:
|
|
745
|
+
return None
|
|
746
|
+
return str(self._crl_config.crl_cache_dir)
|
|
747
|
+
|
|
748
|
+
@property
|
|
749
|
+
def crl_cache_removal_delay_days(self) -> int | None:
|
|
750
|
+
"""Days to keep expired CRL files before removal."""
|
|
751
|
+
if not self._crl_config:
|
|
752
|
+
return self._crl_cache_removal_delay_days
|
|
753
|
+
return self._crl_config.crl_cache_removal_delay_days
|
|
754
|
+
|
|
755
|
+
@property
|
|
756
|
+
def crl_cache_cleanup_interval_hours(self) -> int | None:
|
|
757
|
+
"""CRL cache cleanup interval in hours."""
|
|
758
|
+
if not self._crl_config:
|
|
759
|
+
return self._crl_cache_cleanup_interval_hours
|
|
760
|
+
return self._crl_config.crl_cache_cleanup_interval_hours
|
|
761
|
+
|
|
762
|
+
@property
|
|
763
|
+
def crl_cache_start_cleanup(self) -> bool | None:
|
|
764
|
+
"""Whether to start CRL cache cleanup immediately."""
|
|
765
|
+
if not self._crl_config:
|
|
766
|
+
return self._crl_cache_start_cleanup
|
|
767
|
+
return self._crl_config.crl_cache_start_cleanup
|
|
768
|
+
|
|
623
769
|
@property
|
|
624
770
|
def session_id(self) -> int:
|
|
625
771
|
return self._session_id
|
|
@@ -921,6 +1067,8 @@ class SnowflakeConnection:
|
|
|
921
1067
|
if len(kwargs) > 0:
|
|
922
1068
|
self.__config(**kwargs)
|
|
923
1069
|
|
|
1070
|
+
self._crl_config: CRLConfig = CRLConfig.from_connection(self)
|
|
1071
|
+
|
|
924
1072
|
self._http_config = HttpConfig(
|
|
925
1073
|
adapter_factory=ProxySupportAdapterFactory(),
|
|
926
1074
|
use_pooling=(not self.disable_request_pooling),
|
|
@@ -1054,9 +1202,7 @@ class SnowflakeConnection:
|
|
|
1054
1202
|
"""Rolls back the current transaction."""
|
|
1055
1203
|
self.cursor().execute("ROLLBACK")
|
|
1056
1204
|
|
|
1057
|
-
def cursor(
|
|
1058
|
-
self, cursor_class: type[SnowflakeCursor] = SnowflakeCursor
|
|
1059
|
-
) -> SnowflakeCursor:
|
|
1205
|
+
def cursor(self, cursor_class: type[CursorCls] = SnowflakeCursor) -> CursorCls:
|
|
1060
1206
|
"""Creates a cursor object. Each statement will be executed in a new cursor object."""
|
|
1061
1207
|
logger.debug("cursor")
|
|
1062
1208
|
if not self.rest:
|
|
@@ -1311,6 +1457,7 @@ class SnowflakeConnection:
|
|
|
1311
1457
|
host=self.host, port=self.port
|
|
1312
1458
|
),
|
|
1313
1459
|
scope=self._oauth_scope,
|
|
1460
|
+
credentials_in_body=self._oauth_credentials_in_body,
|
|
1314
1461
|
connection=self,
|
|
1315
1462
|
)
|
|
1316
1463
|
elif self._authenticator == USR_PWD_MFA_AUTHENTICATOR:
|
|
@@ -1355,10 +1502,28 @@ class SnowflakeConnection:
|
|
|
1355
1502
|
"errno": ER_INVALID_WIF_SETTINGS,
|
|
1356
1503
|
},
|
|
1357
1504
|
)
|
|
1505
|
+
if (
|
|
1506
|
+
self._workload_identity_impersonation_path
|
|
1507
|
+
and self._workload_identity_provider
|
|
1508
|
+
not in (
|
|
1509
|
+
AttestationProvider.GCP,
|
|
1510
|
+
AttestationProvider.AWS,
|
|
1511
|
+
)
|
|
1512
|
+
):
|
|
1513
|
+
Error.errorhandler_wrapper(
|
|
1514
|
+
self,
|
|
1515
|
+
None,
|
|
1516
|
+
ProgrammingError,
|
|
1517
|
+
{
|
|
1518
|
+
"msg": "workload_identity_impersonation_path is currently only supported for GCP and AWS.",
|
|
1519
|
+
"errno": ER_INVALID_WIF_SETTINGS,
|
|
1520
|
+
},
|
|
1521
|
+
)
|
|
1358
1522
|
self.auth_class = AuthByWorkloadIdentity(
|
|
1359
1523
|
provider=self._workload_identity_provider,
|
|
1360
1524
|
token=self._token,
|
|
1361
1525
|
entra_resource=self._workload_identity_entra_resource,
|
|
1526
|
+
impersonation_path=self._workload_identity_impersonation_path,
|
|
1362
1527
|
)
|
|
1363
1528
|
else:
|
|
1364
1529
|
# okta URL, e.g., https://<account>.okta.com/
|
|
@@ -1531,6 +1696,7 @@ class SnowflakeConnection:
|
|
|
1531
1696
|
workload_identity_dependent_options = [
|
|
1532
1697
|
"workload_identity_provider",
|
|
1533
1698
|
"workload_identity_entra_resource",
|
|
1699
|
+
"workload_identity_impersonation_path",
|
|
1534
1700
|
]
|
|
1535
1701
|
for dependent_option in workload_identity_dependent_options:
|
|
1536
1702
|
if (
|