altcodepro-polydb-python 2.2.2__py3-none-any.whl → 2.2.4__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.2.4.dist-info/METADATA +489 -0
- altcodepro_polydb_python-2.2.4.dist-info/RECORD +57 -0
- {altcodepro_polydb_python-2.2.2.dist-info → altcodepro_polydb_python-2.2.4.dist-info}/WHEEL +1 -1
- polydb/__init__.py +2 -2
- polydb/adapters/AzureBlobStorageAdapter.py +146 -41
- polydb/adapters/AzureFileStorageAdapter.py +148 -43
- polydb/adapters/AzureQueueAdapter.py +96 -34
- polydb/adapters/AzureTableStorageAdapter.py +462 -119
- polydb/adapters/BlockchainBlobAdapter.py +111 -0
- polydb/adapters/BlockchainKVAdapter.py +152 -0
- polydb/adapters/BlockchainQueueAdapter.py +116 -0
- polydb/adapters/DynamoDBAdapter.py +463 -176
- polydb/adapters/FirestoreAdapter.py +320 -148
- polydb/adapters/GCPPubSubAdapter.py +217 -0
- polydb/adapters/GCPStorageAdapter.py +184 -39
- polydb/adapters/MongoDBAdapter.py +159 -39
- polydb/adapters/PostgreSQLAdapter.py +285 -83
- polydb/adapters/S3Adapter.py +172 -35
- polydb/adapters/S3CompatibleAdapter.py +62 -8
- polydb/adapters/SQSAdapter.py +121 -44
- polydb/adapters/VercelBlobAdapter.py +196 -0
- polydb/adapters/VercelKVAdapter.py +275 -283
- polydb/adapters/VercelQueueAdapter.py +61 -0
- polydb/audit/AuditStorage.py +1 -1
- polydb/base/NoSQLKVAdapter.py +113 -101
- polydb/base/ObjectStorageAdapter.py +42 -6
- polydb/base/QueueAdapter.py +2 -2
- polydb/base/SharedFilesAdapter.py +2 -2
- polydb/cloudDatabaseFactory.py +200 -0
- polydb/databaseFactory.py +434 -101
- polydb/models.py +63 -1
- polydb/query.py +111 -42
- altcodepro_polydb_python-2.2.2.dist-info/METADATA +0 -379
- altcodepro_polydb_python-2.2.2.dist-info/RECORD +0 -52
- polydb/adapters/PubSubAdapter.py +0 -85
- polydb/factory.py +0 -107
- {altcodepro_polydb_python-2.2.2.dist-info → altcodepro_polydb_python-2.2.4.dist-info}/licenses/LICENSE +0 -0
- {altcodepro_polydb_python-2.2.2.dist-info → altcodepro_polydb_python-2.2.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import threading
|
|
5
|
+
from typing import Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
from .models import (
|
|
8
|
+
AzureStorageConfig,
|
|
9
|
+
BlockchainStorageConfig,
|
|
10
|
+
CloudProvider,
|
|
11
|
+
GCPStorageConfig,
|
|
12
|
+
PartitionConfig,
|
|
13
|
+
StorageConfig,
|
|
14
|
+
VercelStorageConfig,
|
|
15
|
+
)
|
|
16
|
+
from .utils import setup_logger
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# ============================================================
|
|
20
|
+
# FACTORY
|
|
21
|
+
# ============================================================
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CloudDatabaseFactory:
|
|
25
|
+
"""
|
|
26
|
+
Multi-cloud factory (simple + production ready)
|
|
27
|
+
|
|
28
|
+
Supports:
|
|
29
|
+
- Typed configs (preferred)
|
|
30
|
+
- Env fallback
|
|
31
|
+
- Multiple named connections
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
provider: Optional[CloudProvider] = None,
|
|
37
|
+
storage_configs: Optional[List[StorageConfig]] = None,
|
|
38
|
+
):
|
|
39
|
+
self.logger = setup_logger(__name__)
|
|
40
|
+
|
|
41
|
+
self.provider = provider or self._detect_provider()
|
|
42
|
+
|
|
43
|
+
# map name -> config
|
|
44
|
+
self.configs: Dict[str, StorageConfig] = {}
|
|
45
|
+
if storage_configs:
|
|
46
|
+
for cfg in storage_configs:
|
|
47
|
+
self.configs[cfg.name] = cfg
|
|
48
|
+
|
|
49
|
+
self.instances: Dict[str, object] = {}
|
|
50
|
+
self._lock = threading.Lock()
|
|
51
|
+
|
|
52
|
+
self.logger.info(f"Factory initialized (default provider={self.provider.value})")
|
|
53
|
+
|
|
54
|
+
# --------------------------------------------------------
|
|
55
|
+
# Provider detection (env fallback)
|
|
56
|
+
# --------------------------------------------------------
|
|
57
|
+
def _detect_provider(self) -> CloudProvider:
|
|
58
|
+
explicit = os.getenv("CLOUD_PROVIDER")
|
|
59
|
+
if explicit:
|
|
60
|
+
try:
|
|
61
|
+
return CloudProvider(explicit.lower())
|
|
62
|
+
except Exception:
|
|
63
|
+
self.logger.warning(f"Invalid CLOUD_PROVIDER: {explicit}")
|
|
64
|
+
|
|
65
|
+
if os.getenv("AZURE_STORAGE_CONNECTION_STRING"):
|
|
66
|
+
return CloudProvider.AZURE
|
|
67
|
+
if os.getenv("AWS_ACCESS_KEY_ID"):
|
|
68
|
+
return CloudProvider.AWS
|
|
69
|
+
if os.getenv("GOOGLE_CLOUD_PROJECT"):
|
|
70
|
+
return CloudProvider.GCP
|
|
71
|
+
if os.getenv("VERCEL_ENV"):
|
|
72
|
+
return CloudProvider.VERCEL
|
|
73
|
+
|
|
74
|
+
return CloudProvider.POSTGRESQL
|
|
75
|
+
|
|
76
|
+
# --------------------------------------------------------
|
|
77
|
+
# OBJECT STORAGE
|
|
78
|
+
# --------------------------------------------------------
|
|
79
|
+
def get_object_storage(self, name: str = "default"):
|
|
80
|
+
with self._lock:
|
|
81
|
+
if name in self.instances:
|
|
82
|
+
return self.instances[name]
|
|
83
|
+
|
|
84
|
+
cfg = self.configs.get(name)
|
|
85
|
+
if not cfg:
|
|
86
|
+
cfg = StorageConfig(provider=self.provider, name=name)
|
|
87
|
+
|
|
88
|
+
provider = cfg.provider
|
|
89
|
+
|
|
90
|
+
# ---------------- AZURE ----------------
|
|
91
|
+
if provider == CloudProvider.AZURE:
|
|
92
|
+
from .adapters.AzureBlobStorageAdapter import AzureBlobStorageAdapter
|
|
93
|
+
|
|
94
|
+
connection_string = None
|
|
95
|
+
container = None
|
|
96
|
+
|
|
97
|
+
if isinstance(cfg, AzureStorageConfig):
|
|
98
|
+
connection_string = cfg.connection_string
|
|
99
|
+
container = cfg.container
|
|
100
|
+
|
|
101
|
+
instance = AzureBlobStorageAdapter(
|
|
102
|
+
connection_string=connection_string or "",
|
|
103
|
+
container_name=container or "",
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# ---------------- AWS / S3 ----------------
|
|
107
|
+
elif provider in (CloudProvider.AWS, CloudProvider.S3_COMPATIBLE):
|
|
108
|
+
from .adapters.S3CompatibleAdapter import S3CompatibleAdapter
|
|
109
|
+
|
|
110
|
+
instance = S3CompatibleAdapter()
|
|
111
|
+
|
|
112
|
+
# ---------------- GCP ----------------
|
|
113
|
+
elif provider == CloudProvider.GCP:
|
|
114
|
+
from .adapters.GCPStorageAdapter import GCPStorageAdapter
|
|
115
|
+
|
|
116
|
+
bucket = None
|
|
117
|
+
if isinstance(cfg, GCPStorageConfig):
|
|
118
|
+
bucket = cfg.bucket
|
|
119
|
+
|
|
120
|
+
instance = GCPStorageAdapter(bucket_name=bucket)
|
|
121
|
+
|
|
122
|
+
# ---------------- VERCEL ----------------
|
|
123
|
+
elif provider == CloudProvider.VERCEL:
|
|
124
|
+
from .adapters.VercelBlobAdapter import VercelBlobAdapter
|
|
125
|
+
|
|
126
|
+
token = None
|
|
127
|
+
timeout = 10
|
|
128
|
+
|
|
129
|
+
if isinstance(cfg, VercelStorageConfig):
|
|
130
|
+
token = cfg.token
|
|
131
|
+
timeout = cfg.timeout
|
|
132
|
+
|
|
133
|
+
instance = VercelBlobAdapter(token=token or "", timeout=timeout)
|
|
134
|
+
|
|
135
|
+
# ---------------- BLOCKCHAIN ----------------
|
|
136
|
+
elif provider == CloudProvider.BLOCKCHAIN:
|
|
137
|
+
from .adapters.BlockchainBlobAdapter import BlockchainBlobAdapter
|
|
138
|
+
|
|
139
|
+
ipfs_url = None
|
|
140
|
+
if isinstance(cfg, BlockchainStorageConfig):
|
|
141
|
+
ipfs_url = cfg.ipfs_url
|
|
142
|
+
|
|
143
|
+
instance = BlockchainBlobAdapter(ipfs_url=ipfs_url)
|
|
144
|
+
|
|
145
|
+
# ---------------- DEFAULT ----------------
|
|
146
|
+
else:
|
|
147
|
+
from .adapters.S3CompatibleAdapter import S3CompatibleAdapter
|
|
148
|
+
|
|
149
|
+
self.logger.warning(f"Fallback to S3-compatible for provider={provider}")
|
|
150
|
+
instance = S3CompatibleAdapter()
|
|
151
|
+
|
|
152
|
+
self.instances[name] = instance
|
|
153
|
+
return instance
|
|
154
|
+
|
|
155
|
+
# --------------------------------------------------------
|
|
156
|
+
# KV / NoSQL
|
|
157
|
+
# --------------------------------------------------------
|
|
158
|
+
def get_nosql_kv(
|
|
159
|
+
self,
|
|
160
|
+
partition_config: Optional[PartitionConfig] = None,
|
|
161
|
+
):
|
|
162
|
+
if self.provider == CloudProvider.AZURE:
|
|
163
|
+
from .adapters.AzureTableStorageAdapter import AzureTableStorageAdapter
|
|
164
|
+
|
|
165
|
+
return AzureTableStorageAdapter(partition_config)
|
|
166
|
+
|
|
167
|
+
if self.provider == CloudProvider.AWS:
|
|
168
|
+
from .adapters.DynamoDBAdapter import DynamoDBAdapter
|
|
169
|
+
|
|
170
|
+
return DynamoDBAdapter(partition_config)
|
|
171
|
+
|
|
172
|
+
if self.provider == CloudProvider.GCP:
|
|
173
|
+
from .adapters.FirestoreAdapter import FirestoreAdapter
|
|
174
|
+
|
|
175
|
+
return FirestoreAdapter(partition_config)
|
|
176
|
+
|
|
177
|
+
if self.provider == CloudProvider.VERCEL:
|
|
178
|
+
from .adapters.VercelKVAdapter import VercelKVAdapter
|
|
179
|
+
|
|
180
|
+
return VercelKVAdapter(partition_config)
|
|
181
|
+
|
|
182
|
+
if self.provider == CloudProvider.BLOCKCHAIN:
|
|
183
|
+
from .adapters.BlockchainKVAdapter import BlockchainKVAdapter
|
|
184
|
+
|
|
185
|
+
return BlockchainKVAdapter()
|
|
186
|
+
|
|
187
|
+
from .adapters.MongoDBAdapter import MongoDBAdapter
|
|
188
|
+
|
|
189
|
+
return MongoDBAdapter(partition_config)
|
|
190
|
+
|
|
191
|
+
# --------------------------------------------------------
|
|
192
|
+
# SQL
|
|
193
|
+
# --------------------------------------------------------
|
|
194
|
+
def get_sql(self):
|
|
195
|
+
from .adapters.PostgreSQLAdapter import PostgreSQLAdapter
|
|
196
|
+
|
|
197
|
+
with self._lock:
|
|
198
|
+
if "sql" not in self.instances:
|
|
199
|
+
self.instances["sql"] = PostgreSQLAdapter()
|
|
200
|
+
return self.instances["sql"]
|