snowflake-connector-python 3.12.4__tar.gz → 3.13.1__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.12.4 → snowflake_connector_python-3.13.1}/DESCRIPTION.md +12 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/PKG-INFO +14 -2
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/README.md +20 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/__init__.py +3 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/_auth.py +6 -1
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/by_plugin.py +1 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/keypair.py +13 -2
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/oauth.py +1 -1
- snowflake_connector_python-3.13.1/src/snowflake/connector/auth/pat.py +43 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/cache.py +11 -3
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/connection.py +41 -6
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/cursor.py +15 -7
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/encryption_util.py +2 -1
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/errors.py +2 -3
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/file_transfer_agent.py +12 -2
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/file_util.py +4 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/network.py +1 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/ocsp_snowflake.py +161 -5
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/pandas_tools.py +93 -29
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/storage_client.py +7 -2
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/util_text.py +5 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/version.py +1 -1
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake_connector_python.egg-info/PKG-INFO +14 -2
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake_connector_python.egg-info/SOURCES.txt +1 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/CONTRIBUTING.md +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/LICENSE.txt +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/MANIFEST.in +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/NOTICE +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/SECURITY.md +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/pyproject.toml +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/setup.cfg +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/setup.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/_query_context_cache.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/_sql_util.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/_utils.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/arrow_context.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/default.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/idtoken.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/okta.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/usrpwdmfa.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/auth/webbrowser.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/azure_storage_client.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/backoff_policies.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/bind_upload_agent.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/compat.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/config_manager.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/connection_diagnostic.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/constants.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/converter.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/converter_issue23517.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/converter_null.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/converter_snowsql.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/dbapi.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/description.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/errorcode.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/feature.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/file_compression_type.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/gcs_storage_client.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/gzip_decoder.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/local_storage_client.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/log_configuration.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/ocsp_asn1crypto.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/options.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/proxy.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/py.typed +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/result_batch.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/result_set.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/s3_storage_client.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/secret_detector.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/sf_dirs.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/sfbinaryformat.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/sfdatetime.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/snow_logging.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/sqlstate.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/ssd_internal_keys.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/ssl_wrap_socket.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/telemetry.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/telemetry_oob.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/test_util.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/time_util.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/tool/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/tool/dump_certs.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/tool/dump_ocsp_response.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/tool/dump_ocsp_response_cache.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/tool/probe_connection.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/url_util.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/LICENSE +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/__version__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/_internal_utils.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/adapters.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/api.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/auth.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/certs.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/compat.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/cookies.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/exceptions.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/help.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/hooks.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/models.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/sessions.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/status_codes.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/structures.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/requests/utils.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/LICENSE.txt +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/_collections.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/_version.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/connection.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/connectionpool.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/_appengine_environ.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/_securetransport/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/_securetransport/bindings.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/_securetransport/low_level.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/appengine.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/ntlmpool.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/securetransport.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/contrib/socks.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/exceptions.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/fields.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/filepost.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/packages/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/packages/backports/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/packages/backports/makefile.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/packages/backports/weakref_finalize.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/packages/six.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/poolmanager.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/request.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/response.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/__init__.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/connection.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/proxy.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/queue.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/request.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/response.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/retry.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/ssl_.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/ssltransport.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/timeout.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/url.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake/connector/vendored/urllib3/util/wait.py +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake_connector_python.egg-info/dependency_links.txt +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake_connector_python.egg-info/entry_points.txt +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake_connector_python.egg-info/not-zip-safe +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake_connector_python.egg-info/requires.txt +0 -0
- {snowflake_connector_python-3.12.4 → snowflake_connector_python-3.13.1}/src/snowflake_connector_python.egg-info/top_level.txt +0 -0
|
@@ -8,6 +8,18 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
|
|
|
8
8
|
|
|
9
9
|
# Release Notes
|
|
10
10
|
|
|
11
|
+
- v3.13.1(January 29, 2025)
|
|
12
|
+
- Remedied SQL injection vulnerability in snowflake.connector.pandas_tools.write_pandas. See more https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-2vpq-fh52-j3wv
|
|
13
|
+
- Remedied vulnerability in deserialization of the OCSP response cache. See more: https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-m4f6-vcj4-w5mx
|
|
14
|
+
- Remedied vulnerability connected to cache files permissions. See more: https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-r2x6-cjg7-8r43
|
|
15
|
+
|
|
16
|
+
- v3.13.0(January 23,2025)
|
|
17
|
+
- Added a feature to limit the sizes of IO-bound ThreadPoolExecutors during PUT and GET commands.
|
|
18
|
+
- Updated README.md to include instructions on how to verify package signatures using `cosign`.
|
|
19
|
+
- Updated the log level for cursor's chunk rowcount from INFO to DEBUG.
|
|
20
|
+
- Added a feature to verify if the connection is still good enough to send queries over.
|
|
21
|
+
- Added support for base64-encoded DER private key strings in the `private_key` authentication type.
|
|
22
|
+
|
|
11
23
|
- v3.12.4(December 3,2024)
|
|
12
24
|
- Fixed a bug where multipart uploads to Azure would be missing their MD5 hashes.
|
|
13
25
|
- Fixed a bug where OpenTelemetry header injection would sometimes cause Exceptions to be thrown.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: snowflake-connector-python
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.13.1
|
|
4
4
|
Summary: Snowflake Connector for Python
|
|
5
5
|
Home-page: https://www.snowflake.com/
|
|
6
6
|
Author: Snowflake, Inc
|
|
@@ -85,6 +85,18 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
|
|
|
85
85
|
|
|
86
86
|
# Release Notes
|
|
87
87
|
|
|
88
|
+
- v3.13.1(January 29, 2025)
|
|
89
|
+
- Remedied SQL injection vulnerability in snowflake.connector.pandas_tools.write_pandas. See more https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-2vpq-fh52-j3wv
|
|
90
|
+
- Remedied vulnerability in deserialization of the OCSP response cache. See more: https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-m4f6-vcj4-w5mx
|
|
91
|
+
- Remedied vulnerability connected to cache files permissions. See more: https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-r2x6-cjg7-8r43
|
|
92
|
+
|
|
93
|
+
- v3.13.0(January 23,2025)
|
|
94
|
+
- Added a feature to limit the sizes of IO-bound ThreadPoolExecutors during PUT and GET commands.
|
|
95
|
+
- Updated README.md to include instructions on how to verify package signatures using `cosign`.
|
|
96
|
+
- Updated the log level for cursor's chunk rowcount from INFO to DEBUG.
|
|
97
|
+
- Added a feature to verify if the connection is still good enough to send queries over.
|
|
98
|
+
- Added support for base64-encoded DER private key strings in the `private_key` authentication type.
|
|
99
|
+
|
|
88
100
|
- v3.12.4(December 3,2024)
|
|
89
101
|
- Fixed a bug where multipart uploads to Azure would be missing their MD5 hashes.
|
|
90
102
|
- Fixed a bug where OpenTelemetry header injection would sometimes cause Exceptions to be thrown.
|
|
@@ -82,6 +82,26 @@ conn = snowflake.connector.connect(
|
|
|
82
82
|
conn.telemetry_enabled = False
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
## Verifying Package Signatures
|
|
86
|
+
|
|
87
|
+
To ensure the authenticity and integrity of the Python package, follow the steps below to verify the package signature using `cosign`.
|
|
88
|
+
|
|
89
|
+
**Steps to verify the signature:**
|
|
90
|
+
- Install cosign:
|
|
91
|
+
- This example is using golang installation: [installing-cosign-with-go](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-go)
|
|
92
|
+
- Download the file from the repository like pypi:
|
|
93
|
+
- https://pypi.org/project/snowflake-connector-python/#files
|
|
94
|
+
- Download the signature files from the release tag, replace the version number with the version you are verifying:
|
|
95
|
+
- https://github.com/snowflakedb/snowflake-connector-python/releases/tag/v3.12.2
|
|
96
|
+
- Verify signature:
|
|
97
|
+
````bash
|
|
98
|
+
# replace the version number with the version you are verifying
|
|
99
|
+
./cosign verify-blob snowflake_connector_python-3.12.2.tar.gz \
|
|
100
|
+
--key snowflake-connector-python-v3.12.2.pub \
|
|
101
|
+
--signature resources.linux.snowflake_connector_python-3.12.2.tar.gz.sig
|
|
102
|
+
|
|
103
|
+
Verified OK
|
|
104
|
+
````
|
|
85
105
|
|
|
86
106
|
## NOTE
|
|
87
107
|
|
|
@@ -11,6 +11,7 @@ from .idtoken import AuthByIdToken
|
|
|
11
11
|
from .keypair import AuthByKeyPair
|
|
12
12
|
from .oauth import AuthByOAuth
|
|
13
13
|
from .okta import AuthByOkta
|
|
14
|
+
from .pat import AuthByPAT
|
|
14
15
|
from .usrpwdmfa import AuthByUsrPwdMfa
|
|
15
16
|
from .webbrowser import AuthByWebBrowser
|
|
16
17
|
|
|
@@ -23,6 +24,7 @@ FIRST_PARTY_AUTHENTICATORS = frozenset(
|
|
|
23
24
|
AuthByUsrPwdMfa,
|
|
24
25
|
AuthByWebBrowser,
|
|
25
26
|
AuthByIdToken,
|
|
27
|
+
AuthByPAT,
|
|
26
28
|
)
|
|
27
29
|
)
|
|
28
30
|
|
|
@@ -30,6 +32,7 @@ __all__ = [
|
|
|
30
32
|
"AuthByPlugin",
|
|
31
33
|
"AuthByDefault",
|
|
32
34
|
"AuthByKeyPair",
|
|
35
|
+
"AuthByPAT",
|
|
33
36
|
"AuthByOAuth",
|
|
34
37
|
"AuthByOkta",
|
|
35
38
|
"AuthByUsrPwdMfa",
|
|
@@ -52,6 +52,7 @@ from ..errors import (
|
|
|
52
52
|
ProgrammingError,
|
|
53
53
|
ServiceUnavailableError,
|
|
54
54
|
)
|
|
55
|
+
from ..file_util import owner_rw_opener
|
|
55
56
|
from ..network import (
|
|
56
57
|
ACCEPT_TYPE_APPLICATION_SNOWFLAKE,
|
|
57
58
|
CONTENT_TYPE_APPLICATION_JSON,
|
|
@@ -625,7 +626,11 @@ def flush_temporary_credentials() -> None:
|
|
|
625
626
|
)
|
|
626
627
|
try:
|
|
627
628
|
with open(
|
|
628
|
-
TEMPORARY_CREDENTIAL_FILE,
|
|
629
|
+
TEMPORARY_CREDENTIAL_FILE,
|
|
630
|
+
"w",
|
|
631
|
+
encoding="utf-8",
|
|
632
|
+
errors="ignore",
|
|
633
|
+
opener=owner_rw_opener,
|
|
629
634
|
) as f:
|
|
630
635
|
json.dump(TEMPORARY_CREDENTIAL, f)
|
|
631
636
|
except Exception as ex:
|
|
@@ -43,7 +43,7 @@ class AuthByKeyPair(AuthByPlugin):
|
|
|
43
43
|
|
|
44
44
|
def __init__(
|
|
45
45
|
self,
|
|
46
|
-
private_key: bytes | RSAPrivateKey,
|
|
46
|
+
private_key: bytes | str | RSAPrivateKey,
|
|
47
47
|
lifetime_in_seconds: int = LIFETIME,
|
|
48
48
|
**kwargs,
|
|
49
49
|
) -> None:
|
|
@@ -75,7 +75,7 @@ class AuthByKeyPair(AuthByPlugin):
|
|
|
75
75
|
).total_seconds()
|
|
76
76
|
)
|
|
77
77
|
|
|
78
|
-
self._private_key: bytes | RSAPrivateKey | None = private_key
|
|
78
|
+
self._private_key: bytes | str | RSAPrivateKey | None = private_key
|
|
79
79
|
self._jwt_token = ""
|
|
80
80
|
self._jwt_token_exp = 0
|
|
81
81
|
self._lifetime = timedelta(
|
|
@@ -105,6 +105,17 @@ class AuthByKeyPair(AuthByPlugin):
|
|
|
105
105
|
|
|
106
106
|
now = datetime.now(timezone.utc).replace(tzinfo=None)
|
|
107
107
|
|
|
108
|
+
if isinstance(self._private_key, str):
|
|
109
|
+
try:
|
|
110
|
+
self._private_key = base64.b64decode(self._private_key)
|
|
111
|
+
except Exception as e:
|
|
112
|
+
raise ProgrammingError(
|
|
113
|
+
msg=f"Failed to decode private key: {e}\nPlease provide a valid "
|
|
114
|
+
"unencrypted rsa private key in base64-encoded DER format as a "
|
|
115
|
+
"str object",
|
|
116
|
+
errno=ER_INVALID_PRIVATE_KEY,
|
|
117
|
+
)
|
|
118
|
+
|
|
108
119
|
if isinstance(self._private_key, bytes):
|
|
109
120
|
try:
|
|
110
121
|
private_key = load_der_private_key(
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import typing
|
|
8
|
+
|
|
9
|
+
from snowflake.connector.network import PROGRAMMATIC_ACCESS_TOKEN
|
|
10
|
+
|
|
11
|
+
from .by_plugin import AuthByPlugin, AuthType
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AuthByPAT(AuthByPlugin):
|
|
15
|
+
|
|
16
|
+
def __init__(self, pat_token: str, **kwargs) -> None:
|
|
17
|
+
super().__init__(**kwargs)
|
|
18
|
+
self._pat_token: str | None = pat_token
|
|
19
|
+
|
|
20
|
+
def type_(self) -> AuthType:
|
|
21
|
+
return AuthType.PAT
|
|
22
|
+
|
|
23
|
+
def reset_secrets(self) -> None:
|
|
24
|
+
self._pat_token = None
|
|
25
|
+
|
|
26
|
+
def update_body(self, body: dict[typing.Any, typing.Any]) -> None:
|
|
27
|
+
body["data"]["AUTHENTICATOR"] = PROGRAMMATIC_ACCESS_TOKEN
|
|
28
|
+
body["data"]["TOKEN"] = self._pat_token
|
|
29
|
+
|
|
30
|
+
def prepare(
|
|
31
|
+
self,
|
|
32
|
+
**kwargs: typing.Any,
|
|
33
|
+
) -> None:
|
|
34
|
+
"""Nothing to do here, token should be obtained outside the driver."""
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
def reauthenticate(self, **kwargs: typing.Any) -> dict[str, bool]:
|
|
38
|
+
return {"success": False}
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def assertion_content(self) -> str | None:
|
|
42
|
+
"""Returns the token."""
|
|
43
|
+
return self._pat_token
|
|
@@ -388,6 +388,7 @@ class SFDictFileCache(SFDictCache):
|
|
|
388
388
|
file_path: str | dict[str, str],
|
|
389
389
|
entry_lifetime: int = constants.DAY_IN_SECONDS,
|
|
390
390
|
file_timeout: int = 0,
|
|
391
|
+
load_if_file_exists: bool = True,
|
|
391
392
|
) -> None:
|
|
392
393
|
"""Inits an SFDictFileCache with path, lifetime.
|
|
393
394
|
|
|
@@ -445,7 +446,7 @@ class SFDictFileCache(SFDictCache):
|
|
|
445
446
|
self._file_lock_path = f"{self.file_path}.lock"
|
|
446
447
|
self._file_lock = FileLock(self._file_lock_path, timeout=self.file_timeout)
|
|
447
448
|
self.last_loaded: datetime.datetime | None = None
|
|
448
|
-
if os.path.exists(self.file_path):
|
|
449
|
+
if os.path.exists(self.file_path) and load_if_file_exists:
|
|
449
450
|
with self._lock:
|
|
450
451
|
self._load()
|
|
451
452
|
# indicate whether the cache is modified or not, this variable is for
|
|
@@ -498,7 +499,7 @@ class SFDictFileCache(SFDictCache):
|
|
|
498
499
|
"""Load cache from disk if possible, returns whether it was able to load."""
|
|
499
500
|
try:
|
|
500
501
|
with open(self.file_path, "rb") as r_file:
|
|
501
|
-
other: SFDictFileCache =
|
|
502
|
+
other: SFDictFileCache = self._deserialize(r_file)
|
|
502
503
|
# Since we want to know whether we are dirty after loading
|
|
503
504
|
# we have to know whether the file could learn anything from self
|
|
504
505
|
# so instead of calling self.update we call other.update and swap
|
|
@@ -529,6 +530,13 @@ class SFDictFileCache(SFDictCache):
|
|
|
529
530
|
with self._lock:
|
|
530
531
|
return self._load()
|
|
531
532
|
|
|
533
|
+
def _serialize(self):
|
|
534
|
+
return pickle.dumps(self)
|
|
535
|
+
|
|
536
|
+
@classmethod
|
|
537
|
+
def _deserialize(cls, r_file):
|
|
538
|
+
return pickle.load(r_file)
|
|
539
|
+
|
|
532
540
|
def _save(self, load_first: bool = True, force_flush: bool = False) -> bool:
|
|
533
541
|
"""Save cache to disk if possible, returns whether it was able to save.
|
|
534
542
|
|
|
@@ -559,7 +567,7 @@ class SFDictFileCache(SFDictCache):
|
|
|
559
567
|
# python program.
|
|
560
568
|
# thus we fall back to the approach using the normal open() method to open a file and write.
|
|
561
569
|
with open(tmp_file, "wb") as w_file:
|
|
562
|
-
w_file.write(
|
|
570
|
+
w_file.write(self._serialize())
|
|
563
571
|
# We write to a tmp file and then move it to have atomic write
|
|
564
572
|
os.replace(tmp_file_path, self.file_path)
|
|
565
573
|
self.last_loaded = datetime.datetime.fromtimestamp(
|
|
@@ -41,6 +41,7 @@ from .auth import (
|
|
|
41
41
|
AuthByKeyPair,
|
|
42
42
|
AuthByOAuth,
|
|
43
43
|
AuthByOkta,
|
|
44
|
+
AuthByPAT,
|
|
44
45
|
AuthByPlugin,
|
|
45
46
|
AuthByUsrPwdMfa,
|
|
46
47
|
AuthByWebBrowser,
|
|
@@ -99,6 +100,7 @@ from .network import (
|
|
|
99
100
|
EXTERNAL_BROWSER_AUTHENTICATOR,
|
|
100
101
|
KEY_PAIR_AUTHENTICATOR,
|
|
101
102
|
OAUTH_AUTHENTICATOR,
|
|
103
|
+
PROGRAMMATIC_ACCESS_TOKEN,
|
|
102
104
|
REQUEST_ID,
|
|
103
105
|
USR_PWD_MFA_AUTHENTICATOR,
|
|
104
106
|
ReauthenticationRequest,
|
|
@@ -182,10 +184,14 @@ DEFAULT_CONFIGURATION: dict[str, tuple[Any, type | tuple[type, ...]]] = {
|
|
|
182
184
|
"backoff_policy": (DEFAULT_BACKOFF_POLICY, Callable),
|
|
183
185
|
"passcode_in_password": (False, bool), # Snowflake MFA
|
|
184
186
|
"passcode": (None, (type(None), str)), # Snowflake MFA
|
|
185
|
-
"private_key": (None, (type(None), bytes, RSAPrivateKey)),
|
|
187
|
+
"private_key": (None, (type(None), bytes, str, RSAPrivateKey)),
|
|
186
188
|
"private_key_file": (None, (type(None), str)),
|
|
187
189
|
"private_key_file_pwd": (None, (type(None), str, bytes)),
|
|
188
|
-
"token": (None, (type(None), str)), # OAuth
|
|
190
|
+
"token": (None, (type(None), str)), # OAuth/JWT/PAT Token
|
|
191
|
+
"token_file_path": (
|
|
192
|
+
None,
|
|
193
|
+
(type(None), str, bytes),
|
|
194
|
+
), # OAuth/JWT/PAT Token file path
|
|
189
195
|
"authenticator": (DEFAULT_AUTHENTICATOR, (type(None), str)),
|
|
190
196
|
"mfa_callback": (None, (type(None), Callable)),
|
|
191
197
|
"password_callback": (None, (type(None), Callable)),
|
|
@@ -294,6 +300,10 @@ DEFAULT_CONFIGURATION: dict[str, tuple[Any, type | tuple[type, ...]]] = {
|
|
|
294
300
|
False,
|
|
295
301
|
bool,
|
|
296
302
|
), # disable saml url check in okta authentication
|
|
303
|
+
"iobound_tpe_limit": (
|
|
304
|
+
None,
|
|
305
|
+
(type(None), int),
|
|
306
|
+
), # SNOW-1817982: limit iobound TPE sizes when executing PUT/GET
|
|
297
307
|
}
|
|
298
308
|
|
|
299
309
|
APPLICATION_RE = re.compile(r"[\w\d_]+")
|
|
@@ -726,6 +736,10 @@ class SnowflakeConnection:
|
|
|
726
736
|
def is_query_context_cache_disabled(self) -> bool:
|
|
727
737
|
return self._disable_query_context_cache
|
|
728
738
|
|
|
739
|
+
@property
|
|
740
|
+
def iobound_tpe_limit(self) -> int | None:
|
|
741
|
+
return self._iobound_tpe_limit
|
|
742
|
+
|
|
729
743
|
def connect(self, **kwargs) -> None:
|
|
730
744
|
"""Establishes connection to Snowflake."""
|
|
731
745
|
logger.debug("connect")
|
|
@@ -1089,6 +1103,8 @@ class SnowflakeConnection:
|
|
|
1089
1103
|
timeout=self.login_timeout,
|
|
1090
1104
|
backoff_generator=self._backoff_generator,
|
|
1091
1105
|
)
|
|
1106
|
+
elif self._authenticator == PROGRAMMATIC_ACCESS_TOKEN:
|
|
1107
|
+
self.auth_class = AuthByPAT(self._token)
|
|
1092
1108
|
else:
|
|
1093
1109
|
# okta URL, e.g., https://<account>.okta.com/
|
|
1094
1110
|
self.auth_class = AuthByOkta(
|
|
@@ -1237,11 +1253,12 @@ class SnowflakeConnection:
|
|
|
1237
1253
|
if (
|
|
1238
1254
|
self.auth_class is None
|
|
1239
1255
|
and self._authenticator
|
|
1240
|
-
not in
|
|
1256
|
+
not in (
|
|
1241
1257
|
EXTERNAL_BROWSER_AUTHENTICATOR,
|
|
1242
1258
|
OAUTH_AUTHENTICATOR,
|
|
1243
1259
|
KEY_PAIR_AUTHENTICATOR,
|
|
1244
|
-
|
|
1260
|
+
PROGRAMMATIC_ACCESS_TOKEN,
|
|
1261
|
+
)
|
|
1245
1262
|
and not self._password
|
|
1246
1263
|
):
|
|
1247
1264
|
Error.errorhandler_wrapper(
|
|
@@ -1660,7 +1677,7 @@ class SnowflakeConnection:
|
|
|
1660
1677
|
self._telemetry.try_add_log_to_batch(telemetry_data)
|
|
1661
1678
|
|
|
1662
1679
|
def _add_heartbeat(self) -> None:
|
|
1663
|
-
"""Add
|
|
1680
|
+
"""Add a periodic heartbeat query in order to keep connection alive."""
|
|
1664
1681
|
if not self.heartbeat_thread:
|
|
1665
1682
|
self._validate_client_session_keep_alive_heartbeat_frequency()
|
|
1666
1683
|
heartbeat_wref = weakref.WeakMethod(self._heartbeat_tick)
|
|
@@ -1686,7 +1703,7 @@ class SnowflakeConnection:
|
|
|
1686
1703
|
logger.debug("stopped heartbeat")
|
|
1687
1704
|
|
|
1688
1705
|
def _heartbeat_tick(self) -> None:
|
|
1689
|
-
"""Execute a
|
|
1706
|
+
"""Execute a heartbeat if connection isn't closed yet."""
|
|
1690
1707
|
if not self.is_closed():
|
|
1691
1708
|
logger.debug("heartbeating!")
|
|
1692
1709
|
self.rest._heartbeat()
|
|
@@ -1973,3 +1990,21 @@ class SnowflakeConnection:
|
|
|
1973
1990
|
connection=self,
|
|
1974
1991
|
)
|
|
1975
1992
|
)
|
|
1993
|
+
|
|
1994
|
+
def is_valid(self) -> bool:
|
|
1995
|
+
"""This function tries to answer the question: Is this connection still good for sending queries?
|
|
1996
|
+
Attempts to validate the connections both on the TCP/IP and Session levels."""
|
|
1997
|
+
logger.debug("validating connection and session")
|
|
1998
|
+
if self.is_closed():
|
|
1999
|
+
logger.debug("connection is already closed and not valid")
|
|
2000
|
+
return False
|
|
2001
|
+
|
|
2002
|
+
try:
|
|
2003
|
+
logger.debug("trying to heartbeat into the session to validate")
|
|
2004
|
+
hb_result = self.rest._heartbeat()
|
|
2005
|
+
session_valid = hb_result.get("success")
|
|
2006
|
+
logger.debug("session still valid? %s", session_valid)
|
|
2007
|
+
return bool(session_valid)
|
|
2008
|
+
except Exception as e:
|
|
2009
|
+
logger.debug("session could not be validated due to exception: %s", e)
|
|
2010
|
+
return False
|
|
@@ -875,6 +875,7 @@ class SnowflakeCursor:
|
|
|
875
875
|
_skip_upload_on_content_match: bool = False,
|
|
876
876
|
file_stream: IO[bytes] | None = None,
|
|
877
877
|
num_statements: int | None = None,
|
|
878
|
+
_force_qmark_paramstyle: bool = False,
|
|
878
879
|
_dataframe_ast: str | None = None,
|
|
879
880
|
) -> Self | dict[str, Any] | None:
|
|
880
881
|
"""Executes a command/query.
|
|
@@ -910,6 +911,7 @@ class SnowflakeCursor:
|
|
|
910
911
|
file_stream: File-like object to be uploaded with PUT
|
|
911
912
|
num_statements: Query level parameter submitted in _statement_params constraining exact number of
|
|
912
913
|
statements being submitted (or 0 if submitting an uncounted number) when using a multi-statement query.
|
|
914
|
+
_force_qmark_paramstyle: Force the use of qmark paramstyle regardless of the connection's paramstyle.
|
|
913
915
|
_dataframe_ast: Base64-encoded dataframe request abstract syntax tree.
|
|
914
916
|
|
|
915
917
|
Returns:
|
|
@@ -929,12 +931,15 @@ class SnowflakeCursor:
|
|
|
929
931
|
|
|
930
932
|
if _do_reset:
|
|
931
933
|
self.reset()
|
|
932
|
-
command = command.strip(" \t\n\r") if command else
|
|
934
|
+
command = command.strip(" \t\n\r") if command else ""
|
|
933
935
|
if not command:
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
936
|
+
if _dataframe_ast:
|
|
937
|
+
logger.debug("dataframe ast: [%s]", _dataframe_ast)
|
|
938
|
+
else:
|
|
939
|
+
logger.warning("execute: no query is given to execute")
|
|
940
|
+
return None
|
|
937
941
|
|
|
942
|
+
logger.debug("query: [%s]", self._format_query_for_log(command))
|
|
938
943
|
_statement_params = _statement_params or dict()
|
|
939
944
|
# If we need to add another parameter, please consider introducing a dict for all extra params
|
|
940
945
|
# See discussion in https://github.com/snowflakedb/snowflake-connector-python/pull/1524#discussion_r1174061775
|
|
@@ -955,7 +960,7 @@ class SnowflakeCursor:
|
|
|
955
960
|
"dataframe_ast": _dataframe_ast,
|
|
956
961
|
}
|
|
957
962
|
|
|
958
|
-
if self._connection.is_pyformat:
|
|
963
|
+
if self._connection.is_pyformat and not _force_qmark_paramstyle:
|
|
959
964
|
query = self._preprocess_pyformat_query(command, params)
|
|
960
965
|
else:
|
|
961
966
|
# qmark and numeric paramstyle
|
|
@@ -1054,6 +1059,7 @@ class SnowflakeCursor:
|
|
|
1054
1059
|
source_from_stream=file_stream,
|
|
1055
1060
|
multipart_threshold=data.get("threshold"),
|
|
1056
1061
|
use_s3_regional_url=self._connection.enable_stage_s3_privatelink_for_us_east_1,
|
|
1062
|
+
iobound_tpe_limit=self._connection.iobound_tpe_limit,
|
|
1057
1063
|
)
|
|
1058
1064
|
sf_file_transfer_agent.execute()
|
|
1059
1065
|
data = sf_file_transfer_agent.result()
|
|
@@ -1163,7 +1169,7 @@ class SnowflakeCursor:
|
|
|
1163
1169
|
)
|
|
1164
1170
|
|
|
1165
1171
|
if not (is_dml or self.is_file_transfer):
|
|
1166
|
-
logger.
|
|
1172
|
+
logger.debug(
|
|
1167
1173
|
"Number of results in first chunk: %s", result_chunks[0].rowcount
|
|
1168
1174
|
)
|
|
1169
1175
|
|
|
@@ -1454,7 +1460,9 @@ class SnowflakeCursor:
|
|
|
1454
1460
|
else:
|
|
1455
1461
|
if re.search(";/s*$", command) is None:
|
|
1456
1462
|
command = command + "; "
|
|
1457
|
-
if self._connection.is_pyformat
|
|
1463
|
+
if self._connection.is_pyformat and not kwargs.get(
|
|
1464
|
+
"_force_qmark_paramstyle", False
|
|
1465
|
+
):
|
|
1458
1466
|
processed_queries = [
|
|
1459
1467
|
self._preprocess_pyformat_query(command, params)
|
|
1460
1468
|
for params in seqparams
|
|
@@ -17,6 +17,7 @@ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
|
17
17
|
|
|
18
18
|
from .compat import PKCS5_OFFSET, PKCS5_PAD, PKCS5_UNPAD
|
|
19
19
|
from .constants import UTF8, EncryptionMetadata, MaterialDescriptor, kilobyte
|
|
20
|
+
from .file_util import owner_rw_opener
|
|
20
21
|
from .util_text import random_string
|
|
21
22
|
|
|
22
23
|
block_size = int(algorithms.AES.block_size / 8) # in bytes
|
|
@@ -213,7 +214,7 @@ class SnowflakeEncryptionUtil:
|
|
|
213
214
|
|
|
214
215
|
logger.debug("encrypted file: %s, tmp file: %s", in_filename, temp_output_file)
|
|
215
216
|
with open(in_filename, "rb") as infile:
|
|
216
|
-
with open(temp_output_file, "wb") as outfile:
|
|
217
|
+
with open(temp_output_file, "wb", opener=owner_rw_opener) as outfile:
|
|
217
218
|
SnowflakeEncryptionUtil.decrypt_stream(
|
|
218
219
|
metadata, encryption_material, infile, outfile, chunk_size
|
|
219
220
|
)
|
|
@@ -12,7 +12,6 @@ import traceback
|
|
|
12
12
|
from logging import getLogger
|
|
13
13
|
from typing import TYPE_CHECKING, Any
|
|
14
14
|
|
|
15
|
-
from .compat import BASE_EXCEPTION_CLASS
|
|
16
15
|
from .secret_detector import SecretDetector
|
|
17
16
|
from .telemetry import TelemetryData, TelemetryField
|
|
18
17
|
from .time_util import get_time_millis
|
|
@@ -28,7 +27,7 @@ connector_base_path = os.path.join("snowflake", "connector")
|
|
|
28
27
|
RE_FORMATTED_ERROR = re.compile(r"^(\d{6,})(?: \((\S+)\))?:")
|
|
29
28
|
|
|
30
29
|
|
|
31
|
-
class Error(
|
|
30
|
+
class Error(Exception):
|
|
32
31
|
"""Base Snowflake exception class."""
|
|
33
32
|
|
|
34
33
|
def __init__(
|
|
@@ -361,7 +360,7 @@ class Error(BASE_EXCEPTION_CLASS):
|
|
|
361
360
|
return error_class(error_value)
|
|
362
361
|
|
|
363
362
|
|
|
364
|
-
class _Warning(
|
|
363
|
+
class _Warning(Exception):
|
|
365
364
|
"""Exception for important warnings."""
|
|
366
365
|
|
|
367
366
|
pass
|
|
@@ -354,6 +354,7 @@ class SnowflakeFileTransferAgent:
|
|
|
354
354
|
multipart_threshold: int | None = None,
|
|
355
355
|
source_from_stream: IO[bytes] | None = None,
|
|
356
356
|
use_s3_regional_url: bool = False,
|
|
357
|
+
iobound_tpe_limit: int | None = None,
|
|
357
358
|
) -> None:
|
|
358
359
|
self._cursor = cursor
|
|
359
360
|
self._command = command
|
|
@@ -384,6 +385,7 @@ class SnowflakeFileTransferAgent:
|
|
|
384
385
|
self._multipart_threshold = multipart_threshold or 67108864 # Historical value
|
|
385
386
|
self._use_s3_regional_url = use_s3_regional_url
|
|
386
387
|
self._credentials: StorageCredential | None = None
|
|
388
|
+
self._iobound_tpe_limit = iobound_tpe_limit
|
|
387
389
|
|
|
388
390
|
def execute(self) -> None:
|
|
389
391
|
self._parse_command()
|
|
@@ -440,10 +442,15 @@ class SnowflakeFileTransferAgent:
|
|
|
440
442
|
result.result_status = result.result_status.value
|
|
441
443
|
|
|
442
444
|
def transfer(self, metas: list[SnowflakeFileMeta]) -> None:
|
|
445
|
+
iobound_tpe_limit = min(len(metas), os.cpu_count())
|
|
446
|
+
logger.debug("Decided IO-bound TPE size: %d", iobound_tpe_limit)
|
|
447
|
+
if self._iobound_tpe_limit is not None:
|
|
448
|
+
logger.debug("IO-bound TPE size is limited to: %d", self._iobound_tpe_limit)
|
|
449
|
+
iobound_tpe_limit = min(iobound_tpe_limit, self._iobound_tpe_limit)
|
|
443
450
|
max_concurrency = self._parallel
|
|
444
451
|
network_tpe = ThreadPoolExecutor(max_concurrency)
|
|
445
|
-
preprocess_tpe = ThreadPoolExecutor(
|
|
446
|
-
postprocess_tpe = ThreadPoolExecutor(
|
|
452
|
+
preprocess_tpe = ThreadPoolExecutor(iobound_tpe_limit)
|
|
453
|
+
postprocess_tpe = ThreadPoolExecutor(iobound_tpe_limit)
|
|
447
454
|
logger.debug(f"Chunk ThreadPoolExecutor size: {max_concurrency}")
|
|
448
455
|
cv_main_thread = threading.Condition() # to signal the main thread
|
|
449
456
|
cv_chunk_process = (
|
|
@@ -454,6 +461,9 @@ class SnowflakeFileTransferAgent:
|
|
|
454
461
|
transfer_metadata = TransferMetadata() # this is protected by cv_chunk_process
|
|
455
462
|
is_upload = self._command_type == CMD_TYPE_UPLOAD
|
|
456
463
|
exception_caught_in_callback: Exception | None = None
|
|
464
|
+
logger.debug(
|
|
465
|
+
"Going to %sload %d files", "up" if is_upload else "down", len(metas)
|
|
466
|
+
)
|
|
457
467
|
|
|
458
468
|
def notify_file_completed() -> None:
|
|
459
469
|
# Increment the number of completed files, then notify the main thread.
|
|
@@ -21,6 +21,10 @@ from .constants import UTF8, kilobyte
|
|
|
21
21
|
logger = getLogger(__name__)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
def owner_rw_opener(path, flags) -> int:
|
|
25
|
+
return os.open(path, flags, mode=0o600)
|
|
26
|
+
|
|
27
|
+
|
|
24
28
|
class SnowflakeFileUtil:
|
|
25
29
|
@staticmethod
|
|
26
30
|
def get_digest_and_size(src: IO[bytes]) -> tuple[str, int]:
|
|
@@ -187,6 +187,7 @@ KEY_PAIR_AUTHENTICATOR = "SNOWFLAKE_JWT"
|
|
|
187
187
|
OAUTH_AUTHENTICATOR = "OAUTH"
|
|
188
188
|
ID_TOKEN_AUTHENTICATOR = "ID_TOKEN"
|
|
189
189
|
USR_PWD_MFA_AUTHENTICATOR = "USERNAME_PASSWORD_MFA"
|
|
190
|
+
PROGRAMMATIC_ACCESS_TOKEN = "PROGRAMMATIC_ACCESS_TOKEN"
|
|
190
191
|
|
|
191
192
|
|
|
192
193
|
def is_retryable_http_code(code: int) -> bool:
|