mdb-engine 0.2.3__py3-none-any.whl → 0.3.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.
@@ -4,4 +4,6 @@ Utility functions and helpers for MDB Engine.
4
4
  This module provides utility functions used across the MDB Engine codebase.
5
5
  """
6
6
 
7
- __all__ = []
7
+ from .mongo import clean_mongo_doc, clean_mongo_docs
8
+
9
+ __all__ = ["clean_mongo_doc", "clean_mongo_docs"]
@@ -0,0 +1,117 @@
1
+ """
2
+ MongoDB utility functions for MDB Engine.
3
+
4
+ This module provides utility functions for working with MongoDB documents,
5
+ including JSON serialization helpers.
6
+ """
7
+
8
+ from typing import Any
9
+
10
+
11
+ def clean_mongo_doc(doc: dict[str, Any] | None) -> dict[str, Any] | None:
12
+ """
13
+ Convert MongoDB document to JSON-serializable format.
14
+
15
+ Recursively converts MongoDB-specific types to JSON-compatible types:
16
+ - ObjectId -> str
17
+ - datetime -> ISO format string
18
+ - Nested dictionaries and lists are processed recursively
19
+
20
+ Args:
21
+ doc: MongoDB document (dict) or None
22
+
23
+ Returns:
24
+ Cleaned document with all MongoDB types converted, or None if input was None
25
+
26
+ Example:
27
+ ```python
28
+ from mdb_engine.utils import clean_mongo_doc
29
+
30
+ # MongoDB document with ObjectId and datetime
31
+ doc = {
32
+ "_id": ObjectId("507f1f77bcf86cd799439011"),
33
+ "name": "John",
34
+ "created_at": datetime(2024, 1, 1, 12, 0, 0),
35
+ "nested": {
36
+ "id": ObjectId("507f1f77bcf86cd799439012")
37
+ }
38
+ }
39
+
40
+ # Convert to JSON-serializable format
41
+ cleaned = clean_mongo_doc(doc)
42
+ # {
43
+ # "_id": "507f1f77bcf86cd799439011",
44
+ # "name": "John",
45
+ # "created_at": "2024-01-01T12:00:00",
46
+ # "nested": {
47
+ # "id": "507f1f77bcf86cd799439012"
48
+ # }
49
+ # }
50
+ ```
51
+ """
52
+ from datetime import datetime
53
+
54
+ from bson import ObjectId
55
+
56
+ if doc is None:
57
+ return None
58
+
59
+ if not isinstance(doc, dict):
60
+ # If it's not a dict, try to convert it
61
+ if isinstance(doc, ObjectId):
62
+ return str(doc)
63
+ elif isinstance(doc, datetime):
64
+ return doc.isoformat() if hasattr(doc, "isoformat") else str(doc)
65
+ else:
66
+ return doc
67
+
68
+ cleaned: dict[str, Any] = {}
69
+
70
+ for key, value in doc.items():
71
+ if isinstance(value, ObjectId):
72
+ cleaned[key] = str(value)
73
+ elif isinstance(value, datetime):
74
+ cleaned[key] = value.isoformat() if hasattr(value, "isoformat") else str(value)
75
+ elif isinstance(value, dict):
76
+ cleaned[key] = clean_mongo_doc(value)
77
+ elif isinstance(value, list):
78
+ cleaned[key] = [
79
+ clean_mongo_doc(item)
80
+ if isinstance(item, dict)
81
+ else (
82
+ str(item)
83
+ if isinstance(item, ObjectId)
84
+ else (item.isoformat() if isinstance(item, datetime) else item)
85
+ )
86
+ for item in value
87
+ ]
88
+ else:
89
+ cleaned[key] = value
90
+
91
+ return cleaned
92
+
93
+
94
+ def clean_mongo_docs(docs: list[dict[str, Any]]) -> list[dict[str, Any]]:
95
+ """
96
+ Convert a list of MongoDB documents to JSON-serializable format.
97
+
98
+ Convenience function that applies clean_mongo_doc to each document in a list.
99
+
100
+ Args:
101
+ docs: List of MongoDB documents
102
+
103
+ Returns:
104
+ List of cleaned documents
105
+
106
+ Example:
107
+ ```python
108
+ from mdb_engine.utils import clean_mongo_docs
109
+
110
+ # List of MongoDB documents
111
+ docs = await db.collection.find({}).to_list(length=10)
112
+
113
+ # Convert all to JSON-serializable format
114
+ cleaned = clean_mongo_docs(docs)
115
+ ```
116
+ """
117
+ return [clean_mongo_doc(doc) for doc in docs]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mdb-engine
3
- Version: 0.2.3
3
+ Version: 0.3.0
4
4
  Summary: MongoDB Engine
5
5
  Home-page: https://github.com/ranfysvalle02/mdb-engine
6
6
  Author: Fabian Valle
@@ -73,6 +73,31 @@ Dynamic: requires-python
73
73
 
74
74
  ---
75
75
 
76
+ ## 🎯 manifest.json: The Key to Everything
77
+
78
+ **`manifest.json` is the foundation of your application.** It's a single configuration file that defines your app's identity, data structure, authentication, indexes, and services. Everything flows from this file.
79
+
80
+ ### Your First manifest.json
81
+
82
+ Create a `manifest.json` file with just 3 fields:
83
+
84
+ ```json
85
+ {
86
+ "schema_version": "2.0",
87
+ "slug": "my_app",
88
+ "name": "My App"
89
+ }
90
+ ```
91
+
92
+ That's it! This minimal manifest gives you:
93
+ - ✅ Automatic data scoping (all queries filtered by `app_id`)
94
+ - ✅ Collection name prefixing (`db.tasks` → `my_app_tasks`)
95
+ - ✅ App registration and lifecycle management
96
+
97
+ **Learn more**: [Quick Start Guide](docs/QUICK_START.md) | [Manifest Deep Dive](docs/MANIFEST_DEEP_DIVE.md)
98
+
99
+ ---
100
+
76
101
  ## Installation
77
102
 
78
103
  ```bash
@@ -81,31 +106,162 @@ pip install mdb-engine
81
106
 
82
107
  ---
83
108
 
84
- ## 30-Second Quick Start
109
+ ## 30-Second Quick Start: Build a Todo List API
110
+
111
+ Let's build a complete CRUD todo list app in 3 steps!
112
+
113
+ ### Step 1: Create `manifest.json`
114
+
115
+ ```json
116
+ {
117
+ "schema_version": "2.0",
118
+ "slug": "todo_app",
119
+ "name": "Todo List App",
120
+ "managed_indexes": {
121
+ "todos": [
122
+ {
123
+ "type": "regular",
124
+ "keys": {"completed": 1, "created_at": -1},
125
+ "name": "completed_sort"
126
+ }
127
+ ]
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### Step 2: Create `app.py` with Full CRUD
85
133
 
86
134
  ```python
135
+ from datetime import datetime
87
136
  from pathlib import Path
88
- from fastapi import Depends
137
+ from typing import Optional
138
+
139
+ from bson import ObjectId
140
+ from fastapi import Depends, HTTPException
141
+ from pydantic import BaseModel
142
+
89
143
  from mdb_engine import MongoDBEngine
90
144
  from mdb_engine.dependencies import get_scoped_db
91
145
 
92
- # 1. Initialize the engine
146
+ # Initialize engine
93
147
  engine = MongoDBEngine(
94
148
  mongo_uri="mongodb://localhost:27017",
95
149
  db_name="my_database"
96
150
  )
97
151
 
98
- # 2. Create a FastAPI app with automatic lifecycle management
99
- app = engine.create_app(slug="my_app", manifest=Path("manifest.json"))
152
+ # Create app - manifest.json loaded automatically!
153
+ app = engine.create_app(
154
+ slug="todo_app",
155
+ manifest=Path("manifest.json")
156
+ )
100
157
 
101
- # 3. Use request-scoped dependencies - all queries automatically isolated
102
- @app.post("/tasks")
103
- async def create_task(task: dict, db=Depends(get_scoped_db)):
104
- result = await db.tasks.insert_one(task)
105
- return {"id": str(result.inserted_id)}
158
+ # Pydantic models
159
+ class TodoCreate(BaseModel):
160
+ title: str
161
+ description: Optional[str] = None
162
+
163
+ class TodoUpdate(BaseModel):
164
+ title: Optional[str] = None
165
+ description: Optional[str] = None
166
+ completed: Optional[bool] = None
167
+
168
+ # CREATE - Add a new todo
169
+ @app.post("/todos")
170
+ async def create_todo(todo: TodoCreate, db=Depends(get_scoped_db)):
171
+ doc = {
172
+ **todo.dict(),
173
+ "completed": False,
174
+ "created_at": datetime.utcnow()
175
+ }
176
+ result = await db.todos.insert_one(doc)
177
+ return {"id": str(result.inserted_id), "message": "Todo created"}
178
+
179
+ # READ - List all todos
180
+ @app.get("/todos")
181
+ async def list_todos(completed: Optional[bool] = None, db=Depends(get_scoped_db)):
182
+ query = {}
183
+ if completed is not None:
184
+ query["completed"] = completed
185
+
186
+ todos = await db.todos.find(query).sort("created_at", -1).to_list(length=100)
187
+ for todo in todos:
188
+ todo["_id"] = str(todo["_id"])
189
+ return {"todos": todos, "count": len(todos)}
190
+
191
+ # READ - Get single todo
192
+ @app.get("/todos/{todo_id}")
193
+ async def get_todo(todo_id: str, db=Depends(get_scoped_db)):
194
+ todo = await db.todos.find_one({"_id": ObjectId(todo_id)})
195
+ if not todo:
196
+ raise HTTPException(status_code=404, detail="Todo not found")
197
+ todo["_id"] = str(todo["_id"])
198
+ return todo
199
+
200
+ # UPDATE - Update a todo
201
+ @app.put("/todos/{todo_id}")
202
+ async def update_todo(todo_id: str, todo: TodoUpdate, db=Depends(get_scoped_db)):
203
+ updates = {k: v for k, v in todo.dict(exclude_unset=True).items() if v is not None}
204
+ if not updates:
205
+ raise HTTPException(status_code=400, detail="No fields to update")
206
+
207
+ updates["updated_at"] = datetime.utcnow()
208
+ result = await db.todos.update_one(
209
+ {"_id": ObjectId(todo_id)},
210
+ {"$set": updates}
211
+ )
212
+
213
+ if result.matched_count == 0:
214
+ raise HTTPException(status_code=404, detail="Todo not found")
215
+ return {"message": "Todo updated"}
216
+
217
+ # DELETE - Delete a todo
218
+ @app.delete("/todos/{todo_id}")
219
+ async def delete_todo(todo_id: str, db=Depends(get_scoped_db)):
220
+ result = await db.todos.delete_one({"_id": ObjectId(todo_id)})
221
+ if result.deleted_count == 0:
222
+ raise HTTPException(status_code=404, detail="Todo not found")
223
+ return {"message": "Todo deleted"}
224
+ ```
225
+
226
+ ### Step 3: Run It!
227
+
228
+ ```bash
229
+ # Start MongoDB (if not running)
230
+ mongod
231
+
232
+ # Install dependencies
233
+ pip install mdb-engine fastapi uvicorn
234
+
235
+ # Run the app
236
+ uvicorn app:app --reload
237
+ ```
238
+
239
+ **Test your API:**
240
+ ```bash
241
+ # Create a todo
242
+ curl -X POST http://localhost:8000/todos \
243
+ -H "Content-Type: application/json" \
244
+ -d '{"title": "Buy groceries", "description": "Milk and eggs"}'
245
+
246
+ # List todos
247
+ curl http://localhost:8000/todos
248
+
249
+ # Update a todo (replace {id} with actual ID)
250
+ curl -X PUT http://localhost:8000/todos/{id} \
251
+ -H "Content-Type: application/json" \
252
+ -d '{"completed": true}'
253
+
254
+ # Delete a todo
255
+ curl -X DELETE http://localhost:8000/todos/{id}
106
256
  ```
107
257
 
108
- That's it. Your data is automatically sandboxed, indexes are created, and cleanup is handled.
258
+ **What just happened?**
259
+ - ✅ **Automatic scoping**: All queries filtered by `app_id` — your data is isolated
260
+ - ✅ **Indexes created**: The `completed_sort` index was created automatically
261
+ - ✅ **Lifecycle managed**: Startup/shutdown handled automatically
262
+ - ✅ **Zero boilerplate**: No connection setup, no index scripts, no auth handlers
263
+
264
+ **That's it!** You now have a fully functional, production-ready todo API with automatic data sandboxing, index management, and lifecycle handling.
109
265
 
110
266
  ---
111
267
 
@@ -200,9 +356,11 @@ async def health():
200
356
 
201
357
  ## Why mdb-engine?
202
358
 
359
+ - **manifest.json is everything** — Single source of truth for your entire app configuration
203
360
  - **Zero boilerplate** — No more connection setup, index creation scripts, or auth handlers
204
361
  - **Data isolation** — Multi-tenant ready with automatic app sandboxing
205
362
  - **Manifest-driven** — Define your app's "DNA" in JSON, not scattered code
363
+ - **Incremental adoption** — Start minimal, add features as needed
206
364
  - **No lock-in** — Standard Motor/PyMongo underneath; export anytime with `mongodump --query='{"app_id":"my_app"}'`
207
365
 
208
366
  ---
@@ -300,13 +458,34 @@ async def get_items():
300
458
 
301
459
  ---
302
460
 
461
+ ## Understanding manifest.json
462
+
463
+ Your `manifest.json` is the heart of your application. It defines:
464
+
465
+ - **App Identity**: `slug`, `name`, `description`
466
+ - **Data Access**: `data_access.read_scopes`, `data_access.write_scope`
467
+ - **Indexes**: `managed_indexes` (regular, vector, text, TTL, compound)
468
+ - **Authentication**: `auth.policy`, `auth.users` (Casbin/OSO, demo users)
469
+ - **AI Services**: `embedding_config`, `memory_config`
470
+ - **Real-time**: `websockets` endpoints
471
+ - **CORS**: `cors` settings
472
+
473
+ **Start minimal, grow as needed.** You can begin with just `slug`, `name`, and `schema_version`, then add features incrementally.
474
+
475
+ **📖 Learn More:**
476
+ - [Quick Start Guide](docs/QUICK_START.md) - Get started with manifest.json
477
+ - [Manifest Deep Dive](docs/MANIFEST_DEEP_DIVE.md) - Comprehensive manifest.json guide
478
+ - [Examples](examples/) - Real-world manifest.json files
479
+
480
+ ---
481
+
303
482
  ## Links
304
483
 
305
484
  - [GitHub Repository](https://github.com/ranfysvalle02/mdb-engine)
306
485
  - [Documentation](https://github.com/ranfysvalle02/mdb-engine/tree/main/docs)
307
486
  - [All Examples](https://github.com/ranfysvalle02/mdb-engine/tree/main/examples)
308
- - [Quick Start Guide](https://github.com/ranfysvalle02/mdb-engine/blob/main/docs/QUICK_START.md)
309
- - [Contributing](https://github.com/ranfysvalle02/mdb-engine/blob/main/CONTRIBUTING.md)
487
+ - [Quick Start Guide](docs/QUICK_START.md) - **Start here!**
488
+ - [Contributing](CONTRIBUTING.md)
310
489
 
311
490
  ---
312
491
 
@@ -1,11 +1,11 @@
1
1
  mdb_engine/README.md,sha256=T3EFGcPopY9LslYW3lxgG3hohWkAOmBNbYG0FDMUJiY,3502
2
- mdb_engine/__init__.py,sha256=-W3Gdj2GAoptKsR_T4xluYnmnelZTdKrTxCthIytZ48,3008
2
+ mdb_engine/__init__.py,sha256=MUAh3xwHgMQZ9FyYIfDnOwiUficDQbkZ3sBb43v-U64,3189
3
3
  mdb_engine/config.py,sha256=DTAyxfKB8ogyI0v5QR9Y-SJOgXQr_eDBCKxNBSqEyLc,7269
4
4
  mdb_engine/constants.py,sha256=eaotvW57TVOg7rRbLziGrVNoP7adgw_G9iVByHezc_A,7837
5
5
  mdb_engine/dependencies.py,sha256=MJuYQhZ9ZGzXlip1ha5zba9Rvn04HDPWahJFJH81Q2s,14107
6
6
  mdb_engine/exceptions.py,sha256=NkBSdTBNP9bVTtI6w6mAoEfeVZDq-Bg7vCF2L26ZDZo,8442
7
7
  mdb_engine/auth/ARCHITECTURE.md,sha256=JXZsjEIpNz4Szk18KaOiEabhEuz1pmYWXQRN-EJEHDM,4076
8
- mdb_engine/auth/README.md,sha256=STL4PHyMlYpSNEAqo4RBKTEm4kz1GbWpI9c_lS94nV4,36802
8
+ mdb_engine/auth/README.md,sha256=IVlUOat96V3yM6wk4T-u4GxJ4-WF05eBSJBlvIexyBo,37285
9
9
  mdb_engine/auth/__init__.py,sha256=QemWqAVvqlxjF-UbzMTGP5AUOeuaAsUEtK4PMxmozmA,5852
10
10
  mdb_engine/auth/audit.py,sha256=UQ0Bj5Zxp5et9A21YZCVkUjaABFqO1CXaMrWxNcdxm8,17352
11
11
  mdb_engine/auth/base.py,sha256=4E3XkbruZLG9lc6aC56w0ypjnfiR5RbtjQKwn4am8to,7418
@@ -26,7 +26,7 @@ mdb_engine/auth/provider.py,sha256=FOSHn-jp4VYtxvmjnzho5kH6y-xDKWbcKUorYRRl1C4,2
26
26
  mdb_engine/auth/rate_limiter.py,sha256=l3EYZE1Kz9yVfZwNrKq_1AgdD7GXB1WOLSqqGQVSSgA,15808
27
27
  mdb_engine/auth/restrictions.py,sha256=tOyQBO_w0bK9zmTsOPZf9cbvh4oITvpNfSxIXt-XrcU,8824
28
28
  mdb_engine/auth/session_manager.py,sha256=ywWJjTarm-obgJ3zO3s-1cdqEYe0XrozlY00q_yMJ8I,15396
29
- mdb_engine/auth/shared_middleware.py,sha256=c1yQCbEWDyEH3Q0IieTO85Gin50GwTJnMEbwLBM5SHg,22312
29
+ mdb_engine/auth/shared_middleware.py,sha256=3lvm6aC0W_7ECvno_Mj3eu_93DZ--JiXhZ9hte8tvhM,30480
30
30
  mdb_engine/auth/shared_users.py,sha256=25OBks4VRHaYZW7R61vnplV7wmr7RRpDctSgnej_nxc,26773
31
31
  mdb_engine/auth/token_lifecycle.py,sha256=Q9S1X2Y6W7Ckt5PvyYXswBRh2Tg9DGpyRv_3Xve7VYQ,6708
32
32
  mdb_engine/auth/token_store.py,sha256=-B8j5RH5YEoKsswF4rnMoI51BaxMe4icke3kuehXmcI,9121
@@ -46,9 +46,9 @@ mdb_engine/core/app_registration.py,sha256=7szt2a7aBkpSppjmhdkkPPYMKGKo0MkLKZeEe
46
46
  mdb_engine/core/app_secrets.py,sha256=bo-syg9UUATibNyXEZs-0TTYWG-JaY-2S0yNSGA12n0,10524
47
47
  mdb_engine/core/connection.py,sha256=XnwuPG34pJ7kJGJ84T0mhj1UZ6_CLz_9qZf6NRYGIS8,8346
48
48
  mdb_engine/core/encryption.py,sha256=RZ5LPF5g28E3ZBn6v1IMw_oas7u9YGFtBcEj8lTi9LM,7515
49
- mdb_engine/core/engine.py,sha256=ciQHxHEcFh-DOQ0X9gV5kKk9WAxj3GKg5JDIPfFZjMg,69459
49
+ mdb_engine/core/engine.py,sha256=R1mU99Aa3z0P4xlPnofm9H9sZr4CWnsAaa85j-N3iJQ,86857
50
50
  mdb_engine/core/index_management.py,sha256=9-r7MIy3JnjQ35sGqsbj8K_I07vAUWtAVgSWC99lJcE,5555
51
- mdb_engine/core/manifest.py,sha256=Rezktd0Ulv28N6vO2Pg5Z6HNVy8hEdQqJ5pO08rRk6U,133570
51
+ mdb_engine/core/manifest.py,sha256=jguhjVPAHMZGxOJcdSGouv9_XiKmxUjDmyjn2yXHCj4,139205
52
52
  mdb_engine/core/ray_integration.py,sha256=vexYOzztscvRYje1xTNmXJbi99oJxCaVJAwKfTNTF_E,13610
53
53
  mdb_engine/core/seeding.py,sha256=c5IhdwlqUf_4Q5FFTAhPLaHPaUr_Txo3z_DUwZmWsFs,6421
54
54
  mdb_engine/core/service_initialization.py,sha256=rtb6BaPvFqomwT_s7bdbbvqi5m74llT0LkJFEhVG9Gg,12996
@@ -67,14 +67,14 @@ mdb_engine/di/scopes.py,sha256=pZgdkZ9ziW-vYCMvecC8Mv3Ud_Xk4ScsDYZ2eWHvar0,4165
67
67
  mdb_engine/embeddings/README.md,sha256=XjGWUXSdbSpXCAEEVfYmcJoFKBVmXDoM3eTjenrM5Z0,5926
68
68
  mdb_engine/embeddings/__init__.py,sha256=BM8tfcekVZv_iPQj3OuZBQ3hHr0eRQetNLEMysRTZkE,2129
69
69
  mdb_engine/embeddings/dependencies.py,sha256=0LIEU5L1jvZBKO4yhYxh4WxDhzJaZI9ohZGBNa6B7IY,2182
70
- mdb_engine/embeddings/service.py,sha256=yqVplODYLwWpEagv3mwS7n1-WXt2U-TluHwNi_BQ9Uc,25807
70
+ mdb_engine/embeddings/service.py,sha256=3JUqAU-e5TVLOpry5MdP-O4q6tHoqkXA8PyvcxqFoik,26983
71
71
  mdb_engine/indexes/README.md,sha256=r7duq-1vtqHhBk1cwoBMYYh_dfTzxiaQaPE3mLB_3JQ,15341
72
72
  mdb_engine/indexes/__init__.py,sha256=9QFJ6qo_yD26dZcKyKjj-hhesFpaomBt-mWTtYTQvqc,613
73
73
  mdb_engine/indexes/helpers.py,sha256=tJHqDm18jKLrW-P2ofmnUnaf4_-V5xDLjqP_WU8W9MM,4190
74
74
  mdb_engine/indexes/manager.py,sha256=XSjvFNMOv67yey5Vi4mKBt6_w4b6Hqtv24fiAXnfLi0,32460
75
- mdb_engine/memory/README.md,sha256=vy2FSXADcqG18YrFBfrMph9a1vYKuLijhs8ziNFdvRk,10631
75
+ mdb_engine/memory/README.md,sha256=uOE4SnPyq8TdoxGrttof5fSj2KSqnrgzUorMCV_1wg0,13624
76
76
  mdb_engine/memory/__init__.py,sha256=e4kAYgxd_-WAH8GovTwjEBO9hvASu_kXEupMgksAL-U,1008
77
- mdb_engine/memory/service.py,sha256=zX0oaHs8SHikH1fX4CtRF5pbOu1swEoiy3Segz_nLZI,47461
77
+ mdb_engine/memory/service.py,sha256=l2bkKVN9AyUjO9K9ykb5BK9dZjs3ns78FJLOD5LajsY,18454
78
78
  mdb_engine/observability/README.md,sha256=CMgQaC1H8ESmCitfbhJifz6-XoXH_FPNE4MvuZ-oFas,13085
79
79
  mdb_engine/observability/__init__.py,sha256=jjLsrW6Gy2ayrbfLrgHsDB61NxWWkYLHwv0q-N3fxjA,1213
80
80
  mdb_engine/observability/health.py,sha256=eFd8a-Rv3NWML0EDdZ8thZWTiqP_FUZbub97hV2z57g,9190
@@ -87,10 +87,11 @@ mdb_engine/repositories/unit_of_work.py,sha256=XvmwGOspEDj4hsfOULPsQKjB1QZqh83TJ
87
87
  mdb_engine/routing/README.md,sha256=WVvTQXDq0amryrjkCu0wP_piOEwFjLukjmPz2mroWHY,13658
88
88
  mdb_engine/routing/__init__.py,sha256=reupjHi_RTc2ZBA4AH5XzobAmqy4EQIsfSUcTkFknUM,2438
89
89
  mdb_engine/routing/websockets.py,sha256=3X4OjQv_Nln4UmeifJky0gFhMG8A6alR77I8g1iIOLY,29311
90
- mdb_engine/utils/__init__.py,sha256=_xjHB5p6WLWBql1DyDqf5zdjj2xpfMlK25Y6BH9-oFk,145
91
- mdb_engine-0.2.3.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
92
- mdb_engine-0.2.3.dist-info/METADATA,sha256=-GUB0bt3MSLlo3Ayigjb2NnA2rZBPtdXrgq7oI0gBEE,10490
93
- mdb_engine-0.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
94
- mdb_engine-0.2.3.dist-info/entry_points.txt,sha256=INCbYdFbBzJalwPwxliEzLmPfR57IvQ7RAXG_pn8cL8,48
95
- mdb_engine-0.2.3.dist-info/top_level.txt,sha256=PH0UEBwTtgkm2vWvC9He_EOMn7hVn_Wg_Jyc0SmeO8k,11
96
- mdb_engine-0.2.3.dist-info/RECORD,,
90
+ mdb_engine/utils/__init__.py,sha256=lDxQSGqkV4fVw5TWIk6FA6_eey_ZnEtMY0fir3cpAe8,236
91
+ mdb_engine/utils/mongo.py,sha256=Oqtv4tQdpiiZzrilGLEYQPo8Vmh8WsTQypxQs8Of53s,3369
92
+ mdb_engine-0.3.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
93
+ mdb_engine-0.3.0.dist-info/METADATA,sha256=yifqmZSH5TBouzzOqnelCgGXlnMMqmNgTjRl7SXzk5g,15810
94
+ mdb_engine-0.3.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
95
+ mdb_engine-0.3.0.dist-info/entry_points.txt,sha256=INCbYdFbBzJalwPwxliEzLmPfR57IvQ7RAXG_pn8cL8,48
96
+ mdb_engine-0.3.0.dist-info/top_level.txt,sha256=PH0UEBwTtgkm2vWvC9He_EOMn7hVn_Wg_Jyc0SmeO8k,11
97
+ mdb_engine-0.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5