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.
Files changed (75) hide show
  1. mdb_engine/README.md +144 -0
  2. mdb_engine/__init__.py +37 -0
  3. mdb_engine/auth/README.md +631 -0
  4. mdb_engine/auth/__init__.py +128 -0
  5. mdb_engine/auth/casbin_factory.py +199 -0
  6. mdb_engine/auth/casbin_models.py +46 -0
  7. mdb_engine/auth/config_defaults.py +71 -0
  8. mdb_engine/auth/config_helpers.py +213 -0
  9. mdb_engine/auth/cookie_utils.py +158 -0
  10. mdb_engine/auth/decorators.py +350 -0
  11. mdb_engine/auth/dependencies.py +747 -0
  12. mdb_engine/auth/helpers.py +64 -0
  13. mdb_engine/auth/integration.py +578 -0
  14. mdb_engine/auth/jwt.py +225 -0
  15. mdb_engine/auth/middleware.py +241 -0
  16. mdb_engine/auth/oso_factory.py +323 -0
  17. mdb_engine/auth/provider.py +570 -0
  18. mdb_engine/auth/restrictions.py +271 -0
  19. mdb_engine/auth/session_manager.py +477 -0
  20. mdb_engine/auth/token_lifecycle.py +213 -0
  21. mdb_engine/auth/token_store.py +289 -0
  22. mdb_engine/auth/users.py +1516 -0
  23. mdb_engine/auth/utils.py +614 -0
  24. mdb_engine/cli/__init__.py +13 -0
  25. mdb_engine/cli/commands/__init__.py +7 -0
  26. mdb_engine/cli/commands/generate.py +105 -0
  27. mdb_engine/cli/commands/migrate.py +83 -0
  28. mdb_engine/cli/commands/show.py +70 -0
  29. mdb_engine/cli/commands/validate.py +63 -0
  30. mdb_engine/cli/main.py +41 -0
  31. mdb_engine/cli/utils.py +92 -0
  32. mdb_engine/config.py +217 -0
  33. mdb_engine/constants.py +160 -0
  34. mdb_engine/core/README.md +542 -0
  35. mdb_engine/core/__init__.py +42 -0
  36. mdb_engine/core/app_registration.py +392 -0
  37. mdb_engine/core/connection.py +243 -0
  38. mdb_engine/core/engine.py +749 -0
  39. mdb_engine/core/index_management.py +162 -0
  40. mdb_engine/core/manifest.py +2793 -0
  41. mdb_engine/core/seeding.py +179 -0
  42. mdb_engine/core/service_initialization.py +355 -0
  43. mdb_engine/core/types.py +413 -0
  44. mdb_engine/database/README.md +522 -0
  45. mdb_engine/database/__init__.py +31 -0
  46. mdb_engine/database/abstraction.py +635 -0
  47. mdb_engine/database/connection.py +387 -0
  48. mdb_engine/database/scoped_wrapper.py +1721 -0
  49. mdb_engine/embeddings/README.md +184 -0
  50. mdb_engine/embeddings/__init__.py +62 -0
  51. mdb_engine/embeddings/dependencies.py +193 -0
  52. mdb_engine/embeddings/service.py +759 -0
  53. mdb_engine/exceptions.py +167 -0
  54. mdb_engine/indexes/README.md +651 -0
  55. mdb_engine/indexes/__init__.py +21 -0
  56. mdb_engine/indexes/helpers.py +145 -0
  57. mdb_engine/indexes/manager.py +895 -0
  58. mdb_engine/memory/README.md +451 -0
  59. mdb_engine/memory/__init__.py +30 -0
  60. mdb_engine/memory/service.py +1285 -0
  61. mdb_engine/observability/README.md +515 -0
  62. mdb_engine/observability/__init__.py +42 -0
  63. mdb_engine/observability/health.py +296 -0
  64. mdb_engine/observability/logging.py +161 -0
  65. mdb_engine/observability/metrics.py +297 -0
  66. mdb_engine/routing/README.md +462 -0
  67. mdb_engine/routing/__init__.py +73 -0
  68. mdb_engine/routing/websockets.py +813 -0
  69. mdb_engine/utils/__init__.py +7 -0
  70. mdb_engine-0.1.6.dist-info/METADATA +213 -0
  71. mdb_engine-0.1.6.dist-info/RECORD +75 -0
  72. mdb_engine-0.1.6.dist-info/WHEEL +5 -0
  73. mdb_engine-0.1.6.dist-info/entry_points.txt +2 -0
  74. mdb_engine-0.1.6.dist-info/licenses/LICENSE +661 -0
  75. mdb_engine-0.1.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,651 @@
1
+ # Index Management Module
2
+
3
+ High-level index creation and management orchestration for MDB_ENGINE applications. Supports all MongoDB index types including regular, TTL, partial, text, geospatial, vector search, and Atlas Search indexes.
4
+
5
+ ## Features
6
+
7
+ - **Index Orchestration**: High-level functions for creating indexes from manifest definitions
8
+ - **All Index Types**: Support for regular, TTL, partial, text, geospatial, vector, search, and hybrid indexes
9
+ - **Index Validation**: Built-in validation for index definitions
10
+ - **Helper Functions**: Utilities for key normalization and index comparison
11
+ - **Manifest Integration**: Seamless integration with manifest.json index definitions
12
+
13
+ ## Installation
14
+
15
+ The indexes module is part of MDB_ENGINE. No additional installation required.
16
+
17
+ ## Quick Start
18
+
19
+ ### Basic Usage
20
+
21
+ ```python
22
+ from mdb_engine.indexes import run_index_creation_for_collection
23
+ from motor.motor_asyncio import AsyncIOMotorDatabase
24
+
25
+ # Define indexes in manifest or programmatically
26
+ index_definitions = [
27
+ {
28
+ "name": "email_idx",
29
+ "type": "regular",
30
+ "keys": {"email": 1},
31
+ "unique": True
32
+ },
33
+ {
34
+ "name": "status_created_idx",
35
+ "type": "regular",
36
+ "keys": {"status": 1, "created_at": -1}
37
+ }
38
+ ]
39
+
40
+ # Create indexes for a collection
41
+ await run_index_creation_for_collection(
42
+ db=db,
43
+ slug="my_app",
44
+ collection_name="users",
45
+ index_definitions=index_definitions
46
+ )
47
+ ```
48
+
49
+ ## Index Types
50
+
51
+ ### Regular Indexes
52
+
53
+ Standard MongoDB indexes for efficient queries:
54
+
55
+ ```python
56
+ index_definitions = [
57
+ {
58
+ "name": "email_idx",
59
+ "type": "regular",
60
+ "keys": {"email": 1},
61
+ "options": {
62
+ "unique": True,
63
+ "sparse": False
64
+ }
65
+ },
66
+ {
67
+ "name": "compound_idx",
68
+ "type": "regular",
69
+ "keys": {"status": 1, "created_at": -1, "priority": 1}
70
+ }
71
+ ]
72
+ ```
73
+
74
+ ### TTL Indexes
75
+
76
+ Time-to-live indexes that automatically expire documents:
77
+
78
+ ```python
79
+ index_definitions = [
80
+ {
81
+ "name": "expire_sessions",
82
+ "type": "ttl",
83
+ "keys": {"last_activity": 1},
84
+ "options": {
85
+ "expireAfterSeconds": 3600 # Expire after 1 hour
86
+ }
87
+ }
88
+ ]
89
+ ```
90
+
91
+ **Note**: `expireAfterSeconds` must be at least 1 second and is required for TTL indexes.
92
+
93
+ ### Partial Indexes
94
+
95
+ Indexes that only index documents matching a filter expression:
96
+
97
+ ```python
98
+ index_definitions = [
99
+ {
100
+ "name": "active_users_idx",
101
+ "type": "partial",
102
+ "keys": {"email": 1},
103
+ "options": {
104
+ "partialFilterExpression": {
105
+ "status": "active"
106
+ }
107
+ }
108
+ }
109
+ ]
110
+ ```
111
+
112
+ ### Text Indexes
113
+
114
+ Full-text search indexes:
115
+
116
+ ```python
117
+ index_definitions = [
118
+ {
119
+ "name": "text_search",
120
+ "type": "text",
121
+ "keys": [
122
+ ("title", "text"),
123
+ ("content", "text"),
124
+ ("tags", "text")
125
+ ],
126
+ "options": {
127
+ "default_language": "english",
128
+ "weights": {
129
+ "title": 10,
130
+ "content": 5,
131
+ "tags": 2
132
+ }
133
+ }
134
+ }
135
+ ]
136
+ ```
137
+
138
+ ### Geospatial Indexes
139
+
140
+ Indexes for geospatial queries (2dsphere, 2d, geoHaystack):
141
+
142
+ ```python
143
+ index_definitions = [
144
+ {
145
+ "name": "location_idx",
146
+ "type": "geospatial",
147
+ "keys": {"location": "2dsphere"}
148
+ },
149
+ {
150
+ "name": "coordinates_idx",
151
+ "type": "geospatial",
152
+ "keys": {"coordinates": "2d"}
153
+ }
154
+ ]
155
+ ```
156
+
157
+ ### Vector Search Indexes
158
+
159
+ Atlas Vector Search indexes for semantic search:
160
+
161
+ ```python
162
+ index_definitions = [
163
+ {
164
+ "name": "vector_search",
165
+ "type": "vector_search",
166
+ "definition": {
167
+ "fields": [{
168
+ "type": "vector",
169
+ "path": "embedding",
170
+ "numDimensions": 1536,
171
+ "similarity": "cosine"
172
+ }]
173
+ }
174
+ }
175
+ ]
176
+ ```
177
+
178
+ ### Atlas Search Indexes
179
+
180
+ Lucene-based full-text search indexes:
181
+
182
+ ```python
183
+ index_definitions = [
184
+ {
185
+ "name": "atlas_search",
186
+ "type": "search",
187
+ "definition": {
188
+ "mappings": {
189
+ "dynamic": False,
190
+ "fields": {
191
+ "title": {
192
+ "type": "string",
193
+ "analyzer": "lucene.standard"
194
+ },
195
+ "content": {
196
+ "type": "string",
197
+ "analyzer": "lucene.english"
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+ ]
204
+ ```
205
+
206
+ ### Hybrid Indexes
207
+
208
+ Combines vector and keyword search:
209
+
210
+ ```python
211
+ index_definitions = [
212
+ {
213
+ "name": "hybrid_search",
214
+ "type": "hybrid",
215
+ "definition": {
216
+ "fields": [{
217
+ "type": "vector",
218
+ "path": "embedding",
219
+ "numDimensions": 1536
220
+ }],
221
+ "mappings": {
222
+ "dynamic": False,
223
+ "fields": {
224
+ "title": {"type": "string"}
225
+ }
226
+ }
227
+ }
228
+ }
229
+ ]
230
+ ```
231
+
232
+ ## Manifest Integration
233
+
234
+ Define indexes in your `manifest.json`:
235
+
236
+ ```json
237
+ {
238
+ "slug": "my_app",
239
+ "collections": {
240
+ "users": {
241
+ "indexes": [
242
+ {
243
+ "name": "email_idx",
244
+ "type": "regular",
245
+ "keys": {"email": 1},
246
+ "unique": true
247
+ },
248
+ {
249
+ "name": "expire_sessions",
250
+ "type": "ttl",
251
+ "keys": {"last_activity": 1},
252
+ "options": {
253
+ "expireAfterSeconds": 3600
254
+ }
255
+ },
256
+ {
257
+ "name": "vector_search",
258
+ "type": "vector_search",
259
+ "definition": {
260
+ "fields": [{
261
+ "type": "vector",
262
+ "path": "embedding",
263
+ "numDimensions": 1536,
264
+ "similarity": "cosine"
265
+ }]
266
+ }
267
+ }
268
+ ]
269
+ }
270
+ }
271
+ }
272
+ ```
273
+
274
+ Indexes are automatically created when you register the app:
275
+
276
+ ```python
277
+ from mdb_engine import MongoDBEngine
278
+
279
+ engine = MongoDBEngine(mongo_uri="...", db_name="...")
280
+ await engine.initialize()
281
+
282
+ manifest = await engine.load_manifest("manifest.json")
283
+ await engine.register_app(manifest) # Indexes created automatically
284
+ ```
285
+
286
+ ## Helper Functions
287
+
288
+ ### Key Normalization
289
+
290
+ Normalize index keys to consistent format:
291
+
292
+ ```python
293
+ from mdb_engine.indexes.helpers import normalize_keys, keys_to_dict
294
+
295
+ # Normalize dict to list of tuples
296
+ keys_dict = {"email": 1, "name": -1}
297
+ keys_list = normalize_keys(keys_dict)
298
+ # Returns: [("email", 1), ("name", -1)]
299
+
300
+ # Convert list to dict
301
+ keys_dict = keys_to_dict(keys_list)
302
+ # Returns: {"email": 1, "name": -1}
303
+ ```
304
+
305
+ ### Index Validation
306
+
307
+ ```python
308
+ from mdb_engine.indexes.helpers import (
309
+ is_id_index,
310
+ validate_index_definition_basic,
311
+ check_and_update_index
312
+ )
313
+
314
+ # Check if index is _id index (MongoDB creates these automatically)
315
+ is_id = is_id_index({"_id": 1}) # Returns True
316
+
317
+ # Validate index definition
318
+ is_valid, error_msg = validate_index_definition_basic(
319
+ index_def={"name": "test", "keys": {"email": 1}},
320
+ index_name="test",
321
+ required_fields=["keys"],
322
+ log_prefix="[my_app]"
323
+ )
324
+
325
+ # Check if index exists and matches
326
+ exists, existing = await check_and_update_index(
327
+ index_manager=index_manager,
328
+ index_name="email_idx",
329
+ expected_keys={"email": 1},
330
+ expected_options={"unique": True}
331
+ )
332
+ ```
333
+
334
+ ## API Reference
335
+
336
+ ### `run_index_creation_for_collection`
337
+
338
+ Main function for creating indexes from definitions:
339
+
340
+ ```python
341
+ await run_index_creation_for_collection(
342
+ db: AsyncIOMotorDatabase,
343
+ slug: str,
344
+ collection_name: str,
345
+ index_definitions: List[Dict[str, Any]]
346
+ )
347
+ ```
348
+
349
+ **Parameters:**
350
+ - `db`: MongoDB database instance
351
+ - `slug`: App slug (for logging)
352
+ - `collection_name`: Name of the collection
353
+ - `index_definitions`: List of index definition dictionaries
354
+
355
+ **Index Definition Format:**
356
+
357
+ ```python
358
+ {
359
+ "name": str, # Index name (required)
360
+ "type": str, # Index type (required)
361
+ "keys": dict | list, # Index keys (required for most types)
362
+ "options": dict, # Index options (optional)
363
+ "definition": dict # Full definition (for vector/search indexes)
364
+ }
365
+ ```
366
+
367
+ ### Helper Functions
368
+
369
+ #### `normalize_keys(keys)`
370
+
371
+ Normalize index keys to list of tuples format.
372
+
373
+ **Parameters:**
374
+ - `keys`: Dict or list of tuples
375
+
376
+ **Returns:** List of (field_name, direction) tuples
377
+
378
+ #### `keys_to_dict(keys)`
379
+
380
+ Convert index keys to dictionary format.
381
+
382
+ **Parameters:**
383
+ - `keys`: Dict or list of tuples
384
+
385
+ **Returns:** Dictionary representation
386
+
387
+ #### `is_id_index(keys)`
388
+
389
+ Check if index keys target the `_id` field.
390
+
391
+ **Parameters:**
392
+ - `keys`: Index keys to check
393
+
394
+ **Returns:** True if this is an `_id` index
395
+
396
+ #### `check_and_update_index(index_manager, index_name, expected_keys, expected_options=None)`
397
+
398
+ Check if index exists and matches expected definition.
399
+
400
+ **Parameters:**
401
+ - `index_manager`: AsyncAtlasIndexManager instance
402
+ - `index_name`: Name of the index
403
+ - `expected_keys`: Expected index keys
404
+ - `expected_options`: Expected index options
405
+
406
+ **Returns:** Tuple of (index_exists, existing_index_dict or None)
407
+
408
+ #### `validate_index_definition_basic(index_def, index_name, required_fields, log_prefix="")`
409
+
410
+ Validate basic index definition structure.
411
+
412
+ **Parameters:**
413
+ - `index_def`: Index definition dictionary
414
+ - `index_name`: Name of the index
415
+ - `required_fields`: List of required field names
416
+ - `log_prefix`: Logging prefix
417
+
418
+ **Returns:** Tuple of (is_valid, error_message)
419
+
420
+ ## Index Definition Examples
421
+
422
+ ### Compound Index
423
+
424
+ ```python
425
+ {
426
+ "name": "user_status_created",
427
+ "type": "regular",
428
+ "keys": {
429
+ "user_id": 1,
430
+ "status": 1,
431
+ "created_at": -1
432
+ },
433
+ "options": {
434
+ "background": True
435
+ }
436
+ }
437
+ ```
438
+
439
+ ### Unique Index with Sparse
440
+
441
+ ```python
442
+ {
443
+ "name": "username_unique",
444
+ "type": "regular",
445
+ "keys": {"username": 1},
446
+ "options": {
447
+ "unique": True,
448
+ "sparse": True # Only index documents with username field
449
+ }
450
+ }
451
+ ```
452
+
453
+ ### TTL Index with Minimum Expiry
454
+
455
+ ```python
456
+ {
457
+ "name": "session_expiry",
458
+ "type": "ttl",
459
+ "keys": {"last_seen": 1},
460
+ "options": {
461
+ "expireAfterSeconds": 86400 # 24 hours (minimum: 1 second)
462
+ }
463
+ }
464
+ ```
465
+
466
+ ### Partial Index for Active Documents
467
+
468
+ ```python
469
+ {
470
+ "name": "active_docs_idx",
471
+ "type": "partial",
472
+ "keys": {"title": 1, "updated_at": -1},
473
+ "options": {
474
+ "partialFilterExpression": {
475
+ "status": {"$in": ["active", "published"]},
476
+ "deleted": False
477
+ }
478
+ }
479
+ }
480
+ ```
481
+
482
+ ### Multi-Field Text Index
483
+
484
+ ```python
485
+ {
486
+ "name": "full_text_search",
487
+ "type": "text",
488
+ "keys": [
489
+ ("title", "text"),
490
+ ("description", "text"),
491
+ ("tags", "text")
492
+ ],
493
+ "options": {
494
+ "default_language": "english",
495
+ "weights": {
496
+ "title": 10,
497
+ "description": 5,
498
+ "tags": 2
499
+ }
500
+ }
501
+ }
502
+ ```
503
+
504
+ ### Vector Search Index
505
+
506
+ ```python
507
+ {
508
+ "name": "embeddings_vector",
509
+ "type": "vector_search",
510
+ "definition": {
511
+ "fields": [{
512
+ "type": "vector",
513
+ "path": "embedding",
514
+ "numDimensions": 1536,
515
+ "similarity": "cosine"
516
+ }]
517
+ }
518
+ }
519
+ ```
520
+
521
+ ### Atlas Search Index
522
+
523
+ ```python
524
+ {
525
+ "name": "atlas_fulltext",
526
+ "type": "search",
527
+ "definition": {
528
+ "mappings": {
529
+ "dynamic": False,
530
+ "fields": {
531
+ "title": {
532
+ "type": "string",
533
+ "analyzer": "lucene.standard"
534
+ },
535
+ "content": {
536
+ "type": "string",
537
+ "analyzer": "lucene.english"
538
+ },
539
+ "tags": {
540
+ "type": "stringFacet"
541
+ }
542
+ }
543
+ }
544
+ }
545
+ }
546
+ ```
547
+
548
+ ## Best Practices
549
+
550
+ 1. **Name indexes descriptively** - Use clear, descriptive names (e.g., `user_email_unique_idx`)
551
+ 2. **Define indexes in manifest** - Centralize index definitions in manifest.json
552
+ 3. **Use compound indexes wisely** - Order fields by selectivity (most selective first)
553
+ 4. **Consider partial indexes** - Use partial indexes to reduce index size
554
+ 5. **Set TTL appropriately** - Use TTL indexes for time-based data expiration
555
+ 6. **Validate definitions** - Use validation functions before creating indexes
556
+ 7. **Monitor index creation** - Check logs for index creation status
557
+ 8. **Use background creation** - Set `background: True` for large collections
558
+ 9. **Test index performance** - Verify indexes improve query performance
559
+ 10. **Document index purpose** - Add comments explaining why each index exists
560
+
561
+ ## Error Handling
562
+
563
+ ```python
564
+ from mdb_engine.indexes import run_index_creation_for_collection
565
+ import logging
566
+
567
+ logger = logging.getLogger(__name__)
568
+
569
+ try:
570
+ await run_index_creation_for_collection(
571
+ db=db,
572
+ slug="my_app",
573
+ collection_name="users",
574
+ index_definitions=index_definitions
575
+ )
576
+ except Exception as e:
577
+ logger.error(f"Failed to create indexes: {e}", exc_info=True)
578
+ raise
579
+ ```
580
+
581
+ ## Integration Examples
582
+
583
+ ### MongoDBEngine Integration
584
+
585
+ Indexes are automatically created when registering apps:
586
+
587
+ ```python
588
+ from mdb_engine import MongoDBEngine
589
+
590
+ engine = MongoDBEngine(mongo_uri="...", db_name="...")
591
+ await engine.initialize()
592
+
593
+ # Load manifest with index definitions
594
+ manifest = await engine.load_manifest("manifest.json")
595
+
596
+ # Register app (indexes created automatically)
597
+ await engine.register_app(manifest)
598
+ ```
599
+
600
+ ### Manual Index Creation
601
+
602
+ Create indexes programmatically:
603
+
604
+ ```python
605
+ from mdb_engine.indexes import run_index_creation_for_collection
606
+
607
+ index_definitions = [
608
+ {
609
+ "name": "email_idx",
610
+ "type": "regular",
611
+ "keys": {"email": 1},
612
+ "unique": True
613
+ }
614
+ ]
615
+
616
+ await run_index_creation_for_collection(
617
+ db=engine.mongo_db,
618
+ slug="my_app",
619
+ collection_name="users",
620
+ index_definitions=index_definitions
621
+ )
622
+ ```
623
+
624
+ ### Multiple Collections
625
+
626
+ Create indexes for multiple collections:
627
+
628
+ ```python
629
+ collections_with_indexes = {
630
+ "users": [
631
+ {"name": "email_idx", "type": "regular", "keys": {"email": 1}, "unique": True}
632
+ ],
633
+ "documents": [
634
+ {"name": "vector_idx", "type": "vector_search", "definition": {...}}
635
+ ]
636
+ }
637
+
638
+ for collection_name, index_definitions in collections_with_indexes.items():
639
+ await run_index_creation_for_collection(
640
+ db=engine.mongo_db,
641
+ slug="my_app",
642
+ collection_name=collection_name,
643
+ index_definitions=index_definitions
644
+ )
645
+ ```
646
+
647
+ ## Related Modules
648
+
649
+ - **`database/`** - AsyncAtlasIndexManager for Atlas indexes
650
+ - **`core/`** - Manifest system and MongoDBEngine
651
+ - **`observability/`** - Logging for index operations
@@ -0,0 +1,21 @@
1
+ """
2
+ Index Management Module
3
+
4
+ Provides index management utilities for MongoDB Atlas Search and regular indexes.
5
+
6
+ This module is part of MDB_ENGINE - MongoDB Engine.
7
+ """
8
+
9
+ # Re-export index managers from database module for convenience
10
+ from ..database.scoped_wrapper import AsyncAtlasIndexManager, AutoIndexManager
11
+ # Export high-level management functions
12
+ from .manager import normalize_json_def, run_index_creation_for_collection
13
+
14
+ __all__ = [
15
+ # Index managers
16
+ "AsyncAtlasIndexManager",
17
+ "AutoIndexManager",
18
+ # Management functions
19
+ "normalize_json_def",
20
+ "run_index_creation_for_collection",
21
+ ]