wappa 0.1.0__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.
Potentially problematic release.
This version of wappa might be problematic. Click here for more details.
- wappa/__init__.py +85 -0
- wappa/api/__init__.py +1 -0
- wappa/api/controllers/__init__.py +10 -0
- wappa/api/controllers/webhook_controller.py +441 -0
- wappa/api/dependencies/__init__.py +15 -0
- wappa/api/dependencies/whatsapp_dependencies.py +220 -0
- wappa/api/dependencies/whatsapp_media_dependencies.py +26 -0
- wappa/api/middleware/__init__.py +7 -0
- wappa/api/middleware/error_handler.py +158 -0
- wappa/api/middleware/owner.py +99 -0
- wappa/api/middleware/request_logging.py +184 -0
- wappa/api/routes/__init__.py +6 -0
- wappa/api/routes/health.py +102 -0
- wappa/api/routes/webhooks.py +211 -0
- wappa/api/routes/whatsapp/__init__.py +15 -0
- wappa/api/routes/whatsapp/whatsapp_interactive.py +429 -0
- wappa/api/routes/whatsapp/whatsapp_media.py +440 -0
- wappa/api/routes/whatsapp/whatsapp_messages.py +195 -0
- wappa/api/routes/whatsapp/whatsapp_specialized.py +516 -0
- wappa/api/routes/whatsapp/whatsapp_templates.py +431 -0
- wappa/api/routes/whatsapp_combined.py +35 -0
- wappa/cli/__init__.py +9 -0
- wappa/cli/main.py +199 -0
- wappa/core/__init__.py +6 -0
- wappa/core/config/__init__.py +5 -0
- wappa/core/config/settings.py +161 -0
- wappa/core/events/__init__.py +41 -0
- wappa/core/events/default_handlers.py +642 -0
- wappa/core/events/event_dispatcher.py +244 -0
- wappa/core/events/event_handler.py +247 -0
- wappa/core/events/webhook_factory.py +219 -0
- wappa/core/factory/__init__.py +15 -0
- wappa/core/factory/plugin.py +68 -0
- wappa/core/factory/wappa_builder.py +326 -0
- wappa/core/logging/__init__.py +5 -0
- wappa/core/logging/context.py +100 -0
- wappa/core/logging/logger.py +343 -0
- wappa/core/plugins/__init__.py +34 -0
- wappa/core/plugins/auth_plugin.py +169 -0
- wappa/core/plugins/cors_plugin.py +128 -0
- wappa/core/plugins/custom_middleware_plugin.py +182 -0
- wappa/core/plugins/database_plugin.py +235 -0
- wappa/core/plugins/rate_limit_plugin.py +183 -0
- wappa/core/plugins/redis_plugin.py +224 -0
- wappa/core/plugins/wappa_core_plugin.py +261 -0
- wappa/core/plugins/webhook_plugin.py +253 -0
- wappa/core/types.py +108 -0
- wappa/core/wappa_app.py +546 -0
- wappa/database/__init__.py +18 -0
- wappa/database/adapter.py +107 -0
- wappa/database/adapters/__init__.py +17 -0
- wappa/database/adapters/mysql_adapter.py +187 -0
- wappa/database/adapters/postgresql_adapter.py +169 -0
- wappa/database/adapters/sqlite_adapter.py +174 -0
- wappa/domain/__init__.py +28 -0
- wappa/domain/builders/__init__.py +5 -0
- wappa/domain/builders/message_builder.py +189 -0
- wappa/domain/entities/__init__.py +5 -0
- wappa/domain/enums/messenger_platform.py +123 -0
- wappa/domain/factories/__init__.py +6 -0
- wappa/domain/factories/media_factory.py +450 -0
- wappa/domain/factories/message_factory.py +497 -0
- wappa/domain/factories/messenger_factory.py +244 -0
- wappa/domain/interfaces/__init__.py +32 -0
- wappa/domain/interfaces/base_repository.py +94 -0
- wappa/domain/interfaces/cache_factory.py +85 -0
- wappa/domain/interfaces/cache_interface.py +199 -0
- wappa/domain/interfaces/expiry_repository.py +68 -0
- wappa/domain/interfaces/media_interface.py +311 -0
- wappa/domain/interfaces/messaging_interface.py +523 -0
- wappa/domain/interfaces/pubsub_repository.py +151 -0
- wappa/domain/interfaces/repository_factory.py +108 -0
- wappa/domain/interfaces/shared_state_repository.py +122 -0
- wappa/domain/interfaces/state_repository.py +123 -0
- wappa/domain/interfaces/tables_repository.py +215 -0
- wappa/domain/interfaces/user_repository.py +114 -0
- wappa/domain/interfaces/webhooks/__init__.py +1 -0
- wappa/domain/models/media_result.py +110 -0
- wappa/domain/models/platforms/__init__.py +15 -0
- wappa/domain/models/platforms/platform_config.py +104 -0
- wappa/domain/services/__init__.py +11 -0
- wappa/domain/services/tenant_credentials_service.py +56 -0
- wappa/messaging/__init__.py +7 -0
- wappa/messaging/whatsapp/__init__.py +1 -0
- wappa/messaging/whatsapp/client/__init__.py +5 -0
- wappa/messaging/whatsapp/client/whatsapp_client.py +417 -0
- wappa/messaging/whatsapp/handlers/__init__.py +13 -0
- wappa/messaging/whatsapp/handlers/whatsapp_interactive_handler.py +653 -0
- wappa/messaging/whatsapp/handlers/whatsapp_media_handler.py +579 -0
- wappa/messaging/whatsapp/handlers/whatsapp_specialized_handler.py +434 -0
- wappa/messaging/whatsapp/handlers/whatsapp_template_handler.py +416 -0
- wappa/messaging/whatsapp/messenger/__init__.py +5 -0
- wappa/messaging/whatsapp/messenger/whatsapp_messenger.py +904 -0
- wappa/messaging/whatsapp/models/__init__.py +61 -0
- wappa/messaging/whatsapp/models/basic_models.py +65 -0
- wappa/messaging/whatsapp/models/interactive_models.py +287 -0
- wappa/messaging/whatsapp/models/media_models.py +215 -0
- wappa/messaging/whatsapp/models/specialized_models.py +304 -0
- wappa/messaging/whatsapp/models/template_models.py +261 -0
- wappa/persistence/cache_factory.py +93 -0
- wappa/persistence/json/__init__.py +14 -0
- wappa/persistence/json/cache_adapters.py +271 -0
- wappa/persistence/json/handlers/__init__.py +1 -0
- wappa/persistence/json/handlers/state_handler.py +250 -0
- wappa/persistence/json/handlers/table_handler.py +263 -0
- wappa/persistence/json/handlers/user_handler.py +213 -0
- wappa/persistence/json/handlers/utils/__init__.py +1 -0
- wappa/persistence/json/handlers/utils/file_manager.py +153 -0
- wappa/persistence/json/handlers/utils/key_factory.py +11 -0
- wappa/persistence/json/handlers/utils/serialization.py +121 -0
- wappa/persistence/json/json_cache_factory.py +76 -0
- wappa/persistence/json/storage_manager.py +285 -0
- wappa/persistence/memory/__init__.py +14 -0
- wappa/persistence/memory/cache_adapters.py +271 -0
- wappa/persistence/memory/handlers/__init__.py +1 -0
- wappa/persistence/memory/handlers/state_handler.py +250 -0
- wappa/persistence/memory/handlers/table_handler.py +280 -0
- wappa/persistence/memory/handlers/user_handler.py +213 -0
- wappa/persistence/memory/handlers/utils/__init__.py +1 -0
- wappa/persistence/memory/handlers/utils/key_factory.py +11 -0
- wappa/persistence/memory/handlers/utils/memory_store.py +317 -0
- wappa/persistence/memory/handlers/utils/ttl_manager.py +235 -0
- wappa/persistence/memory/memory_cache_factory.py +76 -0
- wappa/persistence/memory/storage_manager.py +235 -0
- wappa/persistence/redis/README.md +699 -0
- wappa/persistence/redis/__init__.py +11 -0
- wappa/persistence/redis/cache_adapters.py +285 -0
- wappa/persistence/redis/ops.py +880 -0
- wappa/persistence/redis/redis_cache_factory.py +71 -0
- wappa/persistence/redis/redis_client.py +231 -0
- wappa/persistence/redis/redis_handler/__init__.py +26 -0
- wappa/persistence/redis/redis_handler/state_handler.py +176 -0
- wappa/persistence/redis/redis_handler/table.py +158 -0
- wappa/persistence/redis/redis_handler/user.py +138 -0
- wappa/persistence/redis/redis_handler/utils/__init__.py +12 -0
- wappa/persistence/redis/redis_handler/utils/key_factory.py +32 -0
- wappa/persistence/redis/redis_handler/utils/serde.py +146 -0
- wappa/persistence/redis/redis_handler/utils/tenant_cache.py +268 -0
- wappa/persistence/redis/redis_manager.py +189 -0
- wappa/processors/__init__.py +6 -0
- wappa/processors/base_processor.py +262 -0
- wappa/processors/factory.py +550 -0
- wappa/processors/whatsapp_processor.py +810 -0
- wappa/schemas/__init__.py +6 -0
- wappa/schemas/core/__init__.py +71 -0
- wappa/schemas/core/base_message.py +499 -0
- wappa/schemas/core/base_status.py +322 -0
- wappa/schemas/core/base_webhook.py +312 -0
- wappa/schemas/core/types.py +253 -0
- wappa/schemas/core/webhook_interfaces/__init__.py +48 -0
- wappa/schemas/core/webhook_interfaces/base_components.py +293 -0
- wappa/schemas/core/webhook_interfaces/universal_webhooks.py +348 -0
- wappa/schemas/factory.py +754 -0
- wappa/schemas/webhooks/__init__.py +3 -0
- wappa/schemas/whatsapp/__init__.py +6 -0
- wappa/schemas/whatsapp/base_models.py +285 -0
- wappa/schemas/whatsapp/message_types/__init__.py +93 -0
- wappa/schemas/whatsapp/message_types/audio.py +350 -0
- wappa/schemas/whatsapp/message_types/button.py +267 -0
- wappa/schemas/whatsapp/message_types/contact.py +464 -0
- wappa/schemas/whatsapp/message_types/document.py +421 -0
- wappa/schemas/whatsapp/message_types/errors.py +195 -0
- wappa/schemas/whatsapp/message_types/image.py +424 -0
- wappa/schemas/whatsapp/message_types/interactive.py +430 -0
- wappa/schemas/whatsapp/message_types/location.py +416 -0
- wappa/schemas/whatsapp/message_types/order.py +372 -0
- wappa/schemas/whatsapp/message_types/reaction.py +271 -0
- wappa/schemas/whatsapp/message_types/sticker.py +328 -0
- wappa/schemas/whatsapp/message_types/system.py +317 -0
- wappa/schemas/whatsapp/message_types/text.py +411 -0
- wappa/schemas/whatsapp/message_types/unsupported.py +273 -0
- wappa/schemas/whatsapp/message_types/video.py +344 -0
- wappa/schemas/whatsapp/status_models.py +479 -0
- wappa/schemas/whatsapp/validators.py +454 -0
- wappa/schemas/whatsapp/webhook_container.py +438 -0
- wappa/webhooks/__init__.py +17 -0
- wappa/webhooks/core/__init__.py +71 -0
- wappa/webhooks/core/base_message.py +499 -0
- wappa/webhooks/core/base_status.py +322 -0
- wappa/webhooks/core/base_webhook.py +312 -0
- wappa/webhooks/core/types.py +253 -0
- wappa/webhooks/core/webhook_interfaces/__init__.py +48 -0
- wappa/webhooks/core/webhook_interfaces/base_components.py +293 -0
- wappa/webhooks/core/webhook_interfaces/universal_webhooks.py +441 -0
- wappa/webhooks/factory.py +754 -0
- wappa/webhooks/whatsapp/__init__.py +6 -0
- wappa/webhooks/whatsapp/base_models.py +285 -0
- wappa/webhooks/whatsapp/message_types/__init__.py +93 -0
- wappa/webhooks/whatsapp/message_types/audio.py +350 -0
- wappa/webhooks/whatsapp/message_types/button.py +267 -0
- wappa/webhooks/whatsapp/message_types/contact.py +464 -0
- wappa/webhooks/whatsapp/message_types/document.py +421 -0
- wappa/webhooks/whatsapp/message_types/errors.py +195 -0
- wappa/webhooks/whatsapp/message_types/image.py +424 -0
- wappa/webhooks/whatsapp/message_types/interactive.py +430 -0
- wappa/webhooks/whatsapp/message_types/location.py +416 -0
- wappa/webhooks/whatsapp/message_types/order.py +372 -0
- wappa/webhooks/whatsapp/message_types/reaction.py +271 -0
- wappa/webhooks/whatsapp/message_types/sticker.py +328 -0
- wappa/webhooks/whatsapp/message_types/system.py +317 -0
- wappa/webhooks/whatsapp/message_types/text.py +411 -0
- wappa/webhooks/whatsapp/message_types/unsupported.py +273 -0
- wappa/webhooks/whatsapp/message_types/video.py +344 -0
- wappa/webhooks/whatsapp/status_models.py +479 -0
- wappa/webhooks/whatsapp/validators.py +454 -0
- wappa/webhooks/whatsapp/webhook_container.py +438 -0
- wappa-0.1.0.dist-info/METADATA +269 -0
- wappa-0.1.0.dist-info/RECORD +211 -0
- wappa-0.1.0.dist-info/WHEEL +4 -0
- wappa-0.1.0.dist-info/entry_points.txt +2 -0
- wappa-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Memory storage manager for coordinating cache operations.
|
|
3
|
+
|
|
4
|
+
Provides high-level interface for memory cache operations with TTL support,
|
|
5
|
+
BaseModel serialization, and thread-safe operations.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Any, Optional
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
from .handlers.utils.memory_store import get_memory_store
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger("MemoryStorageManager")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class MemoryStorageManager:
|
|
19
|
+
"""High-level memory storage operations manager."""
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
self.memory_store = get_memory_store()
|
|
23
|
+
|
|
24
|
+
def _serialize_data(self, data: Any) -> Any:
|
|
25
|
+
"""Serialize data for memory storage (BaseModel -> dict)."""
|
|
26
|
+
if isinstance(data, BaseModel):
|
|
27
|
+
return data.model_dump()
|
|
28
|
+
return data
|
|
29
|
+
|
|
30
|
+
def _deserialize_data(self, data: Any, model: type[BaseModel] | None = None) -> Any:
|
|
31
|
+
"""Deserialize data from memory storage."""
|
|
32
|
+
if data is None:
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
if model is not None and isinstance(data, dict):
|
|
36
|
+
return model.model_validate(data)
|
|
37
|
+
|
|
38
|
+
return data
|
|
39
|
+
|
|
40
|
+
async def get(
|
|
41
|
+
self,
|
|
42
|
+
cache_type: str,
|
|
43
|
+
tenant_id: str,
|
|
44
|
+
user_id: Optional[str],
|
|
45
|
+
key: str,
|
|
46
|
+
model: type[BaseModel] | None = None
|
|
47
|
+
) -> Any:
|
|
48
|
+
"""
|
|
49
|
+
Get value from memory cache.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
cache_type: "users", "tables", or "states"
|
|
53
|
+
tenant_id: Tenant identifier
|
|
54
|
+
user_id: User identifier (required for users/states)
|
|
55
|
+
key: Cache key
|
|
56
|
+
model: Optional BaseModel for deserialization
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Cached value or None if not found/expired
|
|
60
|
+
"""
|
|
61
|
+
try:
|
|
62
|
+
context_key = self._build_context_key(cache_type, tenant_id, user_id)
|
|
63
|
+
data = await self.memory_store.get(cache_type, context_key, key)
|
|
64
|
+
return self._deserialize_data(data, model)
|
|
65
|
+
except Exception as e:
|
|
66
|
+
logger.error(f"Failed to get key '{key}' from {cache_type} cache: {e}")
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
async def set(
|
|
70
|
+
self,
|
|
71
|
+
cache_type: str,
|
|
72
|
+
tenant_id: str,
|
|
73
|
+
user_id: Optional[str],
|
|
74
|
+
key: str,
|
|
75
|
+
value: Any,
|
|
76
|
+
ttl: Optional[int] = None
|
|
77
|
+
) -> bool:
|
|
78
|
+
"""
|
|
79
|
+
Set value in memory cache.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
cache_type: "users", "tables", or "states"
|
|
83
|
+
tenant_id: Tenant identifier
|
|
84
|
+
user_id: User identifier (required for users/states)
|
|
85
|
+
key: Cache key
|
|
86
|
+
value: Value to cache
|
|
87
|
+
ttl: Time to live in seconds
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
True if successful, False otherwise
|
|
91
|
+
"""
|
|
92
|
+
try:
|
|
93
|
+
context_key = self._build_context_key(cache_type, tenant_id, user_id)
|
|
94
|
+
serialized_value = self._serialize_data(value)
|
|
95
|
+
return await self.memory_store.set(cache_type, context_key, key, serialized_value, ttl)
|
|
96
|
+
except Exception as e:
|
|
97
|
+
logger.error(f"Failed to set key '{key}' in {cache_type} cache: {e}")
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
async def delete(
|
|
101
|
+
self,
|
|
102
|
+
cache_type: str,
|
|
103
|
+
tenant_id: str,
|
|
104
|
+
user_id: Optional[str],
|
|
105
|
+
key: str
|
|
106
|
+
) -> bool:
|
|
107
|
+
"""
|
|
108
|
+
Delete key from memory cache.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
cache_type: "users", "tables", or "states"
|
|
112
|
+
tenant_id: Tenant identifier
|
|
113
|
+
user_id: User identifier (required for users/states)
|
|
114
|
+
key: Cache key to delete
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
True if deleted or didn't exist, False on error
|
|
118
|
+
"""
|
|
119
|
+
try:
|
|
120
|
+
context_key = self._build_context_key(cache_type, tenant_id, user_id)
|
|
121
|
+
return await self.memory_store.delete(cache_type, context_key, key)
|
|
122
|
+
except Exception as e:
|
|
123
|
+
logger.error(f"Failed to delete key '{key}' from {cache_type} cache: {e}")
|
|
124
|
+
return False
|
|
125
|
+
|
|
126
|
+
async def exists(
|
|
127
|
+
self,
|
|
128
|
+
cache_type: str,
|
|
129
|
+
tenant_id: str,
|
|
130
|
+
user_id: Optional[str],
|
|
131
|
+
key: str
|
|
132
|
+
) -> bool:
|
|
133
|
+
"""
|
|
134
|
+
Check if key exists in memory cache.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
cache_type: "users", "tables", or "states"
|
|
138
|
+
tenant_id: Tenant identifier
|
|
139
|
+
user_id: User identifier (required for users/states)
|
|
140
|
+
key: Cache key to check
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
True if exists and not expired, False otherwise
|
|
144
|
+
"""
|
|
145
|
+
try:
|
|
146
|
+
context_key = self._build_context_key(cache_type, tenant_id, user_id)
|
|
147
|
+
return await self.memory_store.exists(cache_type, context_key, key)
|
|
148
|
+
except Exception as e:
|
|
149
|
+
logger.error(f"Failed to check existence of key '{key}' in {cache_type} cache: {e}")
|
|
150
|
+
return False
|
|
151
|
+
|
|
152
|
+
async def get_ttl(
|
|
153
|
+
self,
|
|
154
|
+
cache_type: str,
|
|
155
|
+
tenant_id: str,
|
|
156
|
+
user_id: Optional[str],
|
|
157
|
+
key: str
|
|
158
|
+
) -> int:
|
|
159
|
+
"""
|
|
160
|
+
Get remaining TTL for key.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Remaining TTL in seconds, -1 if no expiry, -2 if doesn't exist
|
|
164
|
+
"""
|
|
165
|
+
try:
|
|
166
|
+
context_key = self._build_context_key(cache_type, tenant_id, user_id)
|
|
167
|
+
return await self.memory_store.get_ttl(cache_type, context_key, key)
|
|
168
|
+
except Exception as e:
|
|
169
|
+
logger.error(f"Failed to get TTL for key '{key}' in {cache_type} cache: {e}")
|
|
170
|
+
return -2
|
|
171
|
+
|
|
172
|
+
async def set_ttl(
|
|
173
|
+
self,
|
|
174
|
+
cache_type: str,
|
|
175
|
+
tenant_id: str,
|
|
176
|
+
user_id: Optional[str],
|
|
177
|
+
key: str,
|
|
178
|
+
ttl: int
|
|
179
|
+
) -> bool:
|
|
180
|
+
"""
|
|
181
|
+
Set TTL for key.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
ttl: Time to live in seconds
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
True if successful, False otherwise
|
|
188
|
+
"""
|
|
189
|
+
try:
|
|
190
|
+
context_key = self._build_context_key(cache_type, tenant_id, user_id)
|
|
191
|
+
return await self.memory_store.set_ttl(cache_type, context_key, key, ttl)
|
|
192
|
+
except Exception as e:
|
|
193
|
+
logger.error(f"Failed to set TTL for key '{key}' in {cache_type} cache: {e}")
|
|
194
|
+
return False
|
|
195
|
+
|
|
196
|
+
async def get_all_keys(
|
|
197
|
+
self,
|
|
198
|
+
cache_type: str,
|
|
199
|
+
tenant_id: str,
|
|
200
|
+
user_id: Optional[str]
|
|
201
|
+
) -> dict[str, Any]:
|
|
202
|
+
"""
|
|
203
|
+
Get all keys for a context.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
cache_type: "users", "tables", or "states"
|
|
207
|
+
tenant_id: Tenant identifier
|
|
208
|
+
user_id: User identifier (required for users/states)
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
Dictionary of all non-expired key-value pairs
|
|
212
|
+
"""
|
|
213
|
+
try:
|
|
214
|
+
context_key = self._build_context_key(cache_type, tenant_id, user_id)
|
|
215
|
+
return await self.memory_store.get_all_keys(cache_type, context_key)
|
|
216
|
+
except Exception as e:
|
|
217
|
+
logger.error(f"Failed to get all keys from {cache_type} cache: {e}")
|
|
218
|
+
return {}
|
|
219
|
+
|
|
220
|
+
def _build_context_key(self, cache_type: str, tenant_id: str, user_id: Optional[str]) -> str:
|
|
221
|
+
"""Build context key for isolation."""
|
|
222
|
+
if cache_type == "tables":
|
|
223
|
+
# Tables only use tenant_id for context
|
|
224
|
+
return tenant_id
|
|
225
|
+
elif cache_type in ["users", "states"]:
|
|
226
|
+
# Users and states use tenant_id and user_id
|
|
227
|
+
if not user_id:
|
|
228
|
+
raise ValueError(f"user_id is required for {cache_type} cache")
|
|
229
|
+
return f"{tenant_id}_{user_id}"
|
|
230
|
+
else:
|
|
231
|
+
raise ValueError(f"Invalid cache_type: {cache_type}")
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
# Global storage manager instance
|
|
235
|
+
storage_manager = MemoryStorageManager()
|