altcodepro-polydb-python 2.3.29__tar.gz → 2.3.31__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 (93) hide show
  1. {altcodepro_polydb_python-2.3.29/src/altcodepro_polydb_python.egg-info → altcodepro_polydb_python-2.3.31}/PKG-INFO +1 -1
  2. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/pyproject.toml +1 -1
  3. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31/src/altcodepro_polydb_python.egg-info}/PKG-INFO +1 -1
  4. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/PostgreSQLAdapter.py +27 -2
  5. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/retry.py +11 -2
  6. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/LICENSE +0 -0
  7. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/MANIFEST.in +0 -0
  8. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/README.md +0 -0
  9. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/requirements-aws.txt +0 -0
  10. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/requirements-azure.txt +0 -0
  11. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/requirements-dev.txt +0 -0
  12. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/requirements-gcp.txt +0 -0
  13. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/requirements-generic.txt +0 -0
  14. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/requirements.txt +0 -0
  15. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/setup.cfg +0 -0
  16. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/setup.py +0 -0
  17. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/altcodepro_polydb_python.egg-info/SOURCES.txt +0 -0
  18. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/altcodepro_polydb_python.egg-info/dependency_links.txt +0 -0
  19. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/altcodepro_polydb_python.egg-info/requires.txt +0 -0
  20. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/altcodepro_polydb_python.egg-info/top_level.txt +0 -0
  21. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/PolyDB.py +0 -0
  22. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/__init__.py +0 -0
  23. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/AzureBlobStorageAdapter.py +0 -0
  24. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/AzureFileStorageAdapter.py +0 -0
  25. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/AzureQueueAdapter.py +0 -0
  26. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/AzureTableStorageAdapter.py +0 -0
  27. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/BlockchainBlobAdapter.py +0 -0
  28. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/BlockchainFileAdapter.py +0 -0
  29. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/BlockchainKVAdapter.py +0 -0
  30. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/BlockchainQueueAdapter.py +0 -0
  31. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/DynamoDBAdapter.py +0 -0
  32. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/EFSAdapter.py +0 -0
  33. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/FirestoreAdapter.py +0 -0
  34. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/GCPFilestoreAdapter.py +0 -0
  35. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/GCPPubSubAdapter.py +0 -0
  36. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/GCPStorageAdapter.py +0 -0
  37. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/MongoDBAdapter.py +0 -0
  38. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/S3Adapter.py +0 -0
  39. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/S3CompatibleAdapter.py +0 -0
  40. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/SQSAdapter.py +0 -0
  41. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/VercelBlobAdapter.py +0 -0
  42. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/VercelFileAdapter.py +0 -0
  43. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/VercelKVAdapter.py +0 -0
  44. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/VercelQueueAdapter.py +0 -0
  45. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/adapters/__init__.py +0 -0
  46. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/advanced_query.py +0 -0
  47. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/audit/AuditStorage.py +0 -0
  48. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/audit/__init__.py +0 -0
  49. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/audit/context.py +0 -0
  50. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/audit/manager.py +0 -0
  51. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/audit/models.py +0 -0
  52. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/base/NoSQLKVAdapter.py +0 -0
  53. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/base/ObjectStorageAdapter.py +0 -0
  54. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/base/QueueAdapter.py +0 -0
  55. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/base/SharedFilesAdapter.py +0 -0
  56. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/base/__init__.py +0 -0
  57. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/batch.py +0 -0
  58. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/cache.py +0 -0
  59. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/cloudDatabaseFactory.py +0 -0
  60. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/databaseFactory.py +0 -0
  61. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/decorators.py +0 -0
  62. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/errors.py +0 -0
  63. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/json_safe.py +0 -0
  64. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/models.py +0 -0
  65. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/monitoring.py +0 -0
  66. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/multitenancy.py +0 -0
  67. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/observability/__init__.py +0 -0
  68. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/observability/logging.py +0 -0
  69. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/py.typed +0 -0
  70. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/query.py +0 -0
  71. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/registry.py +0 -0
  72. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/schema.py +0 -0
  73. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/security.py +0 -0
  74. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/services/__init__.py +0 -0
  75. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/services/compliance_service.py +0 -0
  76. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/services/security_service.py +0 -0
  77. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/types.py +0 -0
  78. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/utils.py +0 -0
  79. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/src/polydb/validation.py +0 -0
  80. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_atomic_decrement.py +0 -0
  81. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_aws.py +0 -0
  82. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_azure.py +0 -0
  83. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_azure_queue_receipt_handle.py +0 -0
  84. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_azure_table_empty_filter.py +0 -0
  85. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_azure_table_unpack_entity.py +0 -0
  86. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_blockchain.py +0 -0
  87. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_cloud_factory.py +0 -0
  88. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_gcp.py +0 -0
  89. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_mongodb.py +0 -0
  90. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_multi_engine.py +0 -0
  91. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_observability.py +0 -0
  92. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_postgresql.py +0 -0
  93. {altcodepro_polydb_python-2.3.29 → altcodepro_polydb_python-2.3.31}/tests/test_vercel.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: altcodepro-polydb-python
3
- Version: 2.3.29
3
+ Version: 2.3.31
4
4
  Summary: Production-ready multi-cloud database abstraction layer with connection pooling, retry logic, and thread safety
5
5
  Author: AltCodePro
6
6
  Project-URL: Homepage, https://github.com/altcodepro/polydb-python
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "altcodepro-polydb-python"
7
- version = "2.3.29"
7
+ version = "2.3.31"
8
8
  description = "Production-ready multi-cloud database abstraction layer with connection pooling, retry logic, and thread safety"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: altcodepro-polydb-python
3
- Version: 2.3.29
3
+ Version: 2.3.31
4
4
  Summary: Production-ready multi-cloud database abstraction layer with connection pooling, retry logic, and thread safety
5
5
  Author: AltCodePro
6
6
  Project-URL: Homepage, https://github.com/altcodepro/polydb-python
@@ -76,7 +76,7 @@ class PostgreSQLAdapter:
76
76
  def _initialize_pool(self):
77
77
  try:
78
78
  import psycopg2.pool
79
- from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
79
+ from urllib.parse import urlparse, parse_qs, quote, urlencode, urlunparse
80
80
 
81
81
  dsn = self.connection_string
82
82
  if "postgresql://" in dsn:
@@ -87,8 +87,33 @@ class PostgreSQLAdapter:
87
87
  query.setdefault("keepalives_idle", ["30"])
88
88
  query.setdefault("keepalives_interval", ["10"])
89
89
  query.setdefault("keepalives_count", ["5"])
90
+ # connect_timeout only bounds the initial handshake; keepalives
91
+ # only detect a dead *idle* connection. Neither bounds a query
92
+ # that's already in flight and stalls mid-response (packet
93
+ # loss / a silently-dropped connection somewhere on the path
94
+ # to a remote DB) -- that shows up as libpq's own "could not
95
+ # receive data from server: Operation timed out / SSL SYSCALL
96
+ # error", and without a bound the client can block on that
97
+ # recv() for a very long time (Python can't interrupt a
98
+ # blocking C-level syscall, so even Ctrl+C doesn't land until
99
+ # it returns). tcp_user_timeout bounds unacknowledged data at
100
+ # the OS/TCP level; statement_timeout bounds how long Postgres
101
+ # itself will run a query before cancelling it server-side.
102
+ query.setdefault(
103
+ "tcp_user_timeout",
104
+ [os.getenv("POSTGRES_TCP_USER_TIMEOUT_MS", "20000")],
105
+ )
106
+ query.setdefault(
107
+ "options",
108
+ [f"-c statement_timeout={os.getenv('POSTGRES_STATEMENT_TIMEOUT_MS', '20000')}"],
109
+ )
90
110
 
91
- new_query = urlencode(query, doseq=True)
111
+ # quote_via=quote, not the default quote_plus: libpq's URI
112
+ # parser percent-decodes query values but treats "+" as a
113
+ # literal plus, so form-encoding the space in
114
+ # "-c statement_timeout=..." makes the server see the option
115
+ # name as "+statement_timeout" and reject the connection.
116
+ new_query = urlencode(query, doseq=True, quote_via=quote)
92
117
  parsed = parsed._replace(query=new_query)
93
118
  dsn = urlunparse(parsed)
94
119
 
@@ -3,6 +3,7 @@
3
3
  Retry logic with exponential backoff and metrics hooks
4
4
  """
5
5
 
6
+ import os
6
7
  import time
7
8
  import logging
8
9
  from functools import wraps
@@ -74,7 +75,15 @@ def retry(
74
75
  @wraps(func)
75
76
  def wrapper(*args, **kwargs):
76
77
  attempt = 0
77
- current_delay = delay
78
+ # POLYDB_RETRY_DELAY_SECONDS / POLYDB_RETRY_BACKOFF override every
79
+ # call site's hardcoded delay/backoff without touching them
80
+ # individually -- every adapter passes delay=1.0 explicitly, so a
81
+ # transient failure against a high-latency remote DB (e.g. a local
82
+ # dev box talking to a managed Postgres in a different region)
83
+ # costs a full 1s+2s of sleep on top of the already-elevated
84
+ # network round trip, per retry. Unset, behavior is unchanged.
85
+ current_delay = float(os.getenv("POLYDB_RETRY_DELAY_SECONDS", delay))
86
+ backoff_rate = float(os.getenv("POLYDB_RETRY_BACKOFF", backoff))
78
87
 
79
88
  logger = logging.getLogger(__name__)
80
89
 
@@ -110,7 +119,7 @@ def retry(
110
119
  f"Retrying in {current_delay}s..."
111
120
  )
112
121
  time.sleep(current_delay)
113
- current_delay *= backoff
122
+ current_delay *= backoff_rate
114
123
  raise RuntimeError(
115
124
  f"{func.__name__} exhausted {max_attempts} attempts without returning"
116
125
  )