mdb-engine 0.1.6__py3-none-any.whl → 0.4.12__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.
- mdb_engine/__init__.py +116 -11
- mdb_engine/auth/ARCHITECTURE.md +112 -0
- mdb_engine/auth/README.md +654 -11
- mdb_engine/auth/__init__.py +136 -29
- mdb_engine/auth/audit.py +592 -0
- mdb_engine/auth/base.py +252 -0
- mdb_engine/auth/casbin_factory.py +265 -70
- mdb_engine/auth/config_defaults.py +5 -5
- mdb_engine/auth/config_helpers.py +19 -18
- mdb_engine/auth/cookie_utils.py +12 -16
- mdb_engine/auth/csrf.py +483 -0
- mdb_engine/auth/decorators.py +10 -16
- mdb_engine/auth/dependencies.py +69 -71
- mdb_engine/auth/helpers.py +3 -3
- mdb_engine/auth/integration.py +61 -88
- mdb_engine/auth/jwt.py +11 -15
- mdb_engine/auth/middleware.py +79 -35
- mdb_engine/auth/oso_factory.py +21 -41
- mdb_engine/auth/provider.py +270 -171
- mdb_engine/auth/rate_limiter.py +505 -0
- mdb_engine/auth/restrictions.py +21 -36
- mdb_engine/auth/session_manager.py +24 -41
- mdb_engine/auth/shared_middleware.py +977 -0
- mdb_engine/auth/shared_users.py +775 -0
- mdb_engine/auth/token_lifecycle.py +10 -12
- mdb_engine/auth/token_store.py +17 -32
- mdb_engine/auth/users.py +99 -159
- mdb_engine/auth/utils.py +236 -42
- mdb_engine/cli/commands/generate.py +546 -10
- mdb_engine/cli/commands/validate.py +3 -7
- mdb_engine/cli/utils.py +7 -7
- mdb_engine/config.py +13 -28
- mdb_engine/constants.py +65 -0
- mdb_engine/core/README.md +117 -6
- mdb_engine/core/__init__.py +39 -7
- mdb_engine/core/app_registration.py +31 -50
- mdb_engine/core/app_secrets.py +289 -0
- mdb_engine/core/connection.py +20 -12
- mdb_engine/core/encryption.py +222 -0
- mdb_engine/core/engine.py +2862 -115
- mdb_engine/core/index_management.py +12 -16
- mdb_engine/core/manifest.py +628 -204
- mdb_engine/core/ray_integration.py +436 -0
- mdb_engine/core/seeding.py +13 -21
- mdb_engine/core/service_initialization.py +20 -30
- mdb_engine/core/types.py +40 -43
- mdb_engine/database/README.md +140 -17
- mdb_engine/database/__init__.py +17 -6
- mdb_engine/database/abstraction.py +37 -50
- mdb_engine/database/connection.py +51 -30
- mdb_engine/database/query_validator.py +367 -0
- mdb_engine/database/resource_limiter.py +204 -0
- mdb_engine/database/scoped_wrapper.py +747 -237
- mdb_engine/dependencies.py +427 -0
- mdb_engine/di/__init__.py +34 -0
- mdb_engine/di/container.py +247 -0
- mdb_engine/di/providers.py +206 -0
- mdb_engine/di/scopes.py +139 -0
- mdb_engine/embeddings/README.md +54 -24
- mdb_engine/embeddings/__init__.py +31 -24
- mdb_engine/embeddings/dependencies.py +38 -155
- mdb_engine/embeddings/service.py +78 -75
- mdb_engine/exceptions.py +104 -12
- mdb_engine/indexes/README.md +30 -13
- mdb_engine/indexes/__init__.py +1 -0
- mdb_engine/indexes/helpers.py +11 -11
- mdb_engine/indexes/manager.py +59 -123
- mdb_engine/memory/README.md +95 -4
- mdb_engine/memory/__init__.py +1 -2
- mdb_engine/memory/service.py +363 -1168
- mdb_engine/observability/README.md +4 -2
- mdb_engine/observability/__init__.py +26 -9
- mdb_engine/observability/health.py +17 -17
- mdb_engine/observability/logging.py +10 -10
- mdb_engine/observability/metrics.py +40 -19
- mdb_engine/repositories/__init__.py +34 -0
- mdb_engine/repositories/base.py +325 -0
- mdb_engine/repositories/mongo.py +233 -0
- mdb_engine/repositories/unit_of_work.py +166 -0
- mdb_engine/routing/README.md +1 -1
- mdb_engine/routing/__init__.py +1 -3
- mdb_engine/routing/websockets.py +41 -75
- mdb_engine/utils/__init__.py +3 -1
- mdb_engine/utils/mongo.py +117 -0
- mdb_engine-0.4.12.dist-info/METADATA +492 -0
- mdb_engine-0.4.12.dist-info/RECORD +97 -0
- {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/WHEEL +1 -1
- mdb_engine-0.1.6.dist-info/METADATA +0 -213
- mdb_engine-0.1.6.dist-info/RECORD +0 -75
- {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/entry_points.txt +0 -0
- {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/licenses/LICENSE +0 -0
- {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/top_level.txt +0 -0
mdb_engine/exceptions.py
CHANGED
|
@@ -5,7 +5,7 @@ These exceptions provide more specific error types while maintaining
|
|
|
5
5
|
backward compatibility with RuntimeError.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import Any
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class MongoDBEngineError(RuntimeError):
|
|
@@ -21,7 +21,7 @@ class MongoDBEngineError(RuntimeError):
|
|
|
21
21
|
collection_name, etc.)
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
|
-
def __init__(self, message: str, context:
|
|
24
|
+
def __init__(self, message: str, context: dict[str, Any] | None = None) -> None:
|
|
25
25
|
"""
|
|
26
26
|
Initialize the exception.
|
|
27
27
|
|
|
@@ -58,9 +58,9 @@ class InitializationError(MongoDBEngineError):
|
|
|
58
58
|
def __init__(
|
|
59
59
|
self,
|
|
60
60
|
message: str,
|
|
61
|
-
mongo_uri:
|
|
62
|
-
db_name:
|
|
63
|
-
context:
|
|
61
|
+
mongo_uri: str | None = None,
|
|
62
|
+
db_name: str | None = None,
|
|
63
|
+
context: dict[str, Any] | None = None,
|
|
64
64
|
) -> None:
|
|
65
65
|
"""
|
|
66
66
|
Initialize the initialization error.
|
|
@@ -99,10 +99,10 @@ class ManifestValidationError(MongoDBEngineError):
|
|
|
99
99
|
def __init__(
|
|
100
100
|
self,
|
|
101
101
|
message: str,
|
|
102
|
-
error_paths:
|
|
103
|
-
manifest_slug:
|
|
104
|
-
schema_version:
|
|
105
|
-
context:
|
|
102
|
+
error_paths: list[str] | None = None,
|
|
103
|
+
manifest_slug: str | None = None,
|
|
104
|
+
schema_version: str | None = None,
|
|
105
|
+
context: dict[str, Any] | None = None,
|
|
106
106
|
) -> None:
|
|
107
107
|
"""
|
|
108
108
|
Initialize the manifest validation error.
|
|
@@ -144,9 +144,9 @@ class ConfigurationError(MongoDBEngineError):
|
|
|
144
144
|
def __init__(
|
|
145
145
|
self,
|
|
146
146
|
message: str,
|
|
147
|
-
config_key:
|
|
148
|
-
config_value:
|
|
149
|
-
context:
|
|
147
|
+
config_key: str | None = None,
|
|
148
|
+
config_value: Any | None = None,
|
|
149
|
+
context: dict[str, Any] | None = None,
|
|
150
150
|
) -> None:
|
|
151
151
|
"""
|
|
152
152
|
Initialize the configuration error.
|
|
@@ -165,3 +165,95 @@ class ConfigurationError(MongoDBEngineError):
|
|
|
165
165
|
super().__init__(message, context=context)
|
|
166
166
|
self.config_key = config_key
|
|
167
167
|
self.config_value = config_value
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class QueryValidationError(MongoDBEngineError):
|
|
171
|
+
"""
|
|
172
|
+
Raised when a query fails validation checks.
|
|
173
|
+
|
|
174
|
+
This exception is raised when a query contains dangerous operators,
|
|
175
|
+
exceeds complexity limits, or violates security policies.
|
|
176
|
+
|
|
177
|
+
Attributes:
|
|
178
|
+
message: Error message
|
|
179
|
+
query_type: Type of query that failed (filter, pipeline, etc.)
|
|
180
|
+
operator: Dangerous operator that was found (if applicable)
|
|
181
|
+
path: JSON path where the issue was found (if applicable)
|
|
182
|
+
context: Additional context information
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
def __init__(
|
|
186
|
+
self,
|
|
187
|
+
message: str,
|
|
188
|
+
query_type: str | None = None,
|
|
189
|
+
operator: str | None = None,
|
|
190
|
+
path: str | None = None,
|
|
191
|
+
context: dict[str, Any] | None = None,
|
|
192
|
+
) -> None:
|
|
193
|
+
"""
|
|
194
|
+
Initialize the query validation error.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
message: Error message
|
|
198
|
+
query_type: Type of query that failed (filter, pipeline, etc.)
|
|
199
|
+
operator: Dangerous operator that was found (if applicable)
|
|
200
|
+
path: JSON path where the issue was found (if applicable)
|
|
201
|
+
context: Additional context information
|
|
202
|
+
"""
|
|
203
|
+
context = context or {}
|
|
204
|
+
if query_type:
|
|
205
|
+
context["query_type"] = query_type
|
|
206
|
+
if operator:
|
|
207
|
+
context["operator"] = operator
|
|
208
|
+
if path:
|
|
209
|
+
context["path"] = path
|
|
210
|
+
super().__init__(message, context=context)
|
|
211
|
+
self.query_type = query_type
|
|
212
|
+
self.operator = operator
|
|
213
|
+
self.path = path
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class ResourceLimitExceeded(MongoDBEngineError):
|
|
217
|
+
"""
|
|
218
|
+
Raised when a resource limit is exceeded.
|
|
219
|
+
|
|
220
|
+
This exception is raised when queries exceed timeouts, result sizes,
|
|
221
|
+
or other resource limits.
|
|
222
|
+
|
|
223
|
+
Attributes:
|
|
224
|
+
message: Error message
|
|
225
|
+
limit_type: Type of limit that was exceeded (timeout, size, etc.)
|
|
226
|
+
limit_value: The limit value that was exceeded
|
|
227
|
+
actual_value: The actual value that exceeded the limit
|
|
228
|
+
context: Additional context information
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
def __init__(
|
|
232
|
+
self,
|
|
233
|
+
message: str,
|
|
234
|
+
limit_type: str | None = None,
|
|
235
|
+
limit_value: Any | None = None,
|
|
236
|
+
actual_value: Any | None = None,
|
|
237
|
+
context: dict[str, Any] | None = None,
|
|
238
|
+
) -> None:
|
|
239
|
+
"""
|
|
240
|
+
Initialize the resource limit exceeded error.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
message: Error message
|
|
244
|
+
limit_type: Type of limit that was exceeded (timeout, size, etc.)
|
|
245
|
+
limit_value: The limit value that was exceeded
|
|
246
|
+
actual_value: The actual value that exceeded the limit
|
|
247
|
+
context: Additional context information
|
|
248
|
+
"""
|
|
249
|
+
context = context or {}
|
|
250
|
+
if limit_type:
|
|
251
|
+
context["limit_type"] = limit_type
|
|
252
|
+
if limit_value is not None:
|
|
253
|
+
context["limit_value"] = limit_value
|
|
254
|
+
if actual_value is not None:
|
|
255
|
+
context["actual_value"] = actual_value
|
|
256
|
+
super().__init__(message, context=context)
|
|
257
|
+
self.limit_type = limit_type
|
|
258
|
+
self.limit_value = limit_value
|
|
259
|
+
self.actual_value = actual_value
|
mdb_engine/indexes/README.md
CHANGED
|
@@ -573,7 +573,7 @@ try:
|
|
|
573
573
|
collection_name="users",
|
|
574
574
|
index_definitions=index_definitions
|
|
575
575
|
)
|
|
576
|
-
except
|
|
576
|
+
except (PyMongoError, ValueError, TypeError) as e:
|
|
577
577
|
logger.error(f"Failed to create indexes: {e}", exc_info=True)
|
|
578
578
|
raise
|
|
579
579
|
```
|
|
@@ -613,12 +613,20 @@ index_definitions = [
|
|
|
613
613
|
}
|
|
614
614
|
]
|
|
615
615
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
616
|
+
# Get scoped database and collection
|
|
617
|
+
db = engine.get_scoped_db("my_app")
|
|
618
|
+
collection = db.users
|
|
619
|
+
|
|
620
|
+
# Use collection.index_manager for index operations
|
|
621
|
+
index_manager = collection.index_manager
|
|
622
|
+
for index_def in index_definitions:
|
|
623
|
+
if index_def["type"] == "regular":
|
|
624
|
+
await index_manager.create_index(
|
|
625
|
+
keys=list(index_def["keys"].items()),
|
|
626
|
+
name=index_def.get("name"),
|
|
627
|
+
**index_def.get("options", {})
|
|
628
|
+
)
|
|
629
|
+
# Handle other index types similarly...
|
|
622
630
|
```
|
|
623
631
|
|
|
624
632
|
### Multiple Collections
|
|
@@ -635,13 +643,22 @@ collections_with_indexes = {
|
|
|
635
643
|
]
|
|
636
644
|
}
|
|
637
645
|
|
|
646
|
+
# Get scoped database
|
|
647
|
+
db = engine.get_scoped_db("my_app")
|
|
648
|
+
|
|
649
|
+
# Use collection.index_manager for each collection
|
|
638
650
|
for collection_name, index_definitions in collections_with_indexes.items():
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
651
|
+
collection = getattr(db, collection_name)
|
|
652
|
+
index_manager = collection.index_manager
|
|
653
|
+
|
|
654
|
+
for index_def in index_definitions:
|
|
655
|
+
if index_def["type"] == "regular":
|
|
656
|
+
await index_manager.create_index(
|
|
657
|
+
keys=list(index_def["keys"].items()),
|
|
658
|
+
name=index_def.get("name"),
|
|
659
|
+
**index_def.get("options", {})
|
|
660
|
+
)
|
|
661
|
+
# Handle other index types similarly...
|
|
645
662
|
```
|
|
646
663
|
|
|
647
664
|
## Related Modules
|
mdb_engine/indexes/__init__.py
CHANGED
|
@@ -8,6 +8,7 @@ This module is part of MDB_ENGINE - MongoDB Engine.
|
|
|
8
8
|
|
|
9
9
|
# Re-export index managers from database module for convenience
|
|
10
10
|
from ..database.scoped_wrapper import AsyncAtlasIndexManager, AutoIndexManager
|
|
11
|
+
|
|
11
12
|
# Export high-level management functions
|
|
12
13
|
from .manager import normalize_json_def, run_index_creation_for_collection
|
|
13
14
|
|
mdb_engine/indexes/helpers.py
CHANGED
|
@@ -6,14 +6,14 @@ in index creation and management.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import logging
|
|
9
|
-
from typing import Any
|
|
9
|
+
from typing import Any
|
|
10
10
|
|
|
11
11
|
logger = logging.getLogger(__name__)
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def normalize_keys(
|
|
15
|
-
keys:
|
|
16
|
-
) ->
|
|
15
|
+
keys: dict[str, Any] | list[tuple[str, Any]],
|
|
16
|
+
) -> list[tuple[str, Any]]:
|
|
17
17
|
"""
|
|
18
18
|
Normalize index keys to a consistent format.
|
|
19
19
|
|
|
@@ -28,7 +28,7 @@ def normalize_keys(
|
|
|
28
28
|
return keys
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def keys_to_dict(keys:
|
|
31
|
+
def keys_to_dict(keys: dict[str, Any] | list[tuple[str, Any]]) -> dict[str, Any]:
|
|
32
32
|
"""
|
|
33
33
|
Convert index keys to dictionary format for comparison.
|
|
34
34
|
|
|
@@ -43,7 +43,7 @@ def keys_to_dict(keys: Union[Dict[str, Any], List[Tuple[str, Any]]]) -> Dict[str
|
|
|
43
43
|
return {k: v for k, v in keys}
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
def is_id_index(keys:
|
|
46
|
+
def is_id_index(keys: dict[str, Any] | list[tuple[str, Any]]) -> bool:
|
|
47
47
|
"""
|
|
48
48
|
Check if index keys target the _id field (which MongoDB creates automatically).
|
|
49
49
|
|
|
@@ -63,10 +63,10 @@ def is_id_index(keys: Union[Dict[str, Any], List[Tuple[str, Any]]]) -> bool:
|
|
|
63
63
|
async def check_and_update_index(
|
|
64
64
|
index_manager: Any,
|
|
65
65
|
index_name: str,
|
|
66
|
-
expected_keys:
|
|
67
|
-
expected_options:
|
|
66
|
+
expected_keys: dict[str, Any] | list[tuple[str, Any]],
|
|
67
|
+
expected_options: dict[str, Any] | None = None,
|
|
68
68
|
log_prefix: str = "",
|
|
69
|
-
) ->
|
|
69
|
+
) -> tuple[bool, dict[str, Any] | None]:
|
|
70
70
|
"""
|
|
71
71
|
Check if an index exists and matches the expected definition.
|
|
72
72
|
|
|
@@ -118,11 +118,11 @@ async def check_and_update_index(
|
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
def validate_index_definition_basic(
|
|
121
|
-
index_def:
|
|
121
|
+
index_def: dict[str, Any],
|
|
122
122
|
index_name: str,
|
|
123
|
-
required_fields:
|
|
123
|
+
required_fields: list[str],
|
|
124
124
|
log_prefix: str = "",
|
|
125
|
-
) ->
|
|
125
|
+
) -> tuple[bool, str | None]:
|
|
126
126
|
"""
|
|
127
127
|
Basic validation for index definitions.
|
|
128
128
|
|