snowflake-connector-python 3.13.0__tar.gz → 3.13.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/DESCRIPTION.md +7 -0
  2. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/PKG-INFO +8 -1
  3. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/_auth.py +6 -1
  4. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/cache.py +11 -3
  5. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/cursor.py +6 -2
  6. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/encryption_util.py +2 -1
  7. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/file_util.py +4 -0
  8. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/ocsp_snowflake.py +161 -5
  9. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/pandas_tools.py +99 -29
  10. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/storage_client.py +7 -2
  11. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/util_text.py +5 -0
  12. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/version.py +1 -1
  13. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake_connector_python.egg-info/PKG-INFO +8 -1
  14. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/CONTRIBUTING.md +0 -0
  15. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/LICENSE.txt +0 -0
  16. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/MANIFEST.in +0 -0
  17. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/NOTICE +0 -0
  18. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/README.md +0 -0
  19. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/SECURITY.md +0 -0
  20. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/pyproject.toml +0 -0
  21. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/setup.cfg +0 -0
  22. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/setup.py +0 -0
  23. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/__init__.py +0 -0
  24. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/_query_context_cache.py +0 -0
  25. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/_sql_util.py +0 -0
  26. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/_utils.py +0 -0
  27. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/arrow_context.py +0 -0
  28. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/__init__.py +0 -0
  29. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/by_plugin.py +0 -0
  30. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/default.py +0 -0
  31. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/idtoken.py +0 -0
  32. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/keypair.py +0 -0
  33. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/oauth.py +0 -0
  34. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/okta.py +0 -0
  35. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/pat.py +0 -0
  36. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/usrpwdmfa.py +0 -0
  37. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/auth/webbrowser.py +0 -0
  38. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/azure_storage_client.py +0 -0
  39. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/backoff_policies.py +0 -0
  40. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/bind_upload_agent.py +0 -0
  41. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/compat.py +0 -0
  42. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/config_manager.py +0 -0
  43. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/connection.py +0 -0
  44. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/connection_diagnostic.py +0 -0
  45. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/constants.py +0 -0
  46. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/converter.py +0 -0
  47. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/converter_issue23517.py +0 -0
  48. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/converter_null.py +0 -0
  49. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/converter_snowsql.py +0 -0
  50. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/dbapi.py +0 -0
  51. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/description.py +0 -0
  52. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/errorcode.py +0 -0
  53. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/errors.py +0 -0
  54. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/feature.py +0 -0
  55. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/file_compression_type.py +0 -0
  56. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/file_transfer_agent.py +0 -0
  57. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/gcs_storage_client.py +0 -0
  58. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/gzip_decoder.py +0 -0
  59. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/local_storage_client.py +0 -0
  60. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/log_configuration.py +0 -0
  61. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +0 -0
  62. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +0 -0
  63. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +0 -0
  64. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +0 -0
  65. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +0 -0
  66. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +0 -0
  67. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +0 -0
  68. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +0 -0
  69. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +0 -0
  70. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +0 -0
  71. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +0 -0
  72. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +0 -0
  73. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +0 -0
  74. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +0 -0
  75. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +0 -0
  76. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +0 -0
  77. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +0 -0
  78. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +0 -0
  79. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +0 -0
  80. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +0 -0
  81. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +0 -0
  82. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +0 -0
  83. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +0 -0
  84. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +0 -0
  85. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +0 -0
  86. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +0 -0
  87. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +0 -0
  88. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +0 -0
  89. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +0 -0
  90. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +0 -0
  91. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +0 -0
  92. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +0 -0
  93. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +0 -0
  94. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +0 -0
  95. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +0 -0
  96. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +0 -0
  97. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +0 -0
  98. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +0 -0
  99. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +0 -0
  100. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +0 -0
  101. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +0 -0
  102. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +0 -0
  103. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +0 -0
  104. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +0 -0
  105. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +0 -0
  106. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +0 -0
  107. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +0 -0
  108. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +0 -0
  109. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +0 -0
  110. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +0 -0
  111. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +0 -0
  112. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +0 -0
  113. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +0 -0
  114. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +0 -0
  115. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +0 -0
  116. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +0 -0
  117. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +0 -0
  118. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +0 -0
  119. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +0 -0
  120. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +0 -0
  121. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +0 -0
  122. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +0 -0
  123. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +0 -0
  124. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +0 -0
  125. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +0 -0
  126. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +0 -0
  127. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +0 -0
  128. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +0 -0
  129. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +0 -0
  130. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +0 -0
  131. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +0 -0
  132. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +0 -0
  133. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +0 -0
  134. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +0 -0
  135. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +0 -0
  136. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +0 -0
  137. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +0 -0
  138. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +0 -0
  139. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +0 -0
  140. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +0 -0
  141. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +0 -0
  142. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +0 -0
  143. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +0 -0
  144. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +0 -0
  145. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +0 -0
  146. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +0 -0
  147. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +0 -0
  148. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/network.py +0 -0
  149. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/ocsp_asn1crypto.py +0 -0
  150. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/options.py +0 -0
  151. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/proxy.py +0 -0
  152. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/py.typed +0 -0
  153. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/result_batch.py +0 -0
  154. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/result_set.py +0 -0
  155. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/s3_storage_client.py +0 -0
  156. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/secret_detector.py +0 -0
  157. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/sf_dirs.py +0 -0
  158. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/sfbinaryformat.py +0 -0
  159. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/sfdatetime.py +0 -0
  160. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/snow_logging.py +0 -0
  161. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/sqlstate.py +0 -0
  162. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/ssd_internal_keys.py +0 -0
  163. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/ssl_wrap_socket.py +0 -0
  164. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/telemetry.py +0 -0
  165. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/telemetry_oob.py +0 -0
  166. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/test_util.py +0 -0
  167. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/time_util.py +0 -0
  168. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/tool/__init__.py +0 -0
  169. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/tool/dump_certs.py +0 -0
  170. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/tool/dump_ocsp_response.py +0 -0
  171. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/tool/dump_ocsp_response_cache.py +0 -0
  172. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/tool/probe_connection.py +0 -0
  173. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/url_util.py +0 -0
  174. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/__init__.py +0 -0
  175. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/LICENSE +0 -0
  176. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/__init__.py +0 -0
  177. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/__version__.py +0 -0
  178. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/_internal_utils.py +0 -0
  179. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/adapters.py +0 -0
  180. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/api.py +0 -0
  181. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/auth.py +0 -0
  182. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/certs.py +0 -0
  183. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/compat.py +0 -0
  184. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/cookies.py +0 -0
  185. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/exceptions.py +0 -0
  186. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/help.py +0 -0
  187. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/hooks.py +0 -0
  188. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/models.py +0 -0
  189. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/sessions.py +0 -0
  190. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/status_codes.py +0 -0
  191. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/structures.py +0 -0
  192. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/requests/utils.py +0 -0
  193. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/LICENSE.txt +0 -0
  194. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/__init__.py +0 -0
  195. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/_collections.py +0 -0
  196. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/_version.py +0 -0
  197. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/connection.py +0 -0
  198. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/connectionpool.py +0 -0
  199. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
  200. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/_appengine_environ.py +0 -0
  201. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/_securetransport/__init__.py +0 -0
  202. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/_securetransport/bindings.py +0 -0
  203. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/_securetransport/low_level.py +0 -0
  204. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/appengine.py +0 -0
  205. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/ntlmpool.py +0 -0
  206. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +0 -0
  207. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/securetransport.py +0 -0
  208. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/contrib/socks.py +0 -0
  209. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/exceptions.py +0 -0
  210. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/fields.py +0 -0
  211. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/filepost.py +0 -0
  212. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/packages/__init__.py +0 -0
  213. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/packages/backports/__init__.py +0 -0
  214. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/packages/backports/makefile.py +0 -0
  215. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/packages/backports/weakref_finalize.py +0 -0
  216. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/packages/six.py +0 -0
  217. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/poolmanager.py +0 -0
  218. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/request.py +0 -0
  219. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/response.py +0 -0
  220. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/__init__.py +0 -0
  221. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/connection.py +0 -0
  222. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/proxy.py +0 -0
  223. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/queue.py +0 -0
  224. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/request.py +0 -0
  225. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/response.py +0 -0
  226. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/retry.py +0 -0
  227. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/ssl_.py +0 -0
  228. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +0 -0
  229. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/ssltransport.py +0 -0
  230. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/timeout.py +0 -0
  231. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/url.py +0 -0
  232. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake/connector/vendored/urllib3/util/wait.py +0 -0
  233. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake_connector_python.egg-info/SOURCES.txt +0 -0
  234. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake_connector_python.egg-info/dependency_links.txt +0 -0
  235. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake_connector_python.egg-info/entry_points.txt +0 -0
  236. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake_connector_python.egg-info/not-zip-safe +0 -0
  237. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake_connector_python.egg-info/requires.txt +0 -0
  238. {snowflake_connector_python-3.13.0 → snowflake_connector_python-3.13.2}/src/snowflake_connector_python.egg-info/top_level.txt +0 -0
@@ -7,6 +7,13 @@ https://docs.snowflake.com/
7
7
  Source code is also available at: https://github.com/snowflakedb/snowflake-connector-python
8
8
 
9
9
  # Release Notes
10
+ - v3.13.2(January 29, 2025)
11
+ - Changed not to use scoped temporary objects.
12
+
13
+ - v3.13.1(January 29, 2025)
14
+ - 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
15
+ - Remedied vulnerability in deserialization of the OCSP response cache. See more: https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-m4f6-vcj4-w5mx
16
+ - Remedied vulnerability connected to cache files permissions. See more: https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-r2x6-cjg7-8r43
10
17
 
11
18
  - v3.13.0(January 23,2025)
12
19
  - Added a feature to limit the sizes of IO-bound ThreadPoolExecutors during PUT and GET commands.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: snowflake-connector-python
3
- Version: 3.13.0
3
+ Version: 3.13.2
4
4
  Summary: Snowflake Connector for Python
5
5
  Home-page: https://www.snowflake.com/
6
6
  Author: Snowflake, Inc
@@ -84,6 +84,13 @@ https://docs.snowflake.com/
84
84
  Source code is also available at: https://github.com/snowflakedb/snowflake-connector-python
85
85
 
86
86
  # Release Notes
87
+ - v3.13.2(January 29, 2025)
88
+ - Changed not to use scoped temporary objects.
89
+
90
+ - v3.13.1(January 29, 2025)
91
+ - 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
92
+ - Remedied vulnerability in deserialization of the OCSP response cache. See more: https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-m4f6-vcj4-w5mx
93
+ - Remedied vulnerability connected to cache files permissions. See more: https://github.com/snowflakedb/snowflake-connector-python/security/advisories/GHSA-r2x6-cjg7-8r43
87
94
 
88
95
  - v3.13.0(January 23,2025)
89
96
  - Added a feature to limit the sizes of IO-bound ThreadPoolExecutors during PUT and GET commands.
@@ -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, "w", encoding="utf-8", errors="ignore"
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:
@@ -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 = pickle.load(r_file)
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(pickle.dumps(self))
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(
@@ -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:
@@ -958,7 +960,7 @@ class SnowflakeCursor:
958
960
  "dataframe_ast": _dataframe_ast,
959
961
  }
960
962
 
961
- if self._connection.is_pyformat:
963
+ if self._connection.is_pyformat and not _force_qmark_paramstyle:
962
964
  query = self._preprocess_pyformat_query(command, params)
963
965
  else:
964
966
  # qmark and numeric paramstyle
@@ -1458,7 +1460,9 @@ class SnowflakeCursor:
1458
1460
  else:
1459
1461
  if re.search(";/s*$", command) is None:
1460
1462
  command = command + "; "
1461
- if self._connection.is_pyformat:
1463
+ if self._connection.is_pyformat and not kwargs.get(
1464
+ "_force_qmark_paramstyle", False
1465
+ ):
1462
1466
  processed_queries = [
1463
1467
  self._preprocess_pyformat_query(command, params)
1464
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
  )
@@ -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]:
@@ -6,6 +6,7 @@
6
6
  from __future__ import annotations
7
7
 
8
8
  import codecs
9
+ import importlib
9
10
  import json
10
11
  import os
11
12
  import platform
@@ -30,6 +31,7 @@ from asn1crypto.ocsp import CertId, OCSPRequest, SingleResponse
30
31
  from asn1crypto.x509 import Certificate
31
32
  from OpenSSL.SSL import Connection
32
33
 
34
+ from snowflake.connector import SNOWFLAKE_CONNECTOR_VERSION
33
35
  from snowflake.connector.compat import OK, urlsplit, urlunparse
34
36
  from snowflake.connector.constants import HTTP_HEADER_USER_AGENT
35
37
  from snowflake.connector.errorcode import (
@@ -58,9 +60,10 @@ from snowflake.connector.network import PYTHON_CONNECTOR_USER_AGENT
58
60
 
59
61
  from . import constants
60
62
  from .backoff_policies import exponential_backoff
61
- from .cache import SFDictCache, SFDictFileCache
63
+ from .cache import CacheEntry, SFDictCache, SFDictFileCache
62
64
  from .telemetry import TelemetryField, generate_telemetry_data_dict
63
65
  from .url_util import extract_top_level_domain_from_hostname, url_encode_str
66
+ from .util_text import _base64_bytes_to_str
64
67
 
65
68
 
66
69
  class OCSPResponseValidationResult(NamedTuple):
@@ -72,19 +75,172 @@ class OCSPResponseValidationResult(NamedTuple):
72
75
  ts: int | None = None
73
76
  validated: bool = False
74
77
 
78
+ def _serialize(self):
79
+ def serialize_exception(exc):
80
+ # serialization exception is not supported for all exceptions
81
+ # in the ocsp_snowflake.py, most exceptions are RevocationCheckError which is easy to serialize.
82
+ # however, it would require non-trivial effort to serialize other exceptions especially 3rd part errors
83
+ # as there can be un-serializable members and nondeterministic constructor arguments.
84
+ # here we do a general best efforts serialization for other exceptions recording only the error message.
85
+ if not exc:
86
+ return None
87
+
88
+ exc_type = type(exc)
89
+ ret = {"class": exc_type.__name__, "module": exc_type.__module__}
90
+ if isinstance(exc, RevocationCheckError):
91
+ ret.update({"errno": exc.errno, "msg": exc.raw_msg})
92
+ else:
93
+ ret.update({"msg": str(exc)})
94
+ return ret
95
+
96
+ return json.dumps(
97
+ {
98
+ "exception": serialize_exception(self.exception),
99
+ "issuer": (
100
+ _base64_bytes_to_str(self.issuer.dump()) if self.issuer else None
101
+ ),
102
+ "subject": (
103
+ _base64_bytes_to_str(self.subject.dump()) if self.subject else None
104
+ ),
105
+ "cert_id": (
106
+ _base64_bytes_to_str(self.cert_id.dump()) if self.cert_id else None
107
+ ),
108
+ "ocsp_response": _base64_bytes_to_str(self.ocsp_response),
109
+ "ts": self.ts,
110
+ "validated": self.validated,
111
+ }
112
+ )
113
+
114
+ @classmethod
115
+ def _deserialize(cls, json_str: str) -> OCSPResponseValidationResult:
116
+ json_obj = json.loads(json_str)
117
+
118
+ def deserialize_exception(exception_dict: dict | None) -> Exception | None:
119
+ # as pointed out in the serialization method, here we do the best effort deserialization
120
+ # for non-RevocationCheckError exceptions. If we can not deserialize the exception, we will
121
+ # return a RevocationCheckError with a message indicating the failure.
122
+ if not exception_dict:
123
+ return
124
+ exc_class = exception_dict.get("class")
125
+ exc_module = exception_dict.get("module")
126
+ try:
127
+ if (
128
+ exc_class == "RevocationCheckError"
129
+ and exc_module == "snowflake.connector.errors"
130
+ ):
131
+ return RevocationCheckError(
132
+ msg=exception_dict["msg"],
133
+ errno=exception_dict["errno"],
134
+ )
135
+ else:
136
+ module = importlib.import_module(exc_module)
137
+ exc_cls = getattr(module, exc_class)
138
+ return exc_cls(exception_dict["msg"])
139
+ except Exception as deserialize_exc:
140
+ logger.debug(
141
+ f"hitting error {str(deserialize_exc)} while deserializing exception,"
142
+ f" the original error error class and message are {exc_class} and {exception_dict['msg']}"
143
+ )
144
+ return RevocationCheckError(
145
+ f"Got error {str(deserialize_exc)} while deserializing ocsp cache, please try "
146
+ f"cleaning up the "
147
+ f"OCSP cache under directory {OCSP_RESPONSE_VALIDATION_CACHE.file_path}",
148
+ errno=ER_OCSP_RESPONSE_LOAD_FAILURE,
149
+ )
150
+
151
+ return OCSPResponseValidationResult(
152
+ exception=deserialize_exception(json_obj.get("exception")),
153
+ issuer=(
154
+ Certificate.load(b64decode(json_obj.get("issuer")))
155
+ if json_obj.get("issuer")
156
+ else None
157
+ ),
158
+ subject=(
159
+ Certificate.load(b64decode(json_obj.get("subject")))
160
+ if json_obj.get("subject")
161
+ else None
162
+ ),
163
+ cert_id=(
164
+ CertId.load(b64decode(json_obj.get("cert_id")))
165
+ if json_obj.get("cert_id")
166
+ else None
167
+ ),
168
+ ocsp_response=(
169
+ b64decode(json_obj.get("ocsp_response"))
170
+ if json_obj.get("ocsp_response")
171
+ else None
172
+ ),
173
+ ts=json_obj.get("ts"),
174
+ validated=json_obj.get("validated"),
175
+ )
176
+
177
+
178
+ class _OCSPResponseValidationResultCache(SFDictFileCache):
179
+ def _serialize(self) -> bytes:
180
+ entries = {
181
+ (
182
+ _base64_bytes_to_str(k[0]),
183
+ _base64_bytes_to_str(k[1]),
184
+ _base64_bytes_to_str(k[2]),
185
+ ): (v.expiry.isoformat(), v.entry._serialize())
186
+ for k, v in self._cache.items()
187
+ }
188
+
189
+ return json.dumps(
190
+ {
191
+ "cache_keys": list(entries.keys()),
192
+ "cache_items": list(entries.values()),
193
+ "entry_lifetime": self._entry_lifetime.total_seconds(),
194
+ "file_path": str(self.file_path),
195
+ "file_timeout": self.file_timeout,
196
+ "last_loaded": (
197
+ self.last_loaded.isoformat() if self.last_loaded else None
198
+ ),
199
+ "telemetry": self.telemetry,
200
+ "connector_version": SNOWFLAKE_CONNECTOR_VERSION, # reserved for schema version control
201
+ }
202
+ ).encode()
203
+
204
+ @classmethod
205
+ def _deserialize(cls, opened_fd) -> _OCSPResponseValidationResultCache:
206
+ data = json.loads(opened_fd.read().decode())
207
+ cache_instance = cls(
208
+ file_path=data["file_path"],
209
+ entry_lifetime=int(data["entry_lifetime"]),
210
+ file_timeout=data["file_timeout"],
211
+ load_if_file_exists=False,
212
+ )
213
+ cache_instance.file_path = os.path.expanduser(data["file_path"])
214
+ cache_instance.telemetry = data["telemetry"]
215
+ cache_instance.last_loaded = (
216
+ datetime.fromisoformat(data["last_loaded"]) if data["last_loaded"] else None
217
+ )
218
+ for k, v in zip(data["cache_keys"], data["cache_items"]):
219
+ cache_instance._cache[
220
+ (b64decode(k[0]), b64decode(k[1]), b64decode(k[2]))
221
+ ] = CacheEntry(
222
+ datetime.fromisoformat(v[0]),
223
+ OCSPResponseValidationResult._deserialize(v[1]),
224
+ )
225
+ return cache_instance
226
+
75
227
 
76
228
  try:
77
229
  OCSP_RESPONSE_VALIDATION_CACHE: SFDictFileCache[
78
230
  tuple[bytes, bytes, bytes],
79
231
  OCSPResponseValidationResult,
80
- ] = SFDictFileCache(
232
+ ] = _OCSPResponseValidationResultCache(
81
233
  entry_lifetime=constants.DAY_IN_SECONDS,
82
234
  file_path={
83
235
  "linux": os.path.join(
84
- "~", ".cache", "snowflake", "ocsp_response_validation_cache"
236
+ "~", ".cache", "snowflake", "ocsp_response_validation_cache.json"
85
237
  ),
86
238
  "darwin": os.path.join(
87
- "~", "Library", "Caches", "Snowflake", "ocsp_response_validation_cache"
239
+ "~",
240
+ "Library",
241
+ "Caches",
242
+ "Snowflake",
243
+ "ocsp_response_validation_cache.json",
88
244
  ),
89
245
  "windows": os.path.join(
90
246
  "~",
@@ -92,7 +248,7 @@ try:
92
248
  "Local",
93
249
  "Snowflake",
94
250
  "Caches",
95
- "ocsp_response_validation_cache",
251
+ "ocsp_response_validation_cache.json",
96
252
  ),
97
253
  },
98
254
  )
@@ -85,9 +85,16 @@ def _do_create_temp_stage(
85
85
  overwrite: bool,
86
86
  use_scoped_temp_object: bool,
87
87
  ) -> None:
88
- create_stage_sql = f"CREATE {get_temp_type_for_object(use_scoped_temp_object)} STAGE /* Python:snowflake.connector.pandas_tools.write_pandas() */ {stage_location} FILE_FORMAT=(TYPE=PARQUET COMPRESSION={compression}{' BINARY_AS_TEXT=FALSE' if auto_create_table or overwrite else ''})"
89
- logger.debug(f"creating stage with '{create_stage_sql}'")
90
- cursor.execute(create_stage_sql, _is_internal=True).fetchall()
88
+ create_stage_sql = f"CREATE {get_temp_type_for_object(use_scoped_temp_object)} STAGE /* Python:snowflake.connector.pandas_tools.write_pandas() */ identifier(?) FILE_FORMAT=(TYPE=PARQUET COMPRESSION={compression}{' BINARY_AS_TEXT=FALSE' if auto_create_table or overwrite else ''})"
89
+ params = (stage_location,)
90
+ logger.debug(f"creating stage with '{create_stage_sql}'. params: %s", params)
91
+ cursor.execute(
92
+ create_stage_sql,
93
+ _is_internal=True,
94
+ _force_qmark_paramstyle=True,
95
+ params=params,
96
+ num_statements=1,
97
+ )
91
98
 
92
99
 
93
100
  def _create_temp_stage(
@@ -147,12 +154,19 @@ def _do_create_temp_file_format(
147
154
  use_scoped_temp_object: bool,
148
155
  ) -> None:
149
156
  file_format_sql = (
150
- f"CREATE {get_temp_type_for_object(use_scoped_temp_object)} FILE FORMAT {file_format_location} "
157
+ f"CREATE {get_temp_type_for_object(use_scoped_temp_object)} FILE FORMAT identifier(?) "
151
158
  f"/* Python:snowflake.connector.pandas_tools.write_pandas() */ "
152
159
  f"TYPE=PARQUET COMPRESSION={compression}{sql_use_logical_type}"
153
160
  )
154
- logger.debug(f"creating file format with '{file_format_sql}'")
155
- cursor.execute(file_format_sql, _is_internal=True)
161
+ params = (file_format_location,)
162
+ logger.debug(f"creating file format with '{file_format_sql}'. params: %s", params)
163
+ cursor.execute(
164
+ file_format_sql,
165
+ _is_internal=True,
166
+ _force_qmark_paramstyle=True,
167
+ params=params,
168
+ num_statements=1,
169
+ )
156
170
 
157
171
 
158
172
  def _create_temp_file_format(
@@ -307,6 +321,12 @@ def write_pandas(
307
321
  else False
308
322
  )
309
323
 
324
+ """sfc-gh-yixie: scoped temp stage isn't required out side of a SP.
325
+ TODO: remove the following line when merging SP connector and Python Connector.
326
+ Make sure `create scoped temp stage` is supported when it's not run in a SP.
327
+ """
328
+ _use_scoped_temp_object = False
329
+
310
330
  if create_temp_table:
311
331
  warnings.warn(
312
332
  "create_temp_table is deprecated, we still respect this parameter when it is True but "
@@ -379,14 +399,20 @@ def write_pandas(
379
399
  # Upload parquet file
380
400
  upload_sql = (
381
401
  "PUT /* Python:snowflake.connector.pandas_tools.write_pandas() */ "
382
- "'file://{path}' @{stage_location} PARALLEL={parallel}"
402
+ "'file://{path}' ? PARALLEL={parallel}"
383
403
  ).format(
384
404
  path=chunk_path.replace("\\", "\\\\").replace("'", "\\'"),
385
- stage_location=stage_location,
386
405
  parallel=parallel,
387
406
  )
388
- logger.debug(f"uploading files with '{upload_sql}'")
389
- cursor.execute(upload_sql, _is_internal=True)
407
+ params = ("@" + stage_location,)
408
+ logger.debug(f"uploading files with '{upload_sql}', params: %s", params)
409
+ cursor.execute(
410
+ upload_sql,
411
+ _is_internal=True,
412
+ _force_qmark_paramstyle=True,
413
+ params=params,
414
+ num_statements=1,
415
+ )
390
416
  # Remove chunk file
391
417
  os.remove(chunk_path)
392
418
 
@@ -403,9 +429,16 @@ def write_pandas(
403
429
  columns = quote + f"{quote},{quote}".join(snowflake_column_names) + quote
404
430
 
405
431
  def drop_object(name: str, object_type: str) -> None:
406
- drop_sql = f"DROP {object_type.upper()} IF EXISTS {name} /* Python:snowflake.connector.pandas_tools.write_pandas() */"
407
- logger.debug(f"dropping {object_type} with '{drop_sql}'")
408
- cursor.execute(drop_sql, _is_internal=True)
432
+ drop_sql = f"DROP {object_type.upper()} IF EXISTS identifier(?) /* Python:snowflake.connector.pandas_tools.write_pandas() */"
433
+ params = (name,)
434
+ logger.debug(f"dropping {object_type} with '{drop_sql}'. params: %s", params)
435
+ cursor.execute(
436
+ drop_sql,
437
+ _is_internal=True,
438
+ _force_qmark_paramstyle=True,
439
+ params=params,
440
+ num_statements=1,
441
+ )
409
442
 
410
443
  if auto_create_table or overwrite:
411
444
  file_format_location = _create_temp_file_format(
@@ -417,10 +450,17 @@ def write_pandas(
417
450
  sql_use_logical_type,
418
451
  _use_scoped_temp_object,
419
452
  )
420
- infer_schema_sql = f"SELECT COLUMN_NAME, TYPE FROM table(infer_schema(location=>'@{stage_location}', file_format=>'{file_format_location}'))"
421
- logger.debug(f"inferring schema with '{infer_schema_sql}'")
453
+ infer_schema_sql = "SELECT COLUMN_NAME, TYPE FROM table(infer_schema(location=>?, file_format=>?))"
454
+ params = (f"@{stage_location}", file_format_location)
455
+ logger.debug(f"inferring schema with '{infer_schema_sql}'. params: %s", params)
422
456
  column_type_mapping = dict(
423
- cursor.execute(infer_schema_sql, _is_internal=True).fetchall()
457
+ cursor.execute(
458
+ infer_schema_sql,
459
+ _is_internal=True,
460
+ _force_qmark_paramstyle=True,
461
+ params=params,
462
+ num_statements=1,
463
+ ).fetchall()
424
464
  )
425
465
  # Infer schema can return the columns out of order depending on the chunking we do when uploading
426
466
  # so we have to iterate through the dataframe columns to make sure we create the table with its
@@ -440,12 +480,21 @@ def write_pandas(
440
480
  )
441
481
 
442
482
  create_table_sql = (
443
- f"CREATE {table_type.upper()} TABLE IF NOT EXISTS {target_table_location} "
483
+ f"CREATE {table_type.upper()} TABLE IF NOT EXISTS identifier(?) "
444
484
  f"({create_table_columns})"
445
485
  f" /* Python:snowflake.connector.pandas_tools.write_pandas() */ "
446
486
  )
447
- logger.debug(f"auto creating table with '{create_table_sql}'")
448
- cursor.execute(create_table_sql, _is_internal=True)
487
+ params = (target_table_location,)
488
+ logger.debug(
489
+ f"auto creating table with '{create_table_sql}'. params: %s", params
490
+ )
491
+ cursor.execute(
492
+ create_table_sql,
493
+ _is_internal=True,
494
+ _force_qmark_paramstyle=True,
495
+ params=params,
496
+ num_statements=1,
497
+ )
449
498
  # need explicit casting when the underlying table schema is inferred
450
499
  parquet_columns = "$1:" + ",$1:".join(
451
500
  f"{quote}{snowflake_col}{quote}::{column_type_mapping[col]}"
@@ -464,12 +513,19 @@ def write_pandas(
464
513
 
465
514
  try:
466
515
  if overwrite and (not auto_create_table):
467
- truncate_sql = f"TRUNCATE TABLE {target_table_location} /* Python:snowflake.connector.pandas_tools.write_pandas() */"
468
- logger.debug(f"truncating table with '{truncate_sql}'")
469
- cursor.execute(truncate_sql, _is_internal=True)
516
+ truncate_sql = "TRUNCATE TABLE identifier(?) /* Python:snowflake.connector.pandas_tools.write_pandas() */"
517
+ params = (target_table_location,)
518
+ logger.debug(f"truncating table with '{truncate_sql}'. params: %s", params)
519
+ cursor.execute(
520
+ truncate_sql,
521
+ _is_internal=True,
522
+ _force_qmark_paramstyle=True,
523
+ params=params,
524
+ num_statements=1,
525
+ )
470
526
 
471
527
  copy_into_sql = (
472
- f"COPY INTO {target_table_location} /* Python:snowflake.connector.pandas_tools.write_pandas() */ "
528
+ f"COPY INTO identifier(?) /* Python:snowflake.connector.pandas_tools.write_pandas() */ "
473
529
  f"({columns}) "
474
530
  f"FROM (SELECT {parquet_columns} FROM @{stage_location}) "
475
531
  f"FILE_FORMAT=("
@@ -478,10 +534,17 @@ def write_pandas(
478
534
  f"{' BINARY_AS_TEXT=FALSE' if auto_create_table or overwrite else ''}"
479
535
  f"{sql_use_logical_type}"
480
536
  f") "
481
- f"PURGE=TRUE ON_ERROR={on_error}"
537
+ f"PURGE=TRUE ON_ERROR=?"
482
538
  )
483
- logger.debug(f"copying into with '{copy_into_sql}'")
484
- copy_results = cursor.execute(copy_into_sql, _is_internal=True).fetchall()
539
+ params = (target_table_location, on_error)
540
+ logger.debug(f"copying into with '{copy_into_sql}'. params: %s", params)
541
+ copy_results = cursor.execute(
542
+ copy_into_sql,
543
+ _is_internal=True,
544
+ _force_qmark_paramstyle=True,
545
+ params=params,
546
+ num_statements=1,
547
+ ).fetchall()
485
548
 
486
549
  if overwrite and auto_create_table:
487
550
  original_table_location = build_location_helper(
@@ -491,9 +554,16 @@ def write_pandas(
491
554
  quote_identifiers=quote_identifiers,
492
555
  )
493
556
  drop_object(original_table_location, "table")
494
- rename_table_sql = f"ALTER TABLE {target_table_location} RENAME TO {original_table_location} /* Python:snowflake.connector.pandas_tools.write_pandas() */"
495
- logger.debug(f"rename table with '{rename_table_sql}'")
496
- cursor.execute(rename_table_sql, _is_internal=True)
557
+ rename_table_sql = "ALTER TABLE identifier(?) RENAME TO identifier(?) /* Python:snowflake.connector.pandas_tools.write_pandas() */"
558
+ params = (target_table_location, original_table_location)
559
+ logger.debug(f"rename table with '{rename_table_sql}'. params: %s", params)
560
+ cursor.execute(
561
+ rename_table_sql,
562
+ _is_internal=True,
563
+ _force_qmark_paramstyle=True,
564
+ params=params,
565
+ num_statements=1,
566
+ )
497
567
  except ProgrammingError:
498
568
  if overwrite and auto_create_table:
499
569
  # drop table only if we created a new one with a random name
@@ -329,6 +329,11 @@ class SnowflakeStorageClient(ABC):
329
329
  f"{verb} with url {url} failed for exceeding maximum retries."
330
330
  )
331
331
 
332
+ def _open_intermediate_dst_path(self, mode):
333
+ if not self.intermediate_dst_path.exists():
334
+ self.intermediate_dst_path.touch(mode=0o600)
335
+ return self.intermediate_dst_path.open(mode)
336
+
332
337
  def prepare_download(self) -> None:
333
338
  # TODO: add nicer error message for when target directory is not writeable
334
339
  # but this should be done before we get here
@@ -352,13 +357,13 @@ class SnowflakeStorageClient(ABC):
352
357
  self.num_of_chunks = ceil(file_header.content_length / self.chunk_size)
353
358
 
354
359
  # Preallocate encrypted file.
355
- with self.intermediate_dst_path.open("wb+") as fd:
360
+ with self._open_intermediate_dst_path("wb+") as fd:
356
361
  fd.truncate(self.meta.src_file_size)
357
362
 
358
363
  def write_downloaded_chunk(self, chunk_id: int, data: bytes) -> None:
359
364
  """Writes given data to the temp location starting at chunk_id * chunk_size."""
360
365
  # TODO: should we use chunking and write content in smaller chunks?
361
- with self.intermediate_dst_path.open("rb+") as fd:
366
+ with self._open_intermediate_dst_path("rb+") as fd:
362
367
  fd.seek(self.chunk_size * chunk_id)
363
368
  fd.write(data)
364
369
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
+ import base64
8
9
  import hashlib
9
10
  import logging
10
11
  import random
@@ -292,6 +293,10 @@ def random_string(
292
293
  return "".join([prefix, random_part, suffix])
293
294
 
294
295
 
296
+ def _base64_bytes_to_str(x) -> str | None:
297
+ return base64.b64encode(x).decode("utf-8") if x else None
298
+
299
+
295
300
  def get_md5(text: str | bytes) -> bytes:
296
301
  if isinstance(text, str):
297
302
  text = text.encode("utf-8")
@@ -1,3 +1,3 @@
1
1
  # Update this for the versions
2
2
  # Don't change the forth version number from None
3
- VERSION = (3, 13, 0, None)
3
+ VERSION = (3, 13, 2, None)