mdb-engine 0.1.7__py3-none-any.whl → 0.2.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.
@@ -0,0 +1,233 @@
1
+ """
2
+ MongoDB Repository Implementation
3
+
4
+ Implements the Repository interface using MongoDB through ScopedCollectionWrapper.
5
+ This provides automatic app scoping and security features.
6
+ """
7
+
8
+ import logging
9
+ from datetime import datetime
10
+ from typing import Any, Dict, Generic, List, Optional, Type, TypeVar
11
+
12
+ from bson import ObjectId
13
+
14
+ from .base import Entity, Repository
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ T = TypeVar("T", bound=Entity)
19
+
20
+
21
+ class MongoRepository(Repository[T], Generic[T]):
22
+ """
23
+ MongoDB implementation of the Repository interface.
24
+
25
+ Uses ScopedCollectionWrapper for automatic app_id scoping
26
+ and security features.
27
+
28
+ Example:
29
+ # Direct usage
30
+ users_collection = db.users # ScopedCollectionWrapper
31
+ user_repo = MongoRepository(users_collection, User)
32
+
33
+ # Find users
34
+ users = await user_repo.find({"role": "admin"})
35
+
36
+ # Add new user
37
+ user = User(email="john@example.com", name="John")
38
+ user_id = await user_repo.add(user)
39
+ """
40
+
41
+ def __init__(
42
+ self,
43
+ collection: Any, # ScopedCollectionWrapper - avoid import cycle
44
+ entity_class: Type[T],
45
+ ):
46
+ """
47
+ Initialize the MongoDB repository.
48
+
49
+ Args:
50
+ collection: ScopedCollectionWrapper for the collection
51
+ entity_class: Entity subclass for this repository
52
+ """
53
+ self._collection = collection
54
+ self._entity_class = entity_class
55
+
56
+ def _to_entity(self, doc: Optional[Dict[str, Any]]) -> Optional[T]:
57
+ """Convert a MongoDB document to an entity."""
58
+ if doc is None:
59
+ return None
60
+ return self._entity_class.from_dict(doc)
61
+
62
+ def _to_document(self, entity: T, include_id: bool = False) -> Dict[str, Any]:
63
+ """Convert an entity to a MongoDB document."""
64
+ doc = entity.to_dict()
65
+ if not include_id and "_id" in doc:
66
+ del doc["_id"]
67
+ return doc
68
+
69
+ async def get(self, id: str) -> Optional[T]:
70
+ """Get entity by ID."""
71
+ try:
72
+ object_id = ObjectId(id) if ObjectId.is_valid(id) else id
73
+ except (TypeError, ValueError):
74
+ return None
75
+
76
+ doc = await self._collection.find_one({"_id": object_id})
77
+ return self._to_entity(doc)
78
+
79
+ async def find(
80
+ self,
81
+ filter: Optional[Dict[str, Any]] = None,
82
+ skip: int = 0,
83
+ limit: int = 100,
84
+ sort: Optional[List[tuple]] = None,
85
+ ) -> List[T]:
86
+ """Find entities matching a filter."""
87
+ cursor = self._collection.find(filter or {})
88
+
89
+ if skip > 0:
90
+ cursor = cursor.skip(skip)
91
+ if limit > 0:
92
+ cursor = cursor.limit(limit)
93
+ if sort:
94
+ cursor = cursor.sort(sort)
95
+
96
+ docs = await cursor.to_list(length=limit)
97
+ return [self._to_entity(doc) for doc in docs]
98
+
99
+ async def find_one(self, filter: Dict[str, Any]) -> Optional[T]:
100
+ """Find a single entity matching a filter."""
101
+ doc = await self._collection.find_one(filter)
102
+ return self._to_entity(doc)
103
+
104
+ async def add(self, entity: T) -> str:
105
+ """Add a new entity and return its ID."""
106
+ entity.created_at = datetime.utcnow()
107
+ doc = self._to_document(entity)
108
+
109
+ result = await self._collection.insert_one(doc)
110
+ entity.id = str(result.inserted_id)
111
+
112
+ logger.debug(f"Added {self._entity_class.__name__} with id={entity.id}")
113
+ return entity.id
114
+
115
+ async def add_many(self, entities: List[T]) -> List[str]:
116
+ """Add multiple entities and return their IDs."""
117
+ now = datetime.utcnow()
118
+ docs = []
119
+
120
+ for entity in entities:
121
+ entity.created_at = now
122
+ docs.append(self._to_document(entity))
123
+
124
+ result = await self._collection.insert_many(docs)
125
+ ids = [str(id) for id in result.inserted_ids]
126
+
127
+ for entity, id in zip(entities, ids):
128
+ entity.id = id
129
+
130
+ logger.debug(f"Added {len(ids)} {self._entity_class.__name__} entities")
131
+ return ids
132
+
133
+ async def update(self, id: str, entity: T) -> bool:
134
+ """Update an entity by ID."""
135
+ try:
136
+ object_id = ObjectId(id) if ObjectId.is_valid(id) else id
137
+ except (TypeError, ValueError):
138
+ return False
139
+
140
+ entity.updated_at = datetime.utcnow()
141
+ doc = self._to_document(entity)
142
+
143
+ result = await self._collection.update_one({"_id": object_id}, {"$set": doc})
144
+
145
+ return result.modified_count > 0
146
+
147
+ async def update_fields(self, id: str, fields: Dict[str, Any]) -> bool:
148
+ """Update specific fields of an entity."""
149
+ try:
150
+ object_id = ObjectId(id) if ObjectId.is_valid(id) else id
151
+ except (TypeError, ValueError):
152
+ return False
153
+
154
+ fields["updated_at"] = datetime.utcnow()
155
+
156
+ result = await self._collection.update_one({"_id": object_id}, {"$set": fields})
157
+
158
+ return result.modified_count > 0
159
+
160
+ async def delete(self, id: str) -> bool:
161
+ """Delete an entity by ID."""
162
+ try:
163
+ object_id = ObjectId(id) if ObjectId.is_valid(id) else id
164
+ except (TypeError, ValueError):
165
+ return False
166
+
167
+ result = await self._collection.delete_one({"_id": object_id})
168
+ return result.deleted_count > 0
169
+
170
+ async def count(self, filter: Optional[Dict[str, Any]] = None) -> int:
171
+ """Count entities matching a filter."""
172
+ return await self._collection.count_documents(filter or {})
173
+
174
+ async def exists(self, id: str) -> bool:
175
+ """Check if an entity exists."""
176
+ try:
177
+ object_id = ObjectId(id) if ObjectId.is_valid(id) else id
178
+ except (TypeError, ValueError):
179
+ return False
180
+
181
+ doc = await self._collection.find_one({"_id": object_id}, projection={"_id": 1})
182
+ return doc is not None
183
+
184
+ # Additional MongoDB-specific methods
185
+
186
+ async def aggregate(self, pipeline: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
187
+ """
188
+ Run an aggregation pipeline.
189
+
190
+ Args:
191
+ pipeline: MongoDB aggregation pipeline
192
+
193
+ Returns:
194
+ List of result documents
195
+ """
196
+ cursor = self._collection.aggregate(pipeline)
197
+ return await cursor.to_list(length=None)
198
+
199
+ async def update_many(
200
+ self,
201
+ filter: Dict[str, Any],
202
+ update: Dict[str, Any],
203
+ ) -> int:
204
+ """
205
+ Update multiple documents matching a filter.
206
+
207
+ Args:
208
+ filter: MongoDB filter
209
+ update: Update operations
210
+
211
+ Returns:
212
+ Number of modified documents
213
+ """
214
+ if "$set" not in update:
215
+ update = {"$set": update}
216
+
217
+ update["$set"]["updated_at"] = datetime.utcnow()
218
+
219
+ result = await self._collection.update_many(filter, update)
220
+ return result.modified_count
221
+
222
+ async def delete_many(self, filter: Dict[str, Any]) -> int:
223
+ """
224
+ Delete multiple documents matching a filter.
225
+
226
+ Args:
227
+ filter: MongoDB filter
228
+
229
+ Returns:
230
+ Number of deleted documents
231
+ """
232
+ result = await self._collection.delete_many(filter)
233
+ return result.deleted_count
@@ -0,0 +1,166 @@
1
+ """
2
+ Unit of Work Pattern
3
+
4
+ Manages repository access and provides a clean interface for data operations.
5
+ The UnitOfWork acts as a factory for repositories and manages their lifecycle.
6
+ """
7
+
8
+ import logging
9
+ from typing import Any, Dict, Generic, Optional, Type, TypeVar
10
+
11
+ from .base import Entity, Repository
12
+ from .mongo import MongoRepository
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ T = TypeVar("T", bound=Entity)
17
+
18
+
19
+ class UnitOfWork:
20
+ """
21
+ Unit of Work for managing repository access.
22
+
23
+ Provides a clean interface for accessing repositories through
24
+ attribute access (e.g., uow.users, uow.orders).
25
+
26
+ The UnitOfWork is request-scoped - one instance per HTTP request.
27
+ Repositories are created lazily and cached for the duration of the request.
28
+
29
+ Usage:
30
+ # In a route handler
31
+ @app.get("/users/{user_id}")
32
+ async def get_user(user_id: str, ctx: RequestContext = Depends()):
33
+ # Access repository through UnitOfWork
34
+ user = await ctx.uow.users.get(user_id)
35
+ return user
36
+
37
+ # With explicit repository method
38
+ @app.get("/orders")
39
+ async def list_orders(ctx: RequestContext = Depends()):
40
+ repo = ctx.uow.repository("orders", Order)
41
+ return await repo.find({"status": "pending"})
42
+
43
+ Repository Naming Convention:
44
+ - Attribute access uses collection name: uow.users -> users collection
45
+ - The entity class defaults to Entity if not registered
46
+ - Register entity classes for type-safe repositories
47
+ """
48
+
49
+ def __init__(
50
+ self,
51
+ db: Any, # ScopedMongoWrapper - avoid import cycle
52
+ entity_registry: Optional[Dict[str, Type[Entity]]] = None,
53
+ ):
54
+ """
55
+ Initialize the Unit of Work.
56
+
57
+ Args:
58
+ db: ScopedMongoWrapper for database access
59
+ entity_registry: Optional mapping of collection names to entity classes
60
+ """
61
+ self._db = db
62
+ self._repositories: Dict[str, Repository] = {}
63
+ self._entity_registry: Dict[str, Type[Entity]] = entity_registry or {}
64
+
65
+ def register_entity(self, collection_name: str, entity_class: Type[Entity]) -> None:
66
+ """
67
+ Register an entity class for a collection.
68
+
69
+ This enables type-safe repository access.
70
+
71
+ Args:
72
+ collection_name: Name of the collection
73
+ entity_class: Entity subclass for this collection
74
+ """
75
+ self._entity_registry[collection_name] = entity_class
76
+
77
+ def repository(
78
+ self,
79
+ name: str,
80
+ entity_class: Optional[Type[T]] = None,
81
+ ) -> Repository[T]:
82
+ """
83
+ Get or create a repository for a collection.
84
+
85
+ Args:
86
+ name: Collection name
87
+ entity_class: Optional entity class override
88
+
89
+ Returns:
90
+ Repository instance for the collection
91
+ """
92
+ if name in self._repositories:
93
+ return self._repositories[name]
94
+
95
+ # Determine entity class
96
+ if entity_class is None:
97
+ entity_class = self._entity_registry.get(name, Entity)
98
+
99
+ # Get collection from db wrapper
100
+ collection = getattr(self._db, name)
101
+
102
+ # Create repository
103
+ repo = MongoRepository(collection, entity_class)
104
+ self._repositories[name] = repo
105
+
106
+ logger.debug(f"Created repository for '{name}' with entity {entity_class.__name__}")
107
+ return repo
108
+
109
+ def __getattr__(self, name: str) -> Repository:
110
+ """
111
+ Access repositories via attribute syntax.
112
+
113
+ Example:
114
+ uow.users # Returns Repository for 'users' collection
115
+ uow.orders # Returns Repository for 'orders' collection
116
+ """
117
+ # Prevent recursion on private attributes
118
+ if name.startswith("_"):
119
+ raise AttributeError(f"'{type(self).__name__}' has no attribute '{name}'")
120
+
121
+ return self.repository(name)
122
+
123
+ @property
124
+ def db(self) -> Any:
125
+ """
126
+ Direct access to the underlying ScopedMongoWrapper.
127
+
128
+ Use this for operations not covered by the Repository interface,
129
+ like complex aggregations or raw queries.
130
+
131
+ Example:
132
+ # Complex aggregation
133
+ pipeline = [{"$match": {...}}, {"$group": {...}}]
134
+ results = await ctx.uow.db.users.aggregate(pipeline).to_list(None)
135
+ """
136
+ return self._db
137
+
138
+ def dispose(self) -> None:
139
+ """
140
+ Dispose of the UnitOfWork and clear cached repositories.
141
+
142
+ Called automatically at the end of a request scope.
143
+ """
144
+ self._repositories.clear()
145
+ logger.debug("UnitOfWork disposed")
146
+
147
+
148
+ class TypedUnitOfWork(UnitOfWork, Generic[T]):
149
+ """
150
+ Generic typed UnitOfWork for better IDE support.
151
+
152
+ This is a convenience class that provides type hints for specific
153
+ repository types.
154
+
155
+ Usage:
156
+ class MyUnitOfWork(TypedUnitOfWork):
157
+ @property
158
+ def users(self) -> Repository[User]:
159
+ return self.repository("users", User)
160
+
161
+ @property
162
+ def orders(self) -> Repository[Order]:
163
+ return self.repository("orders", Order)
164
+ """
165
+
166
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mdb-engine
3
- Version: 0.1.7
3
+ Version: 0.2.0
4
4
  Summary: MongoDB Engine
5
5
  Home-page: https://github.com/ranfysvalle02/mdb-engine
6
6
  Author: Your Name
@@ -85,7 +85,9 @@ pip install mdb-engine
85
85
 
86
86
  ```python
87
87
  from pathlib import Path
88
+ from fastapi import Depends
88
89
  from mdb_engine import MongoDBEngine
90
+ from mdb_engine.dependencies import get_scoped_db
89
91
 
90
92
  # 1. Initialize the engine
91
93
  engine = MongoDBEngine(
@@ -96,10 +98,9 @@ engine = MongoDBEngine(
96
98
  # 2. Create a FastAPI app with automatic lifecycle management
97
99
  app = engine.create_app(slug="my_app", manifest=Path("manifest.json"))
98
100
 
99
- # 3. Use the scoped database - all queries automatically isolated
101
+ # 3. Use request-scoped dependencies - all queries automatically isolated
100
102
  @app.post("/tasks")
101
- async def create_task(task: dict):
102
- db = engine.get_scoped_db("my_app")
103
+ async def create_task(task: dict, db=Depends(get_scoped_db)):
103
104
  result = await db.tasks.insert_one(task)
104
105
  return {"id": str(result.inserted_id)}
105
106
  ```
@@ -149,22 +150,29 @@ Supported index types: `regular`, `text`, `vector`, `ttl`, `compound`.
149
150
 
150
151
  ### 2. CRUD Operations (Auto-Scoped)
151
152
 
152
- All database operations are automatically scoped to your app:
153
+ All database operations are automatically scoped to your app. Use `Depends(get_scoped_db)` in route handlers:
153
154
 
154
155
  ```python
155
- db = engine.get_scoped_db("my_app")
156
+ from mdb_engine.dependencies import get_scoped_db
156
157
 
157
- # Create
158
- await db.tasks.insert_one({"title": "Build feature", "status": "pending"})
158
+ @app.post("/tasks")
159
+ async def create_task(task: dict, db=Depends(get_scoped_db)):
160
+ result = await db.tasks.insert_one(task)
161
+ return {"id": str(result.inserted_id)}
159
162
 
160
- # Read
161
- tasks = await db.tasks.find({"status": "pending"}).to_list(length=10)
163
+ @app.get("/tasks")
164
+ async def list_tasks(db=Depends(get_scoped_db)):
165
+ return await db.tasks.find({"status": "pending"}).to_list(length=10)
162
166
 
163
- # Update
164
- await db.tasks.update_one({"_id": task_id}, {"$set": {"status": "done"}})
167
+ @app.put("/tasks/{task_id}")
168
+ async def update_task(task_id: str, db=Depends(get_scoped_db)):
169
+ await db.tasks.update_one({"_id": task_id}, {"$set": {"status": "done"}})
170
+ return {"updated": True}
165
171
 
166
- # Delete
167
- await db.tasks.delete_one({"_id": task_id})
172
+ @app.delete("/tasks/{task_id}")
173
+ async def delete_task(task_id: str, db=Depends(get_scoped_db)):
174
+ await db.tasks.delete_one({"_id": task_id})
175
+ return {"deleted": True}
168
176
  ```
169
177
 
170
178
  **What happens under the hood:**
@@ -210,6 +218,26 @@ async def health():
210
218
  | **Multi-App** | Secure cross-app data access | [Multi-App Example](https://github.com/ranfysvalle02/mdb-engine/tree/main/examples/advanced/multi_app) |
211
219
  | **SSO** | Shared auth across apps | [Shared Auth Example](https://github.com/ranfysvalle02/mdb-engine/tree/main/examples/advanced/multi_app_shared) |
212
220
 
221
+ ### AppContext — All Services in One Place ✨
222
+
223
+ ```python
224
+ from fastapi import Depends
225
+ from mdb_engine.dependencies import AppContext
226
+
227
+ @app.post("/ai-chat")
228
+ async def chat(query: str, ctx: AppContext = Depends()):
229
+ user = ctx.require_user() # 401 if not logged in
230
+ ctx.require_role("user") # 403 if missing role
231
+
232
+ # Everything available: ctx.db, ctx.embedding_service, ctx.memory, ctx.llm
233
+ if ctx.llm:
234
+ response = ctx.llm.chat.completions.create(
235
+ model=ctx.llm_model,
236
+ messages=[{"role": "user", "content": query}]
237
+ )
238
+ return {"response": response.choices[0].message.content}
239
+ ```
240
+
213
241
  ---
214
242
 
215
243
  ## Full Examples
@@ -1,25 +1,28 @@
1
1
  mdb_engine/README.md,sha256=T3EFGcPopY9LslYW3lxgG3hohWkAOmBNbYG0FDMUJiY,3502
2
- mdb_engine/__init__.py,sha256=d5UN7QnkySDKriO4epSGNS2bBbgl_Bw18qu6Sd4I7xs,1629
2
+ mdb_engine/__init__.py,sha256=FILWpL9ZgfAnRj38lGF9QSZNY_OBKz9gZtC8ki2SYvc,3008
3
3
  mdb_engine/config.py,sha256=EsB0PHrRCCt24db6Ly88s6PQ3sm1esSLMa2G4AHpt5k,7315
4
4
  mdb_engine/constants.py,sha256=eaotvW57TVOg7rRbLziGrVNoP7adgw_G9iVByHezc_A,7837
5
+ mdb_engine/dependencies.py,sha256=bkKwYz6CnucDNDcXdxTvRCqmQpsWbAXQFf5w-AcKMH8,14107
5
6
  mdb_engine/exceptions.py,sha256=N8WYOgh1fOH0yJeR9I3FTXqpACIL_EQX3zcfUgrFvPI,8521
6
- mdb_engine/auth/README.md,sha256=pOobYo31ENhGA3d_nTUXVK795w2wvvQ_ub10x9wK1pU,33838
7
- mdb_engine/auth/__init__.py,sha256=0Gc0uFDAcj_BMeACaD0oICAn8YwVcpTf20DJbTzDxr8,5656
7
+ mdb_engine/auth/ARCHITECTURE.md,sha256=JXZsjEIpNz4Szk18KaOiEabhEuz1pmYWXQRN-EJEHDM,4076
8
+ mdb_engine/auth/README.md,sha256=STL4PHyMlYpSNEAqo4RBKTEm4kz1GbWpI9c_lS94nV4,36802
9
+ mdb_engine/auth/__init__.py,sha256=QemWqAVvqlxjF-UbzMTGP5AUOeuaAsUEtK4PMxmozmA,5852
8
10
  mdb_engine/auth/audit.py,sha256=LtdG9GdwYTSMI30zMygB0K8w4l179GaGvkNbxWgoQ2I,17461
9
- mdb_engine/auth/casbin_factory.py,sha256=CjGU7cj_I2OVjsendxpK1ungvHIMHzGJptMDw7LzEtE,5898
11
+ mdb_engine/auth/base.py,sha256=tIcC30_ViVuhmR8PCpY-MYBzu6Y9Ak1DZkAQishQyMg,7434
12
+ mdb_engine/auth/casbin_factory.py,sha256=66unyPRqNPydi0Bln8NNpsPt8gMwl7Hwc_nEsqfJj9U,16633
10
13
  mdb_engine/auth/casbin_models.py,sha256=7XtFmRBhhjw1nKprnluvjyJoTj5fzdPeQwVvo6fI-r0,955
11
14
  mdb_engine/auth/config_defaults.py,sha256=7JYX8CFI7OP7GHFIDHTf3Jns09LJcQ7f0_GL9yBnyuA,2018
12
15
  mdb_engine/auth/config_helpers.py,sha256=DpQ8QZAO2FVVKFmhTJIa4FYPS8Iy8O7vcVh_tg0INLg,6309
13
16
  mdb_engine/auth/cookie_utils.py,sha256=F88p6_aMG0aSmGXCn0KYjweSMPHqfce1lrKHU4P5yQk,4913
14
17
  mdb_engine/auth/csrf.py,sha256=Rx9qYt8owSJJwwj7Z_w4nzkaLbaqWoVpNv13qnqosIA,12458
15
18
  mdb_engine/auth/decorators.py,sha256=47uyOK_6WmK18J6ELRKwwgaIkcp6kHOILXuARj82Ijw,12288
16
- mdb_engine/auth/dependencies.py,sha256=hAmFhtOFFJWRpCFQyPuALJWcgSMZn_Os16S7Q5N9waQ,27038
19
+ mdb_engine/auth/dependencies.py,sha256=-JooBflCsyndw8oUJ864nX01QOX9Pq09KQhY43oaSJk,27156
17
20
  mdb_engine/auth/helpers.py,sha256=BCrid985cYh-3h5ZMUV9TES0q40uJXio4oYKQZta7KA,1970
18
- mdb_engine/auth/integration.py,sha256=MHb4d8ar1eywXJlo4I1dlvUJ6SP7KO_ql3kbVTs8FAU,21756
21
+ mdb_engine/auth/integration.py,sha256=zaTeo4ZXnxnTbw6iZCawZ6dDXDQQCaX6XYc6cbRw6xs,22759
19
22
  mdb_engine/auth/jwt.py,sha256=aRXLfgFjsebIARmPqgfcA5zSgSN44HD7BgSyOEFaQCM,7244
20
23
  mdb_engine/auth/middleware.py,sha256=uMx1dOO1NaR4K2nDet3k_ASR7rc7ZbKD0HlEkVYGJvU,10869
21
- mdb_engine/auth/oso_factory.py,sha256=sJfW9TlrKp6QF_f5kq84axWQJyPsNelDDKuYLmVsduU,11257
22
- mdb_engine/auth/provider.py,sha256=SNpkws-QO56hOo8CZ6LMenLjLQYO0NK_31zMhYekXx0,21926
24
+ mdb_engine/auth/oso_factory.py,sha256=FPDzL5zYrFWd--amBoqKk_1FHET8QzlmiYTLinZeezU,11289
25
+ mdb_engine/auth/provider.py,sha256=m7G1rMgMezalALcV_74Kb0G77exyAIP-eOGyI2XfApc,26595
23
26
  mdb_engine/auth/rate_limiter.py,sha256=kYuYIDlgkmYB2jx_UUmM9VrndUq2iTkdP7DZV-Jfu8o,15825
24
27
  mdb_engine/auth/restrictions.py,sha256=TXa2lO3lZQeMtokhyVLP19-XbWwq2R8JMTw2KfaiDMg,8852
25
28
  mdb_engine/auth/session_manager.py,sha256=XjYeE4i1998tBIefhp8VH3Oe7reyA_CC_qjw6zZ5EVY,15459
@@ -43,23 +46,27 @@ mdb_engine/core/app_registration.py,sha256=zRK2JTeT0rDW4XdOgFAV-j9Og7xijXdov4u1V
43
46
  mdb_engine/core/app_secrets.py,sha256=ipLsC_QdnIFhrCLNQ3nXvBAfndSor4WNRJyqPc0-J8Q,10555
44
47
  mdb_engine/core/connection.py,sha256=9WRccQ2Zz8K6PS6yC2XXxhZkppALvAWZJhfLmsJBnbI,8383
45
48
  mdb_engine/core/encryption.py,sha256=jblhUuu_L_lht0qlbn5vqDsdj9rN80uL9DCFDCD-zxw,7540
46
- mdb_engine/core/engine.py,sha256=hW86qxrHvaQdCJgyI93W0GVVxVB7ZUuY66QAiWaGXRA,55486
49
+ mdb_engine/core/engine.py,sha256=YmsoTNqMaLi4kcUFySSpCQZ1O8Fd41YryhwubfMfc0g,69566
47
50
  mdb_engine/core/index_management.py,sha256=9-r7MIy3JnjQ35sGqsbj8K_I07vAUWtAVgSWC99lJcE,5555
48
- mdb_engine/core/manifest.py,sha256=K95aiGvZ2YQ3pUIGJyMeJTvveg9HgGdJUpd6fO7AxmI,132305
51
+ mdb_engine/core/manifest.py,sha256=4Dk7iDOoxOrpZ20BA2onaX6cqMhWVSIA0bryeKPsXDQ,133677
49
52
  mdb_engine/core/ray_integration.py,sha256=Qe3jAYQhOKeBBlWFAcqzciDWN2zctJh_6uMTIai1tS0,13617
50
53
  mdb_engine/core/seeding.py,sha256=I5g43xdoEdC4rNwc_Ih0L6QOZguPcpAWrS6HvJ2a3fE,6433
51
54
  mdb_engine/core/service_initialization.py,sha256=gJNIB0As4vg6UXRgt1EDo5p3zzlHfF8NZqjCAlB75mA,12997
52
55
  mdb_engine/core/types.py,sha256=v_lSnBTyl2JHX39cPvPsnOxXhu8xaGC92UektvYPOvg,11239
53
- mdb_engine/database/README.md,sha256=cWPUce2PmrnIu4JQPF_RzsQ0Ju4pHIjhNhiFT0OdPKs,18481
56
+ mdb_engine/database/README.md,sha256=-31mVxBeVQaYsF3AD1-gQbD2NCYVcPjdFoA6sZ6b02Y,19354
54
57
  mdb_engine/database/__init__.py,sha256=rrc3eZFli3K2zrvVdDbMBi8YkmoHYzP6JNT0AUBE5VU,981
55
58
  mdb_engine/database/abstraction.py,sha256=FLVhFuS4OTZIRQyDkUBZdIlhqRndqNA89EO0cJvNsN0,23462
56
59
  mdb_engine/database/connection.py,sha256=PDmwkjb4wYhLTUjlcYHscorces69rIuSxt5wdYixGQw,13777
57
60
  mdb_engine/database/query_validator.py,sha256=AIWkQ-c6HAqJ-ixn-hq_0yfC2vdf1-jbEpzYZNmfEqs,13275
58
61
  mdb_engine/database/resource_limiter.py,sha256=n54-I6bjEk5jxNGMXyb6_fArDCiyJ69_h9goFW5GzUs,6936
59
62
  mdb_engine/database/scoped_wrapper.py,sha256=S_QIqGVyCteKAYlSUHNIqqc0S80jWhzHV-Lfa-ezNG4,94794
60
- mdb_engine/embeddings/README.md,sha256=lehHJm7gADRze1Em59Da7DWFuVqDhMKmLz8UaTF12Rc,4997
61
- mdb_engine/embeddings/__init__.py,sha256=UReBuU_0IOFg2kCpMjmZFV9b88PepL6oNok9Osd8t-4,2024
62
- mdb_engine/embeddings/dependencies.py,sha256=aQXZnIVLxWU1qnKh-fih0iCcdX3cPd0AdsNEajBLp4w,5915
63
+ mdb_engine/di/__init__.py,sha256=uy9Q153a0QE678TkJ_AEwLuxPY3OyEum2I42_JsuwrI,912
64
+ mdb_engine/di/container.py,sha256=Wf4-O69Kg_hLC3aHmAf847K7p0sHLh4aYKMGOTmvzok,7441
65
+ mdb_engine/di/providers.py,sha256=jCgez_w1NkfAHCa6O3tsoGHiKcZt-fAbmgvn7KXmTCU,5940
66
+ mdb_engine/di/scopes.py,sha256=0pNzm2I5aRr7H_IBCRhcwd4dW4LzwD4uC2PmWyZI1Ps,4187
67
+ mdb_engine/embeddings/README.md,sha256=XjGWUXSdbSpXCAEEVfYmcJoFKBVmXDoM3eTjenrM5Z0,5926
68
+ mdb_engine/embeddings/__init__.py,sha256=BM8tfcekVZv_iPQj3OuZBQ3hHr0eRQetNLEMysRTZkE,2129
69
+ mdb_engine/embeddings/dependencies.py,sha256=BphKvHYF5iYo6k7v4rYkEOYKZCtlGsPfMdrT6v1J430,2195
63
70
  mdb_engine/embeddings/service.py,sha256=v5Ch4VMADDUw-tqNs8XbaG9JJktvO7cqniNJ8Mes56k,25991
64
71
  mdb_engine/indexes/README.md,sha256=r7duq-1vtqHhBk1cwoBMYYh_dfTzxiaQaPE3mLB_3JQ,15341
65
72
  mdb_engine/indexes/__init__.py,sha256=9QFJ6qo_yD26dZcKyKjj-hhesFpaomBt-mWTtYTQvqc,613
@@ -73,13 +80,17 @@ mdb_engine/observability/__init__.py,sha256=jjLsrW6Gy2ayrbfLrgHsDB61NxWWkYLHwv0q
73
80
  mdb_engine/observability/health.py,sha256=kZ9LXcJ3_8tKXRWXNNCz3qsj0PkZ0BSTdzisc8ds2vw,9197
74
81
  mdb_engine/observability/logging.py,sha256=yo_KnUtqjPx_KvqNrAxW8ud6HQjI7Lk6T7Lj7IMW1uY,4073
75
82
  mdb_engine/observability/metrics.py,sha256=EL9-ZFOaxxIdU8PWIqPRyPZHhP3fc4VyUawRSS2GIY4,10726
83
+ mdb_engine/repositories/__init__.py,sha256=048N4QmFLVhJyLdYrWHTTBqujhaF--B8g0z6fUSMuJs,858
84
+ mdb_engine/repositories/base.py,sha256=-Llwhn5NxEh-5S6CJAzZx1nF6J2Sch0WxIpMaaPQhs4,8575
85
+ mdb_engine/repositories/mongo.py,sha256=aR_JFDYtWIZiZA616tDbOPrLN_Gi8diD6Hc9UfeaT-w,7177
86
+ mdb_engine/repositories/unit_of_work.py,sha256=obTsGCcZgsNhQdFOvNGLtvq-guyykmPZzBo-GM_ROAo,5146
76
87
  mdb_engine/routing/README.md,sha256=WVvTQXDq0amryrjkCu0wP_piOEwFjLukjmPz2mroWHY,13658
77
88
  mdb_engine/routing/__init__.py,sha256=reupjHi_RTc2ZBA4AH5XzobAmqy4EQIsfSUcTkFknUM,2438
78
89
  mdb_engine/routing/websockets.py,sha256=X6-MG0mAN8ZEgdmZD8edaiDx8DqMCN-hV3coIOdgZNc,29346
79
90
  mdb_engine/utils/__init__.py,sha256=_xjHB5p6WLWBql1DyDqf5zdjj2xpfMlK25Y6BH9-oFk,145
80
- mdb_engine-0.1.7.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
81
- mdb_engine-0.1.7.dist-info/METADATA,sha256=xhr0VvNWMKVjLgu-fkRbXzFWLf7nb8B5u_4J1LXkXfE,9305
82
- mdb_engine-0.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
83
- mdb_engine-0.1.7.dist-info/entry_points.txt,sha256=INCbYdFbBzJalwPwxliEzLmPfR57IvQ7RAXG_pn8cL8,48
84
- mdb_engine-0.1.7.dist-info/top_level.txt,sha256=PH0UEBwTtgkm2vWvC9He_EOMn7hVn_Wg_Jyc0SmeO8k,11
85
- mdb_engine-0.1.7.dist-info/RECORD,,
91
+ mdb_engine-0.2.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
92
+ mdb_engine-0.2.0.dist-info/METADATA,sha256=uJJNixiSiX8qERmvxc6hJ4YbDulOg2cn7j3XSm41PxI,10470
93
+ mdb_engine-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
94
+ mdb_engine-0.2.0.dist-info/entry_points.txt,sha256=INCbYdFbBzJalwPwxliEzLmPfR57IvQ7RAXG_pn8cL8,48
95
+ mdb_engine-0.2.0.dist-info/top_level.txt,sha256=PH0UEBwTtgkm2vWvC9He_EOMn7hVn_Wg_Jyc0SmeO8k,11
96
+ mdb_engine-0.2.0.dist-info/RECORD,,