mdb-engine 0.2.1__py3-none-any.whl → 0.2.3__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/auth/audit.py +40 -40
- mdb_engine/auth/base.py +3 -3
- mdb_engine/auth/casbin_factory.py +6 -6
- mdb_engine/auth/config_defaults.py +5 -5
- mdb_engine/auth/config_helpers.py +12 -12
- mdb_engine/auth/cookie_utils.py +9 -9
- mdb_engine/auth/csrf.py +9 -8
- mdb_engine/auth/decorators.py +7 -6
- mdb_engine/auth/dependencies.py +22 -21
- mdb_engine/auth/integration.py +9 -9
- mdb_engine/auth/jwt.py +9 -9
- mdb_engine/auth/middleware.py +4 -3
- mdb_engine/auth/oso_factory.py +6 -6
- mdb_engine/auth/provider.py +4 -4
- mdb_engine/auth/rate_limiter.py +12 -11
- mdb_engine/auth/restrictions.py +16 -15
- mdb_engine/auth/session_manager.py +11 -13
- mdb_engine/auth/shared_middleware.py +16 -15
- mdb_engine/auth/shared_users.py +20 -20
- mdb_engine/auth/token_lifecycle.py +10 -12
- mdb_engine/auth/token_store.py +4 -5
- mdb_engine/auth/users.py +51 -52
- mdb_engine/auth/utils.py +29 -33
- mdb_engine/cli/commands/generate.py +6 -6
- mdb_engine/cli/utils.py +4 -4
- mdb_engine/config.py +6 -7
- mdb_engine/core/app_registration.py +12 -12
- mdb_engine/core/app_secrets.py +1 -2
- mdb_engine/core/connection.py +3 -4
- mdb_engine/core/encryption.py +1 -2
- mdb_engine/core/engine.py +43 -44
- mdb_engine/core/manifest.py +59 -58
- mdb_engine/core/ray_integration.py +10 -9
- mdb_engine/core/seeding.py +3 -3
- mdb_engine/core/service_initialization.py +10 -9
- mdb_engine/core/types.py +40 -40
- mdb_engine/database/abstraction.py +15 -16
- mdb_engine/database/connection.py +40 -12
- mdb_engine/database/query_validator.py +8 -8
- mdb_engine/database/resource_limiter.py +7 -7
- mdb_engine/database/scoped_wrapper.py +51 -58
- mdb_engine/dependencies.py +14 -13
- mdb_engine/di/container.py +12 -13
- mdb_engine/di/providers.py +14 -13
- mdb_engine/di/scopes.py +5 -5
- mdb_engine/embeddings/dependencies.py +2 -2
- mdb_engine/embeddings/service.py +31 -43
- mdb_engine/exceptions.py +20 -20
- mdb_engine/indexes/helpers.py +11 -11
- mdb_engine/indexes/manager.py +9 -9
- mdb_engine/memory/service.py +30 -30
- mdb_engine/observability/health.py +10 -9
- mdb_engine/observability/logging.py +10 -10
- mdb_engine/observability/metrics.py +8 -7
- mdb_engine/repositories/base.py +25 -25
- mdb_engine/repositories/mongo.py +17 -17
- mdb_engine/repositories/unit_of_work.py +6 -6
- mdb_engine/routing/websockets.py +19 -18
- {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.3.dist-info}/METADATA +8 -8
- mdb_engine-0.2.3.dist-info/RECORD +96 -0
- mdb_engine-0.2.1.dist-info/RECORD +0 -96
- {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.3.dist-info}/WHEEL +0 -0
- {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.3.dist-info}/entry_points.txt +0 -0
- {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.3.dist-info}/licenses/LICENSE +0 -0
- {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.3.dist-info}/top_level.txt +0 -0
mdb_engine/core/manifest.py
CHANGED
|
@@ -32,7 +32,8 @@ For Scale:
|
|
|
32
32
|
import asyncio
|
|
33
33
|
import hashlib
|
|
34
34
|
import logging
|
|
35
|
-
from
|
|
35
|
+
from collections.abc import Awaitable, Callable
|
|
36
|
+
from typing import Any
|
|
36
37
|
|
|
37
38
|
from jsonschema import SchemaError, ValidationError, validate
|
|
38
39
|
|
|
@@ -48,10 +49,10 @@ from ..constants import (
|
|
|
48
49
|
logger = logging.getLogger(__name__)
|
|
49
50
|
|
|
50
51
|
# Schema registry: maps version -> schema definition
|
|
51
|
-
SCHEMA_REGISTRY:
|
|
52
|
+
SCHEMA_REGISTRY: dict[str, dict[str, Any]] = {}
|
|
52
53
|
|
|
53
54
|
# Validation cache: maps (manifest_hash, version) -> validation_result
|
|
54
|
-
_validation_cache:
|
|
55
|
+
_validation_cache: dict[str, tuple[bool, str | None, list[str] | None]] = {}
|
|
55
56
|
_cache_lock = asyncio.Lock()
|
|
56
57
|
|
|
57
58
|
|
|
@@ -86,7 +87,7 @@ def _convert_tuples_to_lists(obj: Any) -> Any:
|
|
|
86
87
|
return obj
|
|
87
88
|
|
|
88
89
|
|
|
89
|
-
def _get_manifest_hash(manifest_data:
|
|
90
|
+
def _get_manifest_hash(manifest_data: dict[str, Any]) -> str:
|
|
90
91
|
"""Generate a hash for manifest caching."""
|
|
91
92
|
import json
|
|
92
93
|
|
|
@@ -2083,7 +2084,7 @@ SCHEMA_REGISTRY["default"] = MANIFEST_SCHEMA_V2
|
|
|
2083
2084
|
MANIFEST_SCHEMA = MANIFEST_SCHEMA_V2 # Backward compatibility
|
|
2084
2085
|
|
|
2085
2086
|
|
|
2086
|
-
def get_schema_version(manifest_data:
|
|
2087
|
+
def get_schema_version(manifest_data: dict[str, Any]) -> str:
|
|
2087
2088
|
"""
|
|
2088
2089
|
Detect schema version from manifest.
|
|
2089
2090
|
|
|
@@ -2096,7 +2097,7 @@ def get_schema_version(manifest_data: Dict[str, Any]) -> str:
|
|
|
2096
2097
|
Raises:
|
|
2097
2098
|
ValueError: If schema version format is invalid
|
|
2098
2099
|
"""
|
|
2099
|
-
version:
|
|
2100
|
+
version: str | None = manifest_data.get("schema_version")
|
|
2100
2101
|
if version:
|
|
2101
2102
|
# Validate version format
|
|
2102
2103
|
if not isinstance(version, str) or not version.replace(".", "").isdigit():
|
|
@@ -2118,8 +2119,8 @@ def get_schema_version(manifest_data: Dict[str, Any]) -> str:
|
|
|
2118
2119
|
|
|
2119
2120
|
|
|
2120
2121
|
def migrate_manifest(
|
|
2121
|
-
manifest_data:
|
|
2122
|
-
) ->
|
|
2122
|
+
manifest_data: dict[str, Any], target_version: str = CURRENT_SCHEMA_VERSION
|
|
2123
|
+
) -> dict[str, Any]:
|
|
2123
2124
|
"""
|
|
2124
2125
|
Migrate manifest from one schema version to another.
|
|
2125
2126
|
|
|
@@ -2168,7 +2169,7 @@ def migrate_manifest(
|
|
|
2168
2169
|
return migrated
|
|
2169
2170
|
|
|
2170
2171
|
|
|
2171
|
-
def get_schema_for_version(version: str) ->
|
|
2172
|
+
def get_schema_for_version(version: str) -> dict[str, Any]:
|
|
2172
2173
|
"""
|
|
2173
2174
|
Get schema definition for a specific version.
|
|
2174
2175
|
|
|
@@ -2201,8 +2202,8 @@ def get_schema_for_version(version: str) -> Dict[str, Any]:
|
|
|
2201
2202
|
|
|
2202
2203
|
|
|
2203
2204
|
async def _validate_manifest_async(
|
|
2204
|
-
manifest_data:
|
|
2205
|
-
) ->
|
|
2205
|
+
manifest_data: dict[str, Any], use_cache: bool = True
|
|
2206
|
+
) -> tuple[bool, str | None, list[str] | None]:
|
|
2206
2207
|
"""
|
|
2207
2208
|
Validate a manifest against the JSON Schema with versioning and caching support.
|
|
2208
2209
|
|
|
@@ -2329,8 +2330,8 @@ def clear_validation_cache():
|
|
|
2329
2330
|
|
|
2330
2331
|
|
|
2331
2332
|
async def validate_manifests_parallel(
|
|
2332
|
-
manifests:
|
|
2333
|
-
) ->
|
|
2333
|
+
manifests: list[dict[str, Any]], use_cache: bool = True
|
|
2334
|
+
) -> list[tuple[bool, str | None, list[str] | None, str | None]]:
|
|
2334
2335
|
"""
|
|
2335
2336
|
Validate multiple manifests in parallel for scale.
|
|
2336
2337
|
|
|
@@ -2344,8 +2345,8 @@ async def validate_manifests_parallel(
|
|
|
2344
2345
|
"""
|
|
2345
2346
|
|
|
2346
2347
|
async def validate_one(
|
|
2347
|
-
manifest:
|
|
2348
|
-
) ->
|
|
2348
|
+
manifest: dict[str, Any],
|
|
2349
|
+
) -> tuple[bool, str | None, list[str] | None, str | None]:
|
|
2349
2350
|
slug = manifest.get("slug", "unknown")
|
|
2350
2351
|
is_valid, error, paths = await _validate_manifest_async(manifest, use_cache=use_cache)
|
|
2351
2352
|
return (is_valid, error, paths, slug)
|
|
@@ -2366,8 +2367,8 @@ async def validate_manifests_parallel(
|
|
|
2366
2367
|
|
|
2367
2368
|
|
|
2368
2369
|
async def validate_developer_id(
|
|
2369
|
-
developer_id: str, db_validator:
|
|
2370
|
-
) ->
|
|
2370
|
+
developer_id: str, db_validator: Callable[[str], Awaitable[bool]] | None = None
|
|
2371
|
+
) -> tuple[bool, str | None]:
|
|
2371
2372
|
"""
|
|
2372
2373
|
Validate that a developer_id exists in the system and has developer role.
|
|
2373
2374
|
|
|
@@ -2411,10 +2412,10 @@ async def validate_developer_id(
|
|
|
2411
2412
|
|
|
2412
2413
|
|
|
2413
2414
|
async def validate_manifest_with_db(
|
|
2414
|
-
manifest_data:
|
|
2415
|
+
manifest_data: dict[str, Any],
|
|
2415
2416
|
db_validator: Callable[[str], Awaitable[bool]],
|
|
2416
2417
|
use_cache: bool = True,
|
|
2417
|
-
) ->
|
|
2418
|
+
) -> tuple[bool, str | None, list[str] | None]:
|
|
2418
2419
|
"""
|
|
2419
2420
|
Validate a manifest against the JSON Schema (with versioning) and check
|
|
2420
2421
|
developer_id exists in system.
|
|
@@ -2455,8 +2456,8 @@ async def validate_manifest_with_db(
|
|
|
2455
2456
|
# Public API: Synchronous wrapper for backward compatibility
|
|
2456
2457
|
# Most callers use this synchronously, so we provide a sync wrapper
|
|
2457
2458
|
def validate_manifest(
|
|
2458
|
-
manifest_data:
|
|
2459
|
-
) ->
|
|
2459
|
+
manifest_data: dict[str, Any], use_cache: bool = True
|
|
2460
|
+
) -> tuple[bool, str | None, list[str] | None]:
|
|
2460
2461
|
"""
|
|
2461
2462
|
Validate a manifest against the JSON Schema with versioning and caching
|
|
2462
2463
|
support (synchronous wrapper).
|
|
@@ -2495,8 +2496,8 @@ def validate_manifest(
|
|
|
2495
2496
|
|
|
2496
2497
|
|
|
2497
2498
|
def _validate_regular_index(
|
|
2498
|
-
index_def:
|
|
2499
|
-
) ->
|
|
2499
|
+
index_def: dict[str, Any], collection_name: str, index_name: str
|
|
2500
|
+
) -> tuple[bool, str | None]:
|
|
2500
2501
|
"""Validate a regular index definition."""
|
|
2501
2502
|
if "keys" not in index_def:
|
|
2502
2503
|
return (
|
|
@@ -2533,8 +2534,8 @@ def _validate_regular_index(
|
|
|
2533
2534
|
|
|
2534
2535
|
|
|
2535
2536
|
def _validate_ttl_index(
|
|
2536
|
-
index_def:
|
|
2537
|
-
) ->
|
|
2537
|
+
index_def: dict[str, Any], collection_name: str, index_name: str
|
|
2538
|
+
) -> tuple[bool, str | None]:
|
|
2538
2539
|
"""Validate a TTL index definition."""
|
|
2539
2540
|
if "keys" not in index_def:
|
|
2540
2541
|
return (
|
|
@@ -2567,8 +2568,8 @@ def _validate_ttl_index(
|
|
|
2567
2568
|
|
|
2568
2569
|
|
|
2569
2570
|
def _validate_partial_index(
|
|
2570
|
-
index_def:
|
|
2571
|
-
) ->
|
|
2571
|
+
index_def: dict[str, Any], collection_name: str, index_name: str
|
|
2572
|
+
) -> tuple[bool, str | None]:
|
|
2572
2573
|
"""Validate a partial index definition."""
|
|
2573
2574
|
if "keys" not in index_def:
|
|
2574
2575
|
return (
|
|
@@ -2588,8 +2589,8 @@ def _validate_partial_index(
|
|
|
2588
2589
|
|
|
2589
2590
|
|
|
2590
2591
|
def _validate_text_index(
|
|
2591
|
-
index_def:
|
|
2592
|
-
) ->
|
|
2592
|
+
index_def: dict[str, Any], collection_name: str, index_name: str
|
|
2593
|
+
) -> tuple[bool, str | None]:
|
|
2593
2594
|
"""Validate a text index definition."""
|
|
2594
2595
|
if "keys" not in index_def:
|
|
2595
2596
|
return (
|
|
@@ -2614,8 +2615,8 @@ def _validate_text_index(
|
|
|
2614
2615
|
|
|
2615
2616
|
|
|
2616
2617
|
def _validate_geospatial_index(
|
|
2617
|
-
index_def:
|
|
2618
|
-
) ->
|
|
2618
|
+
index_def: dict[str, Any], collection_name: str, index_name: str
|
|
2619
|
+
) -> tuple[bool, str | None]:
|
|
2619
2620
|
"""Validate a geospatial index definition."""
|
|
2620
2621
|
if "keys" not in index_def:
|
|
2621
2622
|
return (
|
|
@@ -2641,8 +2642,8 @@ def _validate_geospatial_index(
|
|
|
2641
2642
|
|
|
2642
2643
|
|
|
2643
2644
|
def _validate_vector_search_index(
|
|
2644
|
-
index_def:
|
|
2645
|
-
) ->
|
|
2645
|
+
index_def: dict[str, Any], collection_name: str, index_name: str, index_type: str
|
|
2646
|
+
) -> tuple[bool, str | None]:
|
|
2646
2647
|
"""Validate a vectorSearch or search index definition."""
|
|
2647
2648
|
if "definition" not in index_def:
|
|
2648
2649
|
return (
|
|
@@ -2689,8 +2690,8 @@ def _validate_vector_search_index(
|
|
|
2689
2690
|
|
|
2690
2691
|
|
|
2691
2692
|
def _validate_hybrid_index(
|
|
2692
|
-
index_def:
|
|
2693
|
-
) ->
|
|
2693
|
+
index_def: dict[str, Any], collection_name: str, index_name: str
|
|
2694
|
+
) -> tuple[bool, str | None]:
|
|
2694
2695
|
"""Validate a hybrid index definition."""
|
|
2695
2696
|
if "hybrid" not in index_def:
|
|
2696
2697
|
return (
|
|
@@ -2753,8 +2754,8 @@ def _validate_hybrid_index(
|
|
|
2753
2754
|
|
|
2754
2755
|
|
|
2755
2756
|
def validate_index_definition(
|
|
2756
|
-
index_def:
|
|
2757
|
-
) ->
|
|
2757
|
+
index_def: dict[str, Any], collection_name: str, index_name: str
|
|
2758
|
+
) -> tuple[bool, str | None]:
|
|
2758
2759
|
"""
|
|
2759
2760
|
Validate a single index definition with context-specific checks.
|
|
2760
2761
|
|
|
@@ -2797,8 +2798,8 @@ def validate_index_definition(
|
|
|
2797
2798
|
|
|
2798
2799
|
|
|
2799
2800
|
def validate_managed_indexes(
|
|
2800
|
-
managed_indexes:
|
|
2801
|
-
) ->
|
|
2801
|
+
managed_indexes: dict[str, list[dict[str, Any]]],
|
|
2802
|
+
) -> tuple[bool, str | None]:
|
|
2802
2803
|
"""
|
|
2803
2804
|
Validate all managed indexes with collection and index context.
|
|
2804
2805
|
|
|
@@ -2866,8 +2867,8 @@ class ManifestValidator:
|
|
|
2866
2867
|
|
|
2867
2868
|
@staticmethod
|
|
2868
2869
|
def validate(
|
|
2869
|
-
manifest:
|
|
2870
|
-
) ->
|
|
2870
|
+
manifest: dict[str, Any], use_cache: bool = True
|
|
2871
|
+
) -> tuple[bool, str | None, list[str] | None]:
|
|
2871
2872
|
"""
|
|
2872
2873
|
Validate manifest against schema.
|
|
2873
2874
|
|
|
@@ -2882,8 +2883,8 @@ class ManifestValidator:
|
|
|
2882
2883
|
|
|
2883
2884
|
@staticmethod
|
|
2884
2885
|
async def validate_async(
|
|
2885
|
-
manifest:
|
|
2886
|
-
) ->
|
|
2886
|
+
manifest: dict[str, Any], use_cache: bool = True
|
|
2887
|
+
) -> tuple[bool, str | None, list[str] | None]:
|
|
2887
2888
|
"""
|
|
2888
2889
|
Validate manifest asynchronously.
|
|
2889
2890
|
|
|
@@ -2902,10 +2903,10 @@ class ManifestValidator:
|
|
|
2902
2903
|
|
|
2903
2904
|
@staticmethod
|
|
2904
2905
|
async def validate_with_db(
|
|
2905
|
-
manifest:
|
|
2906
|
+
manifest: dict[str, Any],
|
|
2906
2907
|
db_validator: Callable[[str], Awaitable[bool]],
|
|
2907
2908
|
use_cache: bool = True,
|
|
2908
|
-
) ->
|
|
2909
|
+
) -> tuple[bool, str | None, list[str] | None]:
|
|
2909
2910
|
"""
|
|
2910
2911
|
Validate manifest and check developer_id exists in database.
|
|
2911
2912
|
|
|
@@ -2921,8 +2922,8 @@ class ManifestValidator:
|
|
|
2921
2922
|
|
|
2922
2923
|
@staticmethod
|
|
2923
2924
|
def validate_managed_indexes(
|
|
2924
|
-
managed_indexes:
|
|
2925
|
-
) ->
|
|
2925
|
+
managed_indexes: dict[str, list[dict[str, Any]]],
|
|
2926
|
+
) -> tuple[bool, str | None]:
|
|
2926
2927
|
"""
|
|
2927
2928
|
Validate managed indexes configuration.
|
|
2928
2929
|
|
|
@@ -2936,8 +2937,8 @@ class ManifestValidator:
|
|
|
2936
2937
|
|
|
2937
2938
|
@staticmethod
|
|
2938
2939
|
def validate_index_definition(
|
|
2939
|
-
index_def:
|
|
2940
|
-
) ->
|
|
2940
|
+
index_def: dict[str, Any], collection_name: str, index_name: str
|
|
2941
|
+
) -> tuple[bool, str | None]:
|
|
2941
2942
|
"""
|
|
2942
2943
|
Validate a single index definition.
|
|
2943
2944
|
|
|
@@ -2952,7 +2953,7 @@ class ManifestValidator:
|
|
|
2952
2953
|
return validate_index_definition(index_def, collection_name, index_name)
|
|
2953
2954
|
|
|
2954
2955
|
@staticmethod
|
|
2955
|
-
def get_schema_version(manifest:
|
|
2956
|
+
def get_schema_version(manifest: dict[str, Any]) -> str:
|
|
2956
2957
|
"""
|
|
2957
2958
|
Get schema version from manifest.
|
|
2958
2959
|
|
|
@@ -2966,8 +2967,8 @@ class ManifestValidator:
|
|
|
2966
2967
|
|
|
2967
2968
|
@staticmethod
|
|
2968
2969
|
def migrate(
|
|
2969
|
-
manifest:
|
|
2970
|
-
) ->
|
|
2970
|
+
manifest: dict[str, Any], target_version: str = CURRENT_SCHEMA_VERSION
|
|
2971
|
+
) -> dict[str, Any]:
|
|
2971
2972
|
"""
|
|
2972
2973
|
Migrate manifest to target schema version.
|
|
2973
2974
|
|
|
@@ -2994,7 +2995,7 @@ class ManifestParser:
|
|
|
2994
2995
|
with automatic validation and migration.
|
|
2995
2996
|
"""
|
|
2996
2997
|
|
|
2997
|
-
def __init__(self, validator:
|
|
2998
|
+
def __init__(self, validator: ManifestValidator | None = None):
|
|
2998
2999
|
"""
|
|
2999
3000
|
Initialize parser.
|
|
3000
3001
|
|
|
@@ -3004,7 +3005,7 @@ class ManifestParser:
|
|
|
3004
3005
|
self.validator = validator or ManifestValidator()
|
|
3005
3006
|
|
|
3006
3007
|
@staticmethod
|
|
3007
|
-
async def load_from_file(path: Any, validate: bool = True) ->
|
|
3008
|
+
async def load_from_file(path: Any, validate: bool = True) -> dict[str, Any]:
|
|
3008
3009
|
"""
|
|
3009
3010
|
Load and validate manifest from file.
|
|
3010
3011
|
|
|
@@ -3041,7 +3042,7 @@ class ManifestParser:
|
|
|
3041
3042
|
return manifest_data
|
|
3042
3043
|
|
|
3043
3044
|
@staticmethod
|
|
3044
|
-
async def load_from_dict(data:
|
|
3045
|
+
async def load_from_dict(data: dict[str, Any], validate: bool = True) -> dict[str, Any]:
|
|
3045
3046
|
"""
|
|
3046
3047
|
Load and validate manifest from dictionary.
|
|
3047
3048
|
|
|
@@ -3065,7 +3066,7 @@ class ManifestParser:
|
|
|
3065
3066
|
return data.copy()
|
|
3066
3067
|
|
|
3067
3068
|
@staticmethod
|
|
3068
|
-
async def load_from_string(content: str, validate: bool = True) ->
|
|
3069
|
+
async def load_from_string(content: str, validate: bool = True) -> dict[str, Any]:
|
|
3069
3070
|
"""
|
|
3070
3071
|
Load and validate manifest from JSON string.
|
|
3071
3072
|
|
|
@@ -3087,8 +3088,8 @@ class ManifestParser:
|
|
|
3087
3088
|
|
|
3088
3089
|
@staticmethod
|
|
3089
3090
|
async def load_and_migrate(
|
|
3090
|
-
manifest:
|
|
3091
|
-
) ->
|
|
3091
|
+
manifest: dict[str, Any], target_version: str = CURRENT_SCHEMA_VERSION
|
|
3092
|
+
) -> dict[str, Any]:
|
|
3092
3093
|
"""
|
|
3093
3094
|
Load manifest and migrate to target version.
|
|
3094
3095
|
|
|
@@ -25,7 +25,8 @@ This module is part of MDB_ENGINE - MongoDB Engine.
|
|
|
25
25
|
|
|
26
26
|
import logging
|
|
27
27
|
import os
|
|
28
|
-
from
|
|
28
|
+
from collections.abc import Callable
|
|
29
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
29
30
|
|
|
30
31
|
if TYPE_CHECKING:
|
|
31
32
|
pass
|
|
@@ -132,7 +133,7 @@ class AppRayActor:
|
|
|
132
133
|
else:
|
|
133
134
|
raise
|
|
134
135
|
|
|
135
|
-
async def get_app_db(self, app_token:
|
|
136
|
+
async def get_app_db(self, app_token: str | None = None) -> Any:
|
|
136
137
|
"""
|
|
137
138
|
Get scoped database for this app.
|
|
138
139
|
|
|
@@ -191,11 +192,11 @@ class AppRayActor:
|
|
|
191
192
|
async def get_ray_actor_handle(
|
|
192
193
|
app_slug: str,
|
|
193
194
|
namespace: str = "modular_labs",
|
|
194
|
-
mongo_uri:
|
|
195
|
-
db_name:
|
|
195
|
+
mongo_uri: str | None = None,
|
|
196
|
+
db_name: str | None = None,
|
|
196
197
|
create_if_missing: bool = True,
|
|
197
|
-
actor_class:
|
|
198
|
-
) ->
|
|
198
|
+
actor_class: type | None = None,
|
|
199
|
+
) -> Any | None:
|
|
199
200
|
"""
|
|
200
201
|
Get or create a Ray actor handle for an app.
|
|
201
202
|
|
|
@@ -294,7 +295,7 @@ async def get_ray_actor_handle(
|
|
|
294
295
|
|
|
295
296
|
|
|
296
297
|
def ray_actor_decorator(
|
|
297
|
-
app_slug:
|
|
298
|
+
app_slug: str | None = None,
|
|
298
299
|
namespace: str = "modular_labs",
|
|
299
300
|
isolated: bool = True,
|
|
300
301
|
lifetime: str = "detached",
|
|
@@ -369,8 +370,8 @@ def ray_actor_decorator(
|
|
|
369
370
|
def spawn(
|
|
370
371
|
cls,
|
|
371
372
|
*args,
|
|
372
|
-
mongo_uri:
|
|
373
|
-
db_name:
|
|
373
|
+
mongo_uri: str | None = None,
|
|
374
|
+
db_name: str | None = None,
|
|
374
375
|
**kwargs,
|
|
375
376
|
):
|
|
376
377
|
"""
|
mdb_engine/core/seeding.py
CHANGED
|
@@ -8,7 +8,7 @@ This module is part of MDB_ENGINE - MongoDB Engine.
|
|
|
8
8
|
|
|
9
9
|
import logging
|
|
10
10
|
from datetime import datetime
|
|
11
|
-
from typing import Any
|
|
11
|
+
from typing import Any
|
|
12
12
|
|
|
13
13
|
from pymongo.errors import (
|
|
14
14
|
ConnectionFailure,
|
|
@@ -20,8 +20,8 @@ logger = logging.getLogger(__name__)
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
async def seed_initial_data(
|
|
23
|
-
db, app_slug: str, initial_data:
|
|
24
|
-
) ->
|
|
23
|
+
db, app_slug: str, initial_data: dict[str, list[dict[str, Any]]]
|
|
24
|
+
) -> dict[str, int]:
|
|
25
25
|
"""
|
|
26
26
|
Seed initial data into collections.
|
|
27
27
|
|
|
@@ -11,7 +11,8 @@ This module is part of MDB_ENGINE - MongoDB Engine.
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
import logging
|
|
14
|
-
from
|
|
14
|
+
from collections.abc import Callable
|
|
15
|
+
from typing import Any
|
|
15
16
|
|
|
16
17
|
from pymongo.errors import (
|
|
17
18
|
ConnectionFailure,
|
|
@@ -50,10 +51,10 @@ class ServiceInitializer:
|
|
|
50
51
|
self.mongo_uri = mongo_uri
|
|
51
52
|
self.db_name = db_name
|
|
52
53
|
self.get_scoped_db_fn = get_scoped_db_fn
|
|
53
|
-
self._memory_services:
|
|
54
|
-
self._websocket_configs:
|
|
54
|
+
self._memory_services: dict[str, Any] = {}
|
|
55
|
+
self._websocket_configs: dict[str, dict[str, Any]] = {}
|
|
55
56
|
|
|
56
|
-
async def initialize_memory_service(self, slug: str, memory_config:
|
|
57
|
+
async def initialize_memory_service(self, slug: str, memory_config: dict[str, Any]) -> None:
|
|
57
58
|
"""
|
|
58
59
|
Initialize Mem0 memory service for an app.
|
|
59
60
|
|
|
@@ -151,7 +152,7 @@ class ServiceInitializer:
|
|
|
151
152
|
exc_info=True,
|
|
152
153
|
)
|
|
153
154
|
|
|
154
|
-
async def register_websockets(self, slug: str, websockets_config:
|
|
155
|
+
async def register_websockets(self, slug: str, websockets_config: dict[str, Any]) -> None:
|
|
155
156
|
"""
|
|
156
157
|
Register WebSocket endpoints for an app.
|
|
157
158
|
|
|
@@ -195,7 +196,7 @@ class ServiceInitializer:
|
|
|
195
196
|
)
|
|
196
197
|
|
|
197
198
|
async def seed_initial_data(
|
|
198
|
-
self, slug: str, initial_data:
|
|
199
|
+
self, slug: str, initial_data: dict[str, list[dict[str, Any]]]
|
|
199
200
|
) -> None:
|
|
200
201
|
"""
|
|
201
202
|
Seed initial data into collections for an app.
|
|
@@ -240,7 +241,7 @@ class ServiceInitializer:
|
|
|
240
241
|
)
|
|
241
242
|
|
|
242
243
|
async def setup_observability(
|
|
243
|
-
self, slug: str, manifest:
|
|
244
|
+
self, slug: str, manifest: dict[str, Any], observability_config: dict[str, Any]
|
|
244
245
|
) -> None:
|
|
245
246
|
"""
|
|
246
247
|
Set up observability features (health checks, metrics, logging) from manifest.
|
|
@@ -296,7 +297,7 @@ class ServiceInitializer:
|
|
|
296
297
|
f"Could not set up observability for {slug}: {e}", exc_info=True
|
|
297
298
|
)
|
|
298
299
|
|
|
299
|
-
def get_websocket_config(self, slug: str) ->
|
|
300
|
+
def get_websocket_config(self, slug: str) -> dict[str, Any] | None:
|
|
300
301
|
"""
|
|
301
302
|
Get WebSocket configuration for an app.
|
|
302
303
|
|
|
@@ -308,7 +309,7 @@ class ServiceInitializer:
|
|
|
308
309
|
"""
|
|
309
310
|
return self._websocket_configs.get(slug)
|
|
310
311
|
|
|
311
|
-
def get_memory_service(self, slug: str) ->
|
|
312
|
+
def get_memory_service(self, slug: str) -> Any | None:
|
|
312
313
|
"""
|
|
313
314
|
Get Mem0 memory service for an app.
|
|
314
315
|
|
mdb_engine/core/types.py
CHANGED
|
@@ -8,7 +8,7 @@ throughout the codebase.
|
|
|
8
8
|
This module is part of MDB_ENGINE - MongoDB Engine.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
from typing import TYPE_CHECKING, Any,
|
|
11
|
+
from typing import TYPE_CHECKING, Any, Literal, TypedDict
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
14
|
from ..memory import Mem0MemoryService
|
|
@@ -41,20 +41,20 @@ class IndexDefinitionDict(TypedDict, total=False):
|
|
|
41
41
|
"partial",
|
|
42
42
|
"hybrid",
|
|
43
43
|
]
|
|
44
|
-
keys:
|
|
44
|
+
keys: dict[str, int | str] | list[list[str | int]]
|
|
45
45
|
unique: bool
|
|
46
46
|
sparse: bool
|
|
47
47
|
background: bool
|
|
48
48
|
expireAfterSeconds: int
|
|
49
|
-
partialFilterExpression:
|
|
50
|
-
weights:
|
|
49
|
+
partialFilterExpression: dict[str, Any]
|
|
50
|
+
weights: dict[str, int] # For text indexes
|
|
51
51
|
default_language: str # For text indexes
|
|
52
52
|
language_override: str # For text indexes
|
|
53
53
|
textIndexVersion: int # For text indexes
|
|
54
54
|
# Vector search specific
|
|
55
|
-
fields:
|
|
55
|
+
fields: list[dict[str, Any]] # For vectorSearch indexes
|
|
56
56
|
# Search index specific
|
|
57
|
-
mappings:
|
|
57
|
+
mappings: dict[str, Any] # For search indexes
|
|
58
58
|
# Geospatial specific
|
|
59
59
|
bucketSize: float # For geoHaystack
|
|
60
60
|
# TTL specific
|
|
@@ -79,12 +79,12 @@ class AuthAuthorizationDict(TypedDict, total=False):
|
|
|
79
79
|
model: str
|
|
80
80
|
policies_collection: str
|
|
81
81
|
link_users_roles: bool
|
|
82
|
-
default_roles:
|
|
82
|
+
default_roles: list[str]
|
|
83
83
|
# OSO-specific
|
|
84
|
-
api_key:
|
|
85
|
-
url:
|
|
86
|
-
initial_roles:
|
|
87
|
-
initial_policies:
|
|
84
|
+
api_key: str | None
|
|
85
|
+
url: str | None
|
|
86
|
+
initial_roles: list[dict[str, str]]
|
|
87
|
+
initial_policies: list[dict[str, str]]
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
class AuthPolicyDict(TypedDict, total=False):
|
|
@@ -93,12 +93,12 @@ class AuthPolicyDict(TypedDict, total=False):
|
|
|
93
93
|
required: bool
|
|
94
94
|
provider: Literal["casbin", "oso", "custom"]
|
|
95
95
|
authorization: AuthAuthorizationDict
|
|
96
|
-
allowed_roles:
|
|
97
|
-
allowed_users:
|
|
98
|
-
denied_users:
|
|
99
|
-
required_permissions:
|
|
96
|
+
allowed_roles: list[str]
|
|
97
|
+
allowed_users: list[str]
|
|
98
|
+
denied_users: list[str]
|
|
99
|
+
required_permissions: list[str]
|
|
100
100
|
custom_resource: str
|
|
101
|
-
custom_actions:
|
|
101
|
+
custom_actions: list[Literal["access", "read", "write", "admin"]]
|
|
102
102
|
allow_anonymous: bool
|
|
103
103
|
owner_can_access: bool
|
|
104
104
|
|
|
@@ -111,7 +111,7 @@ class DemoUserDict(TypedDict, total=False):
|
|
|
111
111
|
role: str
|
|
112
112
|
auto_create: bool
|
|
113
113
|
link_to_platform: bool
|
|
114
|
-
extra_data:
|
|
114
|
+
extra_data: dict[str, Any]
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
class UsersConfigDict(TypedDict, total=False):
|
|
@@ -126,7 +126,7 @@ class UsersConfigDict(TypedDict, total=False):
|
|
|
126
126
|
link_platform_users: bool
|
|
127
127
|
anonymous_user_prefix: str
|
|
128
128
|
user_id_field: str
|
|
129
|
-
demo_users:
|
|
129
|
+
demo_users: list[DemoUserDict]
|
|
130
130
|
auto_link_platform_demo: bool
|
|
131
131
|
demo_user_seed_strategy: Literal["auto", "manual", "disabled"]
|
|
132
132
|
enable_demo_user_access: bool
|
|
@@ -312,7 +312,7 @@ class MetricsConfigDict(TypedDict, total=False):
|
|
|
312
312
|
enabled: bool
|
|
313
313
|
collect_operation_metrics: bool
|
|
314
314
|
collect_performance_metrics: bool
|
|
315
|
-
custom_metrics:
|
|
315
|
+
custom_metrics: list[str]
|
|
316
316
|
|
|
317
317
|
|
|
318
318
|
class LoggingConfigDict(TypedDict, total=False):
|
|
@@ -341,11 +341,11 @@ class CORSConfigDict(TypedDict, total=False):
|
|
|
341
341
|
"""CORS configuration."""
|
|
342
342
|
|
|
343
343
|
enabled: bool
|
|
344
|
-
allow_origins:
|
|
344
|
+
allow_origins: list[str]
|
|
345
345
|
allow_credentials: bool
|
|
346
|
-
allow_methods:
|
|
347
|
-
allow_headers:
|
|
348
|
-
expose_headers:
|
|
346
|
+
allow_methods: list[Literal["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD", "*"]]
|
|
347
|
+
allow_headers: list[str]
|
|
348
|
+
expose_headers: list[str]
|
|
349
349
|
max_age: int
|
|
350
350
|
|
|
351
351
|
|
|
@@ -371,22 +371,22 @@ class ManifestDict(TypedDict, total=False):
|
|
|
371
371
|
schema_version: str
|
|
372
372
|
slug: str
|
|
373
373
|
name: str
|
|
374
|
-
description:
|
|
374
|
+
description: str | None
|
|
375
375
|
status: Literal["active", "draft", "archived", "inactive"]
|
|
376
376
|
auth_required: bool # Backward compatibility
|
|
377
|
-
auth:
|
|
378
|
-
token_management:
|
|
379
|
-
data_scope:
|
|
380
|
-
pip_deps:
|
|
381
|
-
managed_indexes:
|
|
382
|
-
collection_settings:
|
|
383
|
-
websockets:
|
|
384
|
-
embedding_config:
|
|
385
|
-
memory_config:
|
|
386
|
-
cors:
|
|
387
|
-
observability:
|
|
388
|
-
initial_data:
|
|
389
|
-
developer_id:
|
|
377
|
+
auth: AuthConfigDict | None
|
|
378
|
+
token_management: TokenManagementDict | None
|
|
379
|
+
data_scope: list[str]
|
|
380
|
+
pip_deps: list[str]
|
|
381
|
+
managed_indexes: ManagedIndexesDict | None
|
|
382
|
+
collection_settings: dict[str, dict[str, Any]] | None
|
|
383
|
+
websockets: WebSocketsDict | None
|
|
384
|
+
embedding_config: EmbeddingConfigDict | None
|
|
385
|
+
memory_config: MemoryConfigDict | None
|
|
386
|
+
cors: CORSConfigDict | None
|
|
387
|
+
observability: ObservabilityConfigDict | None
|
|
388
|
+
initial_data: InitialDataDict | None
|
|
389
|
+
developer_id: str | None
|
|
390
390
|
|
|
391
391
|
|
|
392
392
|
# ============================================================================
|
|
@@ -398,13 +398,13 @@ class HealthStatusDict(TypedDict, total=False):
|
|
|
398
398
|
"""Health status response."""
|
|
399
399
|
|
|
400
400
|
status: Literal["healthy", "degraded", "unhealthy"]
|
|
401
|
-
checks:
|
|
401
|
+
checks: dict[str, dict[str, Any]]
|
|
402
402
|
timestamp: str
|
|
403
403
|
|
|
404
404
|
|
|
405
405
|
class MetricsDict(TypedDict, total=False):
|
|
406
406
|
"""Metrics response."""
|
|
407
407
|
|
|
408
|
-
operations:
|
|
409
|
-
summary:
|
|
408
|
+
operations: dict[str, dict[str, Any]]
|
|
409
|
+
summary: dict[str, Any]
|
|
410
410
|
timestamp: str
|