mdb-engine 0.1.6__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/README.md +144 -0
- mdb_engine/__init__.py +37 -0
- mdb_engine/auth/README.md +631 -0
- mdb_engine/auth/__init__.py +128 -0
- mdb_engine/auth/casbin_factory.py +199 -0
- mdb_engine/auth/casbin_models.py +46 -0
- mdb_engine/auth/config_defaults.py +71 -0
- mdb_engine/auth/config_helpers.py +213 -0
- mdb_engine/auth/cookie_utils.py +158 -0
- mdb_engine/auth/decorators.py +350 -0
- mdb_engine/auth/dependencies.py +747 -0
- mdb_engine/auth/helpers.py +64 -0
- mdb_engine/auth/integration.py +578 -0
- mdb_engine/auth/jwt.py +225 -0
- mdb_engine/auth/middleware.py +241 -0
- mdb_engine/auth/oso_factory.py +323 -0
- mdb_engine/auth/provider.py +570 -0
- mdb_engine/auth/restrictions.py +271 -0
- mdb_engine/auth/session_manager.py +477 -0
- mdb_engine/auth/token_lifecycle.py +213 -0
- mdb_engine/auth/token_store.py +289 -0
- mdb_engine/auth/users.py +1516 -0
- mdb_engine/auth/utils.py +614 -0
- mdb_engine/cli/__init__.py +13 -0
- mdb_engine/cli/commands/__init__.py +7 -0
- mdb_engine/cli/commands/generate.py +105 -0
- mdb_engine/cli/commands/migrate.py +83 -0
- mdb_engine/cli/commands/show.py +70 -0
- mdb_engine/cli/commands/validate.py +63 -0
- mdb_engine/cli/main.py +41 -0
- mdb_engine/cli/utils.py +92 -0
- mdb_engine/config.py +217 -0
- mdb_engine/constants.py +160 -0
- mdb_engine/core/README.md +542 -0
- mdb_engine/core/__init__.py +42 -0
- mdb_engine/core/app_registration.py +392 -0
- mdb_engine/core/connection.py +243 -0
- mdb_engine/core/engine.py +749 -0
- mdb_engine/core/index_management.py +162 -0
- mdb_engine/core/manifest.py +2793 -0
- mdb_engine/core/seeding.py +179 -0
- mdb_engine/core/service_initialization.py +355 -0
- mdb_engine/core/types.py +413 -0
- mdb_engine/database/README.md +522 -0
- mdb_engine/database/__init__.py +31 -0
- mdb_engine/database/abstraction.py +635 -0
- mdb_engine/database/connection.py +387 -0
- mdb_engine/database/scoped_wrapper.py +1721 -0
- mdb_engine/embeddings/README.md +184 -0
- mdb_engine/embeddings/__init__.py +62 -0
- mdb_engine/embeddings/dependencies.py +193 -0
- mdb_engine/embeddings/service.py +759 -0
- mdb_engine/exceptions.py +167 -0
- mdb_engine/indexes/README.md +651 -0
- mdb_engine/indexes/__init__.py +21 -0
- mdb_engine/indexes/helpers.py +145 -0
- mdb_engine/indexes/manager.py +895 -0
- mdb_engine/memory/README.md +451 -0
- mdb_engine/memory/__init__.py +30 -0
- mdb_engine/memory/service.py +1285 -0
- mdb_engine/observability/README.md +515 -0
- mdb_engine/observability/__init__.py +42 -0
- mdb_engine/observability/health.py +296 -0
- mdb_engine/observability/logging.py +161 -0
- mdb_engine/observability/metrics.py +297 -0
- mdb_engine/routing/README.md +462 -0
- mdb_engine/routing/__init__.py +73 -0
- mdb_engine/routing/websockets.py +813 -0
- mdb_engine/utils/__init__.py +7 -0
- mdb_engine-0.1.6.dist-info/METADATA +213 -0
- mdb_engine-0.1.6.dist-info/RECORD +75 -0
- mdb_engine-0.1.6.dist-info/WHEEL +5 -0
- mdb_engine-0.1.6.dist-info/entry_points.txt +2 -0
- mdb_engine-0.1.6.dist-info/licenses/LICENSE +661 -0
- mdb_engine-0.1.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Index management for MongoDB Engine.
|
|
3
|
+
|
|
4
|
+
This module handles index creation and validation for apps.
|
|
5
|
+
|
|
6
|
+
This module is part of MDB_ENGINE - MongoDB Engine.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import logging
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
from motor.motor_asyncio import AsyncIOMotorDatabase
|
|
14
|
+
from pymongo.errors import (ConnectionFailure, InvalidOperation,
|
|
15
|
+
OperationFailure, ServerSelectionTimeoutError)
|
|
16
|
+
|
|
17
|
+
from ..indexes import run_index_creation_for_collection
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from .types import ManifestDict
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class IndexManager:
|
|
26
|
+
"""
|
|
27
|
+
Manages index creation for apps.
|
|
28
|
+
|
|
29
|
+
Handles index validation and creation from manifest definitions.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, mongo_db: AsyncIOMotorDatabase) -> None:
|
|
33
|
+
"""
|
|
34
|
+
Initialize the index manager.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
mongo_db: MongoDB database instance
|
|
38
|
+
"""
|
|
39
|
+
self._mongo_db = mongo_db
|
|
40
|
+
|
|
41
|
+
async def create_app_indexes(self, slug: str, manifest: "ManifestDict") -> None:
|
|
42
|
+
"""
|
|
43
|
+
Create managed indexes for an app.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
slug: App slug
|
|
47
|
+
manifest: App manifest
|
|
48
|
+
"""
|
|
49
|
+
# Import validate_managed_indexes from manifest module
|
|
50
|
+
from .manifest import validate_managed_indexes
|
|
51
|
+
|
|
52
|
+
managed_indexes = manifest.get("managed_indexes", {})
|
|
53
|
+
logger.info(
|
|
54
|
+
f"[{slug}] Creating app indexes. managed_indexes keys: "
|
|
55
|
+
f"{list(managed_indexes.keys()) if managed_indexes else 'None'}"
|
|
56
|
+
)
|
|
57
|
+
if not managed_indexes:
|
|
58
|
+
logger.warning(
|
|
59
|
+
f"[{slug}] No 'managed_indexes' found in manifest. "
|
|
60
|
+
f"Skipping index creation."
|
|
61
|
+
)
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
# Validate indexes
|
|
65
|
+
logger.info(
|
|
66
|
+
f"[{slug}] Validating {len(managed_indexes)} collection(s) "
|
|
67
|
+
f"with managed indexes..."
|
|
68
|
+
)
|
|
69
|
+
is_valid, error = validate_managed_indexes(managed_indexes)
|
|
70
|
+
logger.info(
|
|
71
|
+
f"[{slug}] Index validation result: is_valid={is_valid}, " f"error={error}"
|
|
72
|
+
)
|
|
73
|
+
if not is_valid:
|
|
74
|
+
logger.error(
|
|
75
|
+
f"[{slug}] ❌ Invalid 'managed_indexes' configuration: {error}. "
|
|
76
|
+
f"Skipping index creation."
|
|
77
|
+
)
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
# Create indexes for each collection
|
|
81
|
+
logger.info(
|
|
82
|
+
f"[{slug}] Processing {len(managed_indexes)} collection(s) "
|
|
83
|
+
f"with managed indexes"
|
|
84
|
+
)
|
|
85
|
+
for collection_base_name, indexes in managed_indexes.items():
|
|
86
|
+
logger.info(
|
|
87
|
+
f"[{slug}] Processing collection '{collection_base_name}' "
|
|
88
|
+
f"with {len(indexes)} index definition(s)"
|
|
89
|
+
)
|
|
90
|
+
if not collection_base_name or not isinstance(indexes, list):
|
|
91
|
+
logger.warning(
|
|
92
|
+
f"[{slug}] Invalid 'managed_indexes' for "
|
|
93
|
+
f"'{collection_base_name}': "
|
|
94
|
+
f"collection_base_name={collection_base_name}, "
|
|
95
|
+
f"indexes={indexes}"
|
|
96
|
+
)
|
|
97
|
+
continue
|
|
98
|
+
|
|
99
|
+
prefixed_collection_name = f"{slug}_{collection_base_name}"
|
|
100
|
+
prefixed_defs = []
|
|
101
|
+
logger.debug(
|
|
102
|
+
f"[{slug}] Prefixed collection name: '{prefixed_collection_name}'"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
for idx_def in indexes:
|
|
106
|
+
idx_n = idx_def.get("name")
|
|
107
|
+
idx_type = idx_def.get("type")
|
|
108
|
+
logger.debug(
|
|
109
|
+
f"[{slug}] Processing index def: name={idx_n}, "
|
|
110
|
+
f"type={idx_type}, def={idx_def}"
|
|
111
|
+
)
|
|
112
|
+
if not idx_n or not idx_type:
|
|
113
|
+
logger.warning(
|
|
114
|
+
f"[{slug}] Skipping malformed index def in "
|
|
115
|
+
f"'{collection_base_name}': "
|
|
116
|
+
f"name={idx_n}, type={idx_type}"
|
|
117
|
+
)
|
|
118
|
+
continue
|
|
119
|
+
|
|
120
|
+
idx_copy = idx_def.copy()
|
|
121
|
+
idx_copy["name"] = f"{slug}_{idx_n}"
|
|
122
|
+
prefixed_defs.append(idx_copy)
|
|
123
|
+
logger.debug(f"[{slug}] Added prefixed index: '{idx_copy['name']}'")
|
|
124
|
+
|
|
125
|
+
if not prefixed_defs:
|
|
126
|
+
logger.warning(
|
|
127
|
+
f"[{slug}] No valid index definitions for "
|
|
128
|
+
f"'{collection_base_name}'. Skipping."
|
|
129
|
+
)
|
|
130
|
+
continue
|
|
131
|
+
|
|
132
|
+
logger.info(
|
|
133
|
+
f"[{slug}] Creating {len(prefixed_defs)} index(es) for "
|
|
134
|
+
f"'{prefixed_collection_name}'..."
|
|
135
|
+
)
|
|
136
|
+
try:
|
|
137
|
+
await run_index_creation_for_collection(
|
|
138
|
+
db=self._mongo_db,
|
|
139
|
+
slug=slug,
|
|
140
|
+
collection_name=prefixed_collection_name,
|
|
141
|
+
index_definitions=prefixed_defs,
|
|
142
|
+
)
|
|
143
|
+
# Wait a bit after all indexes are created to ensure they're all ready
|
|
144
|
+
await asyncio.sleep(1.0) # Extra wait after all indexes are created
|
|
145
|
+
logger.info(
|
|
146
|
+
f"[{slug}] ✅ Completed index creation for "
|
|
147
|
+
f"'{prefixed_collection_name}'"
|
|
148
|
+
)
|
|
149
|
+
except (
|
|
150
|
+
OperationFailure,
|
|
151
|
+
ConnectionFailure,
|
|
152
|
+
ServerSelectionTimeoutError,
|
|
153
|
+
InvalidOperation,
|
|
154
|
+
ValueError,
|
|
155
|
+
TypeError,
|
|
156
|
+
) as e:
|
|
157
|
+
logger.error(
|
|
158
|
+
f"[{slug}] Error creating indexes for '{prefixed_collection_name}': {e}",
|
|
159
|
+
exc_info=True,
|
|
160
|
+
)
|
|
161
|
+
# Re-raise to surface errors in tests
|
|
162
|
+
raise
|