altcodepro-polydb-python 2.5.4__py3-none-any.whl → 2.5.7__py3-none-any.whl
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.
- {altcodepro_polydb_python-2.5.4.dist-info → altcodepro_polydb_python-2.5.7.dist-info}/METADATA +69 -20
- {altcodepro_polydb_python-2.5.4.dist-info → altcodepro_polydb_python-2.5.7.dist-info}/RECORD +28 -21
- polydb/__init__.py +1 -1
- polydb/adapters/AWSSecretsManagerAdapter.py +72 -0
- polydb/adapters/AzureKeyVaultAdapter.py +65 -0
- polydb/adapters/AzureQueueAdapter.py +82 -4
- polydb/adapters/DynamoDBAdapter.py +31 -16
- polydb/adapters/FirestoreAdapter.py +30 -13
- polydb/adapters/GCPPubSubAdapter.py +46 -0
- polydb/adapters/GCPSecretManagerAdapter.py +79 -0
- polydb/adapters/KafkaQueueAdapter.py +332 -0
- polydb/adapters/PostgreSQLAdapter.py +114 -6
- polydb/adapters/RabbitMQAdapter.py +465 -0
- polydb/adapters/SQSAdapter.py +60 -0
- polydb/adapters/VaultAdapter.py +75 -0
- polydb/adapters/VercelKVAdapter.py +38 -24
- polydb/adapters/VercelQueueAdapter.py +30 -2
- polydb/base/QueueAdapter.py +123 -1
- polydb/base/SecretsAdapter.py +30 -0
- polydb/cache.py +90 -0
- polydb/cloudDatabaseFactory.py +129 -15
- polydb/databaseFactory.py +262 -60
- polydb/errors.py +6 -0
- polydb/models.py +77 -0
- polydb/retry.py +7 -0
- {altcodepro_polydb_python-2.5.4.dist-info → altcodepro_polydb_python-2.5.7.dist-info}/WHEEL +0 -0
- {altcodepro_polydb_python-2.5.4.dist-info → altcodepro_polydb_python-2.5.7.dist-info}/licenses/LICENSE +0 -0
- {altcodepro_polydb_python-2.5.4.dist-info → altcodepro_polydb_python-2.5.7.dist-info}/top_level.txt +0 -0
polydb/cloudDatabaseFactory.py
CHANGED
|
@@ -6,17 +6,17 @@ from typing import Dict, List, Optional
|
|
|
6
6
|
|
|
7
7
|
from .base import SharedFilesAdapter
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
from .adapters.
|
|
12
|
-
from
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
from .adapters.VercelBlobAdapter import VercelBlobAdapter
|
|
17
|
-
|
|
9
|
+
# Deliberately NOT importing adapter classes at module level (they used to
|
|
10
|
+
# be, redundantly -- every branch below already does its own lazy, local
|
|
11
|
+
# `from .adapters.XAdapter import XAdapter` at the point of use, and
|
|
12
|
+
# `from __future__ import annotations` above means the return-type hints
|
|
13
|
+
# don't need a real import either). The top-level imports served no
|
|
14
|
+
# purpose except forcing every cloud SDK to be installed just to
|
|
15
|
+
# `import polydb` at all -- found by actually trying a minimal install.
|
|
18
16
|
from .models import (
|
|
17
|
+
AWSSecretsManagerConfig,
|
|
19
18
|
AzureFileConfig,
|
|
19
|
+
AzureKeyVaultConfig,
|
|
20
20
|
AzureQueueConfig,
|
|
21
21
|
AzureStorageConfig,
|
|
22
22
|
AzureTableConfig,
|
|
@@ -29,22 +29,21 @@ from .models import (
|
|
|
29
29
|
FirestoreConfig,
|
|
30
30
|
GCPFileConfig,
|
|
31
31
|
GCPPubSubConfig,
|
|
32
|
+
GCPSecretManagerConfig,
|
|
32
33
|
GCPStorageConfig,
|
|
34
|
+
KafkaQueueConfig,
|
|
33
35
|
MongoConfig,
|
|
34
36
|
PartitionConfig,
|
|
35
37
|
PostgreSQLConfig,
|
|
38
|
+
RabbitMQConfig,
|
|
36
39
|
SQSAdapterConfig,
|
|
37
40
|
StorageConfig,
|
|
41
|
+
VaultConfig,
|
|
38
42
|
VercelKVConfig,
|
|
39
43
|
VercelQueueConfig,
|
|
40
44
|
VercelStorageConfig,
|
|
41
45
|
)
|
|
42
46
|
from .utils import setup_logger
|
|
43
|
-
from .adapters.AzureQueueAdapter import AzureQueueAdapter
|
|
44
|
-
from .adapters.GCPPubSubAdapter import GCPPubSubAdapter
|
|
45
|
-
from .adapters.VercelQueueAdapter import VercelQueueAdapter
|
|
46
|
-
from .adapters.BlockchainQueueAdapter import BlockchainQueueAdapter
|
|
47
|
-
from .adapters.SQSAdapter import SQSAdapter
|
|
48
47
|
|
|
49
48
|
# ============================================================
|
|
50
49
|
# FACTORY
|
|
@@ -100,6 +99,11 @@ class CloudDatabaseFactory:
|
|
|
100
99
|
return CloudProvider.GCP
|
|
101
100
|
if os.getenv("VERCEL_ENV"):
|
|
102
101
|
return CloudProvider.VERCEL
|
|
102
|
+
# README documents MONGODB_URI as a detection signal; the check was
|
|
103
|
+
# missing here entirely, so it silently fell through to Postgres
|
|
104
|
+
# instead (found by running the package's own test suite).
|
|
105
|
+
if os.getenv("MONGODB_URI"):
|
|
106
|
+
return CloudProvider.MONGODB
|
|
103
107
|
|
|
104
108
|
return CloudProvider.POSTGRESQL
|
|
105
109
|
|
|
@@ -358,6 +362,8 @@ class CloudDatabaseFactory:
|
|
|
358
362
|
| GCPPubSubAdapter
|
|
359
363
|
| VercelQueueAdapter
|
|
360
364
|
| BlockchainQueueAdapter
|
|
365
|
+
| KafkaQueueAdapter
|
|
366
|
+
| RabbitMQAdapter
|
|
361
367
|
):
|
|
362
368
|
with self._lock:
|
|
363
369
|
if name in self.instances:
|
|
@@ -368,6 +374,7 @@ class CloudDatabaseFactory:
|
|
|
368
374
|
cfg = StorageConfig(provider=self.provider, name=name)
|
|
369
375
|
|
|
370
376
|
if cfg.provider == CloudProvider.AZURE:
|
|
377
|
+
from .adapters.AzureQueueAdapter import AzureQueueAdapter
|
|
371
378
|
|
|
372
379
|
connection_string = None
|
|
373
380
|
if isinstance(cfg, AzureQueueConfig):
|
|
@@ -391,6 +398,7 @@ class CloudDatabaseFactory:
|
|
|
391
398
|
)
|
|
392
399
|
|
|
393
400
|
elif cfg.provider == CloudProvider.GCP:
|
|
401
|
+
from .adapters.GCPPubSubAdapter import GCPPubSubAdapter
|
|
394
402
|
|
|
395
403
|
topic = None
|
|
396
404
|
project_id = ""
|
|
@@ -404,6 +412,7 @@ class CloudDatabaseFactory:
|
|
|
404
412
|
)
|
|
405
413
|
|
|
406
414
|
elif cfg.provider == CloudProvider.VERCEL:
|
|
415
|
+
from .adapters.VercelQueueAdapter import VercelQueueAdapter
|
|
407
416
|
|
|
408
417
|
url = ""
|
|
409
418
|
token = ""
|
|
@@ -413,6 +422,7 @@ class CloudDatabaseFactory:
|
|
|
413
422
|
instance = VercelQueueAdapter(url or "", token or "")
|
|
414
423
|
|
|
415
424
|
elif cfg.provider == CloudProvider.BLOCKCHAIN:
|
|
425
|
+
from .adapters.BlockchainQueueAdapter import BlockchainQueueAdapter
|
|
416
426
|
|
|
417
427
|
rpc_url = ""
|
|
418
428
|
private_key = ""
|
|
@@ -430,12 +440,65 @@ class CloudDatabaseFactory:
|
|
|
430
440
|
contract_abi=contract_abi,
|
|
431
441
|
)
|
|
432
442
|
|
|
443
|
+
elif cfg.provider == CloudProvider.KAFKA:
|
|
444
|
+
from .adapters.KafkaQueueAdapter import KafkaQueueAdapter
|
|
445
|
+
|
|
446
|
+
bootstrap_servers = ""
|
|
447
|
+
group_id = ""
|
|
448
|
+
security_protocol = ""
|
|
449
|
+
sasl_mechanism = None
|
|
450
|
+
sasl_plain_username = None
|
|
451
|
+
sasl_plain_password = None
|
|
452
|
+
ssl_cafile = None
|
|
453
|
+
if isinstance(cfg, KafkaQueueConfig):
|
|
454
|
+
bootstrap_servers = cfg.bootstrap_servers
|
|
455
|
+
group_id = cfg.group_id
|
|
456
|
+
security_protocol = cfg.security_protocol
|
|
457
|
+
sasl_mechanism = cfg.sasl_mechanism
|
|
458
|
+
sasl_plain_username = cfg.sasl_plain_username
|
|
459
|
+
sasl_plain_password = cfg.sasl_plain_password
|
|
460
|
+
ssl_cafile = cfg.ssl_cafile
|
|
461
|
+
instance = KafkaQueueAdapter(
|
|
462
|
+
bootstrap_servers=bootstrap_servers or "",
|
|
463
|
+
group_id=group_id or "",
|
|
464
|
+
security_protocol=security_protocol or "",
|
|
465
|
+
sasl_mechanism=sasl_mechanism or "",
|
|
466
|
+
sasl_plain_username=sasl_plain_username or "",
|
|
467
|
+
sasl_plain_password=sasl_plain_password or "",
|
|
468
|
+
ssl_cafile=ssl_cafile or "",
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
elif cfg.provider == CloudProvider.RABBITMQ:
|
|
472
|
+
from .adapters.RabbitMQAdapter import RabbitMQAdapter
|
|
473
|
+
|
|
474
|
+
url = ""
|
|
475
|
+
host = ""
|
|
476
|
+
port = 0
|
|
477
|
+
username = ""
|
|
478
|
+
password = ""
|
|
479
|
+
virtual_host = ""
|
|
480
|
+
if isinstance(cfg, RabbitMQConfig):
|
|
481
|
+
url = cfg.url
|
|
482
|
+
host = cfg.host
|
|
483
|
+
port = cfg.port
|
|
484
|
+
username = cfg.username
|
|
485
|
+
password = cfg.password
|
|
486
|
+
virtual_host = cfg.virtual_host
|
|
487
|
+
instance = RabbitMQAdapter(
|
|
488
|
+
url=url or "",
|
|
489
|
+
host=host or "",
|
|
490
|
+
port=port or 0,
|
|
491
|
+
username=username or "",
|
|
492
|
+
password=password or "",
|
|
493
|
+
virtual_host=virtual_host or "",
|
|
494
|
+
)
|
|
495
|
+
|
|
433
496
|
else:
|
|
434
497
|
raise NotImplementedError(
|
|
435
498
|
f"Queue adapter is not supported for {self.provider.value}"
|
|
436
499
|
)
|
|
437
500
|
|
|
438
|
-
self.instances[
|
|
501
|
+
self.instances[name] = instance
|
|
439
502
|
return instance
|
|
440
503
|
|
|
441
504
|
def get_files(self, name: str = "files"):
|
|
@@ -490,3 +553,54 @@ class CloudDatabaseFactory:
|
|
|
490
553
|
|
|
491
554
|
self.instances[name] = instance
|
|
492
555
|
return instance
|
|
556
|
+
|
|
557
|
+
# --------------------------------------------------------
|
|
558
|
+
# SECRETS
|
|
559
|
+
# --------------------------------------------------------
|
|
560
|
+
def get_secrets(self, name: str = "secrets"):
|
|
561
|
+
"""Cloud-agnostic secrets: Azure Key Vault / AWS Secrets Manager /
|
|
562
|
+
GCP Secret Manager / HashiCorp Vault (self-hosted), dispatched the
|
|
563
|
+
same way as every other adapter type. Unlike the data adapters,
|
|
564
|
+
this deliberately does NOT fall back to self.provider by default --
|
|
565
|
+
a factory configured for provider=postgresql or provider=mongodb
|
|
566
|
+
has no secrets manager of its own, so an unconfigured/unrecognized
|
|
567
|
+
provider here falls back to Vault (self-hosted, cloud-agnostic)
|
|
568
|
+
rather than raising."""
|
|
569
|
+
with self._lock:
|
|
570
|
+
cache_key = f"secrets::{name}"
|
|
571
|
+
if cache_key in self.instances:
|
|
572
|
+
return self.instances[cache_key]
|
|
573
|
+
|
|
574
|
+
cfg = self.configs.get(name)
|
|
575
|
+
provider = cfg.provider if cfg else self.provider
|
|
576
|
+
|
|
577
|
+
if provider == CloudProvider.AZURE:
|
|
578
|
+
from .adapters.AzureKeyVaultAdapter import AzureKeyVaultAdapter
|
|
579
|
+
|
|
580
|
+
vault_url = cfg.vault_url if isinstance(cfg, AzureKeyVaultConfig) else None
|
|
581
|
+
instance = AzureKeyVaultAdapter(vault_url=vault_url or "")
|
|
582
|
+
|
|
583
|
+
elif provider == CloudProvider.AWS:
|
|
584
|
+
from .adapters.AWSSecretsManagerAdapter import AWSSecretsManagerAdapter
|
|
585
|
+
|
|
586
|
+
region = cfg.region if isinstance(cfg, AWSSecretsManagerConfig) else None
|
|
587
|
+
instance = AWSSecretsManagerAdapter(region=region or "")
|
|
588
|
+
|
|
589
|
+
elif provider == CloudProvider.GCP:
|
|
590
|
+
from .adapters.GCPSecretManagerAdapter import GCPSecretManagerAdapter
|
|
591
|
+
|
|
592
|
+
project_id = cfg.project_id if isinstance(cfg, GCPSecretManagerConfig) else None
|
|
593
|
+
instance = GCPSecretManagerAdapter(project_id=project_id or "")
|
|
594
|
+
|
|
595
|
+
else:
|
|
596
|
+
from .adapters.VaultAdapter import VaultAdapter
|
|
597
|
+
|
|
598
|
+
url, token, mount_point = None, None, "secret"
|
|
599
|
+
if isinstance(cfg, VaultConfig):
|
|
600
|
+
url, token, mount_point = cfg.url, cfg.token, cfg.mount_point
|
|
601
|
+
instance = VaultAdapter(
|
|
602
|
+
url=url or "", token=token or "", mount_point=mount_point
|
|
603
|
+
)
|
|
604
|
+
|
|
605
|
+
self.instances[cache_key] = instance
|
|
606
|
+
return instance
|