mdb-engine 0.7.0__py3-none-any.whl → 0.7.2__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/__init__.py CHANGED
@@ -82,19 +82,13 @@ from .repositories import Entity, MongoRepository, Repository, UnitOfWork
82
82
  from .utils import clean_mongo_doc, clean_mongo_docs
83
83
 
84
84
  __version__ = (
85
- "0.6.0" # Secure-by-default WebSocket authentication with encrypted session keys
86
- # - NEW: WebSocket session key generation and management
87
- # - NEW: Envelope encryption for WebSocket session keys
88
- # - NEW: Secure-by-default CSRF protection (csrf_required: true)
89
- # - NEW: WebSocketSessionManager with private collection storage
90
- # - NEW: Session key endpoint (/auth/websocket-session)
91
- # - NEW: Session key integration in login flow
92
- # - ENHANCED: WebSocket authentication with session key support
93
- # - ENHANCED: CSRF middleware session key validation
94
- # - ENHANCED: Multi-app WebSocket routing with session keys
95
- # - BACKWARD COMPATIBLE: Cookie-based authentication fallback
96
- # - UPDATED: All documentation for secure-by-default approach
97
- # - COMPREHENSIVE: Unit and integration tests for session keys
85
+ "0.7.2" # Memory service update functionality
86
+ # - ADDED: Memory service update() method for in-place memory updates
87
+ # - ADDED: Support for updating memory content and metadata while preserving IDs
88
+ # - ADDED: Automatic embedding recomputation via Mem0's update method
89
+ # - ADDED: Comprehensive unit tests for memory update functionality (17 tests)
90
+ # - ENHANCED: Memory service now uses Mem0's native update method exclusively
91
+ # - REMOVED: Direct MongoDB update fallback (simplified implementation)
98
92
  )
99
93
 
100
94
  __all__ = [
mdb_engine/cli/main.py CHANGED
@@ -15,7 +15,7 @@ from .commands.validate import validate
15
15
 
16
16
 
17
17
  @click.group()
18
- @click.version_option(version="0.1.6", prog_name="mdb")
18
+ @click.version_option(version="0.7.2", prog_name="mdb")
19
19
  def cli() -> None:
20
20
  """
21
21
  MDB_ENGINE CLI - Manifest management tool.
mdb_engine/core/engine.py CHANGED
@@ -36,6 +36,11 @@ from typing import TYPE_CHECKING, Any, Optional
36
36
  from motor.motor_asyncio import AsyncIOMotorClient
37
37
  from pymongo.errors import PyMongoError
38
38
 
39
+ try:
40
+ from openai import OpenAIError
41
+ except ImportError:
42
+ OpenAIError = RuntimeError
43
+
39
44
  if TYPE_CHECKING:
40
45
  from fastapi import FastAPI
41
46
 
@@ -2672,7 +2677,7 @@ class MongoDBEngine:
2672
2677
  )
2673
2678
 
2674
2679
  @asynccontextmanager
2675
- async def lifespan(app: FastAPI):
2680
+ async def lifespan(app: FastAPI): # noqa: C901
2676
2681
  """Lifespan context manager for parent app."""
2677
2682
  nonlocal mounted_apps, shared_user_pool_initialized
2678
2683
 
@@ -2911,11 +2916,60 @@ class MongoDBEngine:
2911
2916
  child_app.add_middleware(middleware_class)
2912
2917
  logger.debug(f"Added AppContextMiddleware to child app '{slug}'")
2913
2918
 
2914
- # CRITICAL FIX: Register WebSocket routes on parent app BEFORE mounting
2915
- # This ensures WebSocket routes are checked before mounted app routes
2916
- # Mounted apps create catch-all routes that intercept /app-slug/* paths
2917
2919
  await _register_websocket_routes(app, app_manifest_data, slug, path_prefix)
2918
2920
 
2921
+ memory_config = app_manifest_data.get("memory_config")
2922
+ if memory_config and memory_config.get("enabled", False):
2923
+ if engine._service_initializer: # noqa: SLF001
2924
+ try:
2925
+ await engine._service_initializer.initialize_memory_service( # noqa: SLF001
2926
+ slug, memory_config
2927
+ )
2928
+ logger.info(
2929
+ f"Memory service initialized for mounted app '{slug}' "
2930
+ f"in multi-app context"
2931
+ )
2932
+ except OpenAIError as e:
2933
+ logger.warning(
2934
+ f"Memory service initialization skipped for mounted app "
2935
+ f"'{slug}': OpenAI API error. {e}",
2936
+ extra={"app_slug": slug, "error": str(e)},
2937
+ )
2938
+ except (
2939
+ ImportError,
2940
+ AttributeError,
2941
+ TypeError,
2942
+ ValueError,
2943
+ RuntimeError,
2944
+ ConnectionError,
2945
+ OSError,
2946
+ ) as e:
2947
+ error_msg = str(e).lower()
2948
+ error_type = type(e).__name__
2949
+ is_api_key_error = (
2950
+ "api_key" in error_msg
2951
+ or "api key" in error_msg
2952
+ or "openai" in error_type.lower()
2953
+ )
2954
+ if is_api_key_error:
2955
+ logger.warning(
2956
+ f"Memory service initialization skipped for mounted app "
2957
+ f"'{slug}': Missing API key or configuration. {e}",
2958
+ extra={"app_slug": slug, "error": str(e)},
2959
+ )
2960
+ else:
2961
+ logger.error(
2962
+ f"Failed to initialize memory service for mounted app "
2963
+ f"'{slug}': {e}",
2964
+ exc_info=True,
2965
+ extra={"app_slug": slug, "error": str(e)},
2966
+ )
2967
+ else:
2968
+ logger.warning(
2969
+ f"Memory service requested for '{slug}' but "
2970
+ f"service_initializer is not available"
2971
+ )
2972
+
2919
2973
  # Mount child app at path prefix (AFTER WebSocket routes are registered)
2920
2974
  app.mount(path_prefix, child_app)
2921
2975
 
@@ -26,6 +26,11 @@ from ..observability import get_logger as get_contextual_logger
26
26
  logger = logging.getLogger(__name__)
27
27
  contextual_logger = get_contextual_logger(__name__)
28
28
 
29
+ try:
30
+ from openai import OpenAIError
31
+ except ImportError:
32
+ OpenAIError = RuntimeError
33
+
29
34
 
30
35
  class ServiceInitializer:
31
36
  """
@@ -54,7 +59,9 @@ class ServiceInitializer:
54
59
  self._memory_services: dict[str, Any] = {}
55
60
  self._websocket_configs: dict[str, dict[str, Any]] = {}
56
61
 
57
- async def initialize_memory_service(self, slug: str, memory_config: dict[str, Any]) -> None:
62
+ async def initialize_memory_service(
63
+ self, slug: str, memory_config: dict[str, Any] | None
64
+ ) -> None:
58
65
  """
59
66
  Initialize Mem0 memory service for an app.
60
67
 
@@ -63,8 +70,17 @@ class ServiceInitializer:
63
70
 
64
71
  Args:
65
72
  slug: App slug
66
- memory_config: Memory configuration from manifest (already validated)
73
+ memory_config: Memory configuration from manifest (already validated).
74
+ Can be None or empty dict to skip initialization.
67
75
  """
76
+ # Handle None or empty config
77
+ if not memory_config:
78
+ return
79
+
80
+ # Check if memory is enabled (must be checked before import)
81
+ if not memory_config.get("enabled", False):
82
+ return
83
+
68
84
  # Try to import Memory service (optional dependency)
69
85
  try:
70
86
  from ..memory import Mem0MemoryService, Mem0MemoryServiceError
@@ -145,12 +161,41 @@ class ServiceInitializer:
145
161
  extra={"app_slug": slug, "error": str(e)},
146
162
  exc_info=True,
147
163
  )
148
- except (ImportError, AttributeError, TypeError, ValueError) as e:
149
- contextual_logger.error(
150
- f"Error initializing memory service for app '{slug}': {e}",
164
+ except OpenAIError as e:
165
+ contextual_logger.warning(
166
+ f"Memory service initialization skipped for app '{slug}': "
167
+ f"OpenAI API error. {e}",
151
168
  extra={"app_slug": slug, "error": str(e)},
152
- exc_info=True,
153
169
  )
170
+ except (
171
+ ImportError,
172
+ AttributeError,
173
+ TypeError,
174
+ ValueError,
175
+ RuntimeError,
176
+ ConnectionError,
177
+ OSError,
178
+ ) as e:
179
+ error_msg = str(e).lower()
180
+ error_type = type(e).__name__
181
+ is_api_key_error = (
182
+ "api_key" in error_msg
183
+ or "api key" in error_msg
184
+ or "openai" in error_type.lower()
185
+ or "openai" in error_msg
186
+ )
187
+ if is_api_key_error:
188
+ contextual_logger.warning(
189
+ f"Memory service initialization skipped for app '{slug}': "
190
+ f"Missing API key or configuration. {e}",
191
+ extra={"app_slug": slug, "error": str(e)},
192
+ )
193
+ else:
194
+ contextual_logger.error(
195
+ f"Error initializing memory service for app '{slug}': {e}",
196
+ extra={"app_slug": slug, "error": str(e)},
197
+ exc_info=True,
198
+ )
154
199
 
155
200
  async def register_websockets(self, slug: str, websockets_config: dict[str, Any]) -> None:
156
201
  """
@@ -330,7 +375,18 @@ class ServiceInitializer:
330
375
  extra={"app_slug": slug},
331
376
  )
332
377
  return None
333
- return service
378
+ return service
379
+
380
+ # Service not found - check if it should be initialized but wasn't
381
+ # This can happen in multi-app context if initialization was missed
382
+ # Note: We can't do async initialization here, so we just log a warning
383
+ # The explicit initialization in create_multi_app should handle this
384
+ contextual_logger.debug(
385
+ f"Memory service not found for '{slug}' - "
386
+ f"it may not be initialized yet or memory is disabled",
387
+ extra={"app_slug": slug},
388
+ )
389
+ return None
334
390
  except (KeyError, AttributeError, TypeError) as e:
335
391
  contextual_logger.error(
336
392
  f"Error retrieving memory service for '{slug}': {e}",
@@ -181,18 +181,49 @@ memories = await memory_service.get_all(
181
181
 
182
182
  ### Update Memory
183
183
 
184
- Update existing memories:
184
+ Update existing memories in-place while preserving the original memory ID and creation timestamp:
185
185
 
186
186
  ```python
187
- # Update memory
188
- updated = await memory_service.update(
187
+ # Update memory content and metadata
188
+ updated = memory_service.update(
189
+ memory_id="memory_123",
190
+ user_id="user123",
191
+ memory="Updated memory content",
192
+ metadata={"updated": True, "category": "technical"}
193
+ )
194
+
195
+ # Update using messages format
196
+ updated = memory_service.update(
189
197
  memory_id="memory_123",
190
198
  user_id="user123",
191
199
  messages=[{"role": "user", "content": "Updated content"}],
192
200
  metadata={"updated": True}
193
201
  )
202
+
203
+ # Update only metadata (content unchanged)
204
+ updated = memory_service.update(
205
+ memory_id="memory_123",
206
+ user_id="user123",
207
+ metadata={"category": "updated"}
208
+ )
209
+
210
+ # Backward compatibility: using 'data' parameter
211
+ updated = memory_service.update(
212
+ memory_id="memory_123",
213
+ user_id="user123",
214
+ data="Updated content",
215
+ metadata={"updated": True}
216
+ )
194
217
  ```
195
218
 
219
+ **Key Features:**
220
+ - **Preserves Memory ID**: The original memory ID is maintained
221
+ - **Preserves Creation Timestamp**: `created_at` is not modified
222
+ - **Updates Timestamp**: `updated_at` is automatically set to current time
223
+ - **Recomputes Embeddings**: If content changes, the embedding vector is automatically recomputed
224
+ - **Metadata Merging**: New metadata is merged with existing metadata (doesn't replace)
225
+ - **Partial Updates**: Can update content only, metadata only, or both
226
+
196
227
  ### Delete Memory
197
228
 
198
229
  Remove memories:
@@ -44,6 +44,20 @@ class Mem0MemoryServiceError(Exception):
44
44
 
45
45
 
46
46
  class Mem0MemoryService:
47
+ """
48
+ Production-ready Mem0 Memory Service with MongoDB integration.
49
+
50
+ Features:
51
+ - In-place memory updates preserving IDs and timestamps
52
+ - Automatic embedding recomputation on content changes
53
+ - Knowledge graph support (if enabled in Mem0 config)
54
+ - Comprehensive error handling and logging
55
+ - Backward compatibility with existing code
56
+
57
+ All operations go through Mem0's API to ensure proper state management,
58
+ graph updates, and relationship handling.
59
+ """
60
+
47
61
  def __init__(
48
62
  self,
49
63
  mongo_uri: str,
@@ -54,6 +68,9 @@ class Mem0MemoryService:
54
68
  if not _check_mem0_available():
55
69
  raise Mem0MemoryServiceError("Mem0 not installed. pip install mem0ai")
56
70
 
71
+ if not mongo_uri or not db_name or not app_slug:
72
+ raise Mem0MemoryServiceError("mongo_uri, db_name, and app_slug are required parameters")
73
+
57
74
  self.mongo_uri = mongo_uri
58
75
  self.db_name = db_name
59
76
  self.app_slug = app_slug
@@ -461,6 +478,273 @@ class Mem0MemoryService:
461
478
  ):
462
479
  return False
463
480
 
481
+ def update(
482
+ self,
483
+ memory_id: str,
484
+ user_id: str | None = None,
485
+ memory: str | None = None,
486
+ data: str | dict[str, Any] | None = None,
487
+ messages: str | list[dict[str, str]] | None = None,
488
+ metadata: dict[str, Any] | None = None,
489
+ **kwargs,
490
+ ) -> dict[str, Any] | None:
491
+ """
492
+ Update an existing memory in-place with production-grade error handling.
493
+
494
+ Updates the memory content and/or metadata while preserving:
495
+ - Original memory ID (never changes)
496
+ - Creation timestamp (created_at) - preserved
497
+ - Other existing fields - preserved unless explicitly updated
498
+
499
+ If content is updated, the embedding vector is automatically recomputed.
500
+
501
+ Args:
502
+ memory_id: The ID of the memory to update (required)
503
+ user_id: The user ID who owns the memory (for scoping and security)
504
+ memory: New memory content as a string (optional)
505
+ data: Alternative parameter name for memory content (backward compatibility).
506
+ Can be a string or dict with 'memory'/'text'/'content' key.
507
+ messages: Alternative way to provide content as messages (optional).
508
+ Can be a string or list of dicts with 'content' key.
509
+ metadata: Metadata updates to merge with existing metadata (optional).
510
+ Merged, not replaced - existing keys are preserved unless overridden.
511
+ **kwargs: Additional arguments passed to Mem0 operations
512
+
513
+ Returns:
514
+ Updated memory object with same ID, or None if memory not found
515
+
516
+ Raises:
517
+ Mem0MemoryServiceError: If update operation fails
518
+ ValueError: If memory_id is invalid or empty
519
+
520
+ Example:
521
+ ```python
522
+ # Update content and metadata
523
+ updated = memory_service.update(
524
+ memory_id="04f78986-dfad-46fe-8381-034bbee9a2fc",
525
+ user_id="user123",
526
+ memory="I love Python programming",
527
+ metadata={"category": "technical", "updated": True}
528
+ )
529
+
530
+ # Update only metadata (content unchanged)
531
+ updated = memory_service.update(
532
+ memory_id="04f78986-dfad-46fe-8381-034bbee9a2fc",
533
+ user_id="user123",
534
+ metadata={"category": "updated"}
535
+ )
536
+ ```
537
+ """
538
+ # Input validation
539
+ if not memory_id or not isinstance(memory_id, str) or not memory_id.strip():
540
+ raise ValueError("memory_id is required and must be a non-empty string")
541
+
542
+ try:
543
+ # Normalize data parameter (backward compatibility)
544
+ normalized_memory = self._normalize_content_input(memory, data, messages)
545
+ normalized_metadata = self._normalize_metadata_input(metadata, data)
546
+
547
+ # Verify memory exists before attempting update
548
+ existing_memory = self.get(memory_id=memory_id, user_id=user_id, **kwargs)
549
+ if not existing_memory:
550
+ logger.warning(
551
+ f"Memory {memory_id} not found for update",
552
+ extra={"memory_id": memory_id, "user_id": user_id},
553
+ )
554
+ return None
555
+
556
+ # Use Mem0's built-in update method
557
+ # Mem0's Memory class update method handles:
558
+ # - In-place updates preserving memory ID
559
+ # - Automatic embedding recomputation
560
+ # - Metadata merging
561
+ # - User scoping
562
+ # - Knowledge graph updates (if enabled)
563
+ # - Relationship management
564
+ if not hasattr(self.memory, "update") or not callable(self.memory.update):
565
+ raise Mem0MemoryServiceError(
566
+ "Mem0 update method not available. "
567
+ "Please ensure you're using a compatible version of mem0ai "
568
+ "that supports updates. Install with: pip install --upgrade mem0ai"
569
+ )
570
+
571
+ result = self._update_via_mem0(
572
+ memory_id=memory_id,
573
+ user_id=user_id,
574
+ memory=normalized_memory,
575
+ metadata=normalized_metadata,
576
+ **kwargs,
577
+ )
578
+
579
+ if result is None:
580
+ logger.warning(
581
+ f"Mem0 update returned None for memory {memory_id}",
582
+ extra={"memory_id": memory_id, "user_id": user_id},
583
+ )
584
+ return None
585
+
586
+ logger.info(
587
+ f"Successfully updated memory {memory_id} using Mem0 update method",
588
+ extra={
589
+ "memory_id": memory_id,
590
+ "content_updated": bool(normalized_memory),
591
+ "metadata_updated": bool(normalized_metadata),
592
+ },
593
+ )
594
+ return result
595
+
596
+ except ValueError:
597
+ # Re-raise validation errors as-is
598
+ raise
599
+ except (AttributeError, TypeError, ValueError, KeyError) as e:
600
+ logger.exception(
601
+ f"Error updating memory {memory_id}",
602
+ extra={"memory_id": memory_id, "user_id": user_id},
603
+ )
604
+ raise Mem0MemoryServiceError(f"Update failed: {e}") from e
605
+
606
+ def _normalize_content_input(
607
+ self,
608
+ memory: str | None,
609
+ data: str | dict[str, Any] | None,
610
+ messages: str | list[dict[str, str]] | None,
611
+ ) -> str | None:
612
+ """
613
+ Normalize content input from various parameter formats.
614
+
615
+ Priority: memory > data > messages
616
+ """
617
+ # Already have memory content
618
+ if memory:
619
+ if not isinstance(memory, str):
620
+ raise TypeError("memory parameter must be a string")
621
+ return memory.strip() if memory.strip() else None
622
+
623
+ # Check data parameter
624
+ if data:
625
+ if isinstance(data, str):
626
+ return data.strip() if data.strip() else None
627
+ elif isinstance(data, dict):
628
+ content = data.get("memory") or data.get("text") or data.get("content")
629
+ if content and isinstance(content, str):
630
+ return content.strip() if content.strip() else None
631
+
632
+ # Check messages parameter
633
+ if messages:
634
+ if isinstance(messages, str):
635
+ return messages.strip() if messages.strip() else None
636
+ elif isinstance(messages, list):
637
+ content_parts = []
638
+ for msg in messages:
639
+ if isinstance(msg, dict) and "content" in msg:
640
+ content = msg["content"]
641
+ if isinstance(content, str) and content.strip():
642
+ content_parts.append(content.strip())
643
+ if content_parts:
644
+ return " ".join(content_parts)
645
+
646
+ return None
647
+
648
+ def _normalize_metadata_input(
649
+ self, metadata: dict[str, Any] | None, data: dict[str, Any] | None
650
+ ) -> dict[str, Any] | None:
651
+ """Normalize metadata input, extracting from data dict if needed."""
652
+ if metadata is not None and not isinstance(metadata, dict):
653
+ raise TypeError("metadata must be a dict or None")
654
+
655
+ # If metadata provided directly, use it
656
+ if metadata is not None:
657
+ return metadata
658
+
659
+ # Check if metadata is in data dict
660
+ if isinstance(data, dict) and "metadata" in data:
661
+ data_metadata = data.get("metadata")
662
+ if isinstance(data_metadata, dict):
663
+ return data_metadata
664
+
665
+ return None
666
+
667
+ def _update_via_mem0(
668
+ self,
669
+ memory_id: str,
670
+ user_id: str | None,
671
+ memory: str | None,
672
+ metadata: dict[str, Any] | None,
673
+ **kwargs,
674
+ ) -> dict[str, Any] | None:
675
+ """
676
+ Update memory using Mem0's built-in update method.
677
+
678
+ This is the primary update path. Mem0's update method handles:
679
+ - In-place updates preserving memory ID and created_at timestamp
680
+ - Automatic embedding recomputation when content changes
681
+ - Metadata merging
682
+ - User scoping for security
683
+
684
+ Args:
685
+ memory_id: Memory ID to update
686
+ user_id: User ID for scoping
687
+ memory: New memory content (normalized)
688
+ metadata: Metadata to merge (normalized)
689
+ **kwargs: Additional arguments passed to Mem0
690
+
691
+ Returns:
692
+ Updated memory dict or None if not found
693
+
694
+ Raises:
695
+ Various exceptions from Mem0 if update fails
696
+ """
697
+ # Build update parameters matching Mem0's API
698
+ # Mem0's update method signature:
699
+ # update(memory_id, text=None, metadata=None, user_id=None, **kwargs)
700
+ update_kwargs: dict[str, Any] = {"memory_id": memory_id}
701
+
702
+ # Add user_id for scoping (Mem0 supports this)
703
+ if user_id:
704
+ update_kwargs["user_id"] = str(user_id)
705
+
706
+ # Add text/content if provided
707
+ # Mem0 uses "text" parameter for content
708
+ if memory:
709
+ update_kwargs["text"] = memory
710
+
711
+ # Add metadata if provided
712
+ # Mem0 merges metadata automatically
713
+ if metadata is not None:
714
+ update_kwargs["metadata"] = metadata
715
+
716
+ # Pass through any additional kwargs
717
+ update_kwargs.update(kwargs)
718
+
719
+ logger.debug(
720
+ f"Calling mem0.update() for memory_id={memory_id}",
721
+ extra={
722
+ "memory_id": memory_id,
723
+ "has_content": bool(memory),
724
+ "has_metadata": bool(metadata),
725
+ "user_id": user_id,
726
+ },
727
+ )
728
+
729
+ # Call Mem0's update method directly
730
+ # This handles all the complexity: embedding recomputation, ID preservation, etc.
731
+ result = self.memory.update(**update_kwargs)
732
+
733
+ # Normalize result format
734
+ # Mem0 may return dict, list, or other formats
735
+ if isinstance(result, dict):
736
+ return result
737
+ elif isinstance(result, list) and len(result) > 0:
738
+ # If list, return first item
739
+ return result[0] if isinstance(result[0], dict) else None
740
+ else:
741
+ # If result is None or unexpected format, return None to trigger fallback
742
+ logger.debug(
743
+ f"Mem0 update returned unexpected format: {type(result)}",
744
+ extra={"memory_id": memory_id},
745
+ )
746
+ return None
747
+
464
748
  def _normalize_result(self, result: Any) -> list[dict[str, Any]]:
465
749
  """Normalize Mem0's return type (dict vs list)."""
466
750
  if result is None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mdb-engine
3
- Version: 0.7.0
3
+ Version: 0.7.2
4
4
  Summary: MongoDB Engine
5
5
  Home-page: https://github.com/ranfysvalle02/mdb-engine
6
6
  Author: Fabian Valle
@@ -1,5 +1,5 @@
1
1
  mdb_engine/README.md,sha256=T3EFGcPopY9LslYW3lxgG3hohWkAOmBNbYG0FDMUJiY,3502
2
- mdb_engine/__init__.py,sha256=vishQ3BF6oGQOmAsrMG1UJ-5C-3FNM49JSHC35MhH0k,3937
2
+ mdb_engine/__init__.py,sha256=12PLLmXDANoV30dDxw5To9taKAZnIMolRoV1Vwdjkwk,3618
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
@@ -35,7 +35,7 @@ mdb_engine/auth/utils.py,sha256=YkexCo0xV37mpOJUI32cntRHVOUUS7r19TIMPWHcgpA,2734
35
35
  mdb_engine/auth/websocket_sessions.py,sha256=7eFNagY2K3Rp1x7d_cO5JcpT-DrYkc__cmVhl6pAC2M,15081
36
36
  mdb_engine/auth/websocket_tickets.py,sha256=VoIArcnQBtYqXRMs-5m7NSvCJB1dEeHrLl7j7yG-H-A,9887
37
37
  mdb_engine/cli/__init__.py,sha256=PANRi4THmL34d1mawlqxIrnuItXMdqoMTq5Z1zHd7rM,301
38
- mdb_engine/cli/main.py,sha256=Y5ELFhvsr8zxFWv4WScOGNHiLUTdSXAJeUFLpRXCelg,811
38
+ mdb_engine/cli/main.py,sha256=cp-fxcijZN4o4taBTP2sR57Y1A-ZId0Qga7AhgrU48o,811
39
39
  mdb_engine/cli/utils.py,sha256=bNRGJgdzxUjXAOVe1aoxWJ5M_IqtAE-eW4pfAkwiDDM,2760
40
40
  mdb_engine/cli/commands/__init__.py,sha256=ZSzMhKdV9ILD5EbOSxDV9nURHo1e4bQ0c8AWpqsTEqM,115
41
41
  mdb_engine/cli/commands/generate.py,sha256=VEcn7qNQkIPQlLEK3oXUBgYMwD-G0FyomXQcWTtKsbs,17304
@@ -48,12 +48,12 @@ mdb_engine/core/app_registration.py,sha256=w7wjrlNQsEekuDQkG6HM4Z5t00E65baEzncnh
48
48
  mdb_engine/core/app_secrets.py,sha256=bo-syg9UUATibNyXEZs-0TTYWG-JaY-2S0yNSGA12n0,10524
49
49
  mdb_engine/core/connection.py,sha256=XnwuPG34pJ7kJGJ84T0mhj1UZ6_CLz_9qZf6NRYGIS8,8346
50
50
  mdb_engine/core/encryption.py,sha256=RZ5LPF5g28E3ZBn6v1IMw_oas7u9YGFtBcEj8lTi9LM,7515
51
- mdb_engine/core/engine.py,sha256=RBXJUYRbXrt4rhQLSxcRF-FYzf-ZxN9j358sdlw4_pc,182475
51
+ mdb_engine/core/engine.py,sha256=wSJ99FP3NRUejGCXliwi9fW_pVZPpLjdUMG8FsU5Kms,185252
52
52
  mdb_engine/core/index_management.py,sha256=9-r7MIy3JnjQ35sGqsbj8K_I07vAUWtAVgSWC99lJcE,5555
53
53
  mdb_engine/core/manifest.py,sha256=D3OGRjm1It8dmS3IMoxHckHUerhs5PtcQgPz8o5ZL9w,140785
54
54
  mdb_engine/core/ray_integration.py,sha256=csAgICl2g7Plqy4N49MJU1Ca-lr8KZznAouXMMRwhG8,13706
55
55
  mdb_engine/core/seeding.py,sha256=c5IhdwlqUf_4Q5FFTAhPLaHPaUr_Txo3z_DUwZmWsFs,6421
56
- mdb_engine/core/service_initialization.py,sha256=rtb6BaPvFqomwT_s7bdbbvqi5m74llT0LkJFEhVG9Gg,12996
56
+ mdb_engine/core/service_initialization.py,sha256=N4varRswExBYahAgPfcPtNhqszOjm0JQ0u7r7mfFyqM,15018
57
57
  mdb_engine/core/types.py,sha256=u0LDGE4A3txGDlc9PNoQX8jwVYFjJSw4K5LDnpatsNc,11254
58
58
  mdb_engine/database/README.md,sha256=-31mVxBeVQaYsF3AD1-gQbD2NCYVcPjdFoA6sZ6b02Y,19354
59
59
  mdb_engine/database/__init__.py,sha256=rrc3eZFli3K2zrvVdDbMBi8YkmoHYzP6JNT0AUBE5VU,981
@@ -74,9 +74,9 @@ mdb_engine/indexes/README.md,sha256=r7duq-1vtqHhBk1cwoBMYYh_dfTzxiaQaPE3mLB_3JQ,
74
74
  mdb_engine/indexes/__init__.py,sha256=9QFJ6qo_yD26dZcKyKjj-hhesFpaomBt-mWTtYTQvqc,613
75
75
  mdb_engine/indexes/helpers.py,sha256=tJHqDm18jKLrW-P2ofmnUnaf4_-V5xDLjqP_WU8W9MM,4190
76
76
  mdb_engine/indexes/manager.py,sha256=ekrYBfKD-GOBpZMjXIZWSQ7UPLgrD5BINYzVteWkSI8,32508
77
- mdb_engine/memory/README.md,sha256=uOE4SnPyq8TdoxGrttof5fSj2KSqnrgzUorMCV_1wg0,13624
77
+ mdb_engine/memory/README.md,sha256=Xa7pYut4zgZyRcb2TALcucMVAHCAu9uNGBKSwE7stY8,14764
78
78
  mdb_engine/memory/__init__.py,sha256=e4kAYgxd_-WAH8GovTwjEBO9hvASu_kXEupMgksAL-U,1008
79
- mdb_engine/memory/service.py,sha256=l2bkKVN9AyUjO9K9ykb5BK9dZjs3ns78FJLOD5LajsY,18454
79
+ mdb_engine/memory/service.py,sha256=QWMNZfMaS3-SPZZswnO410C4-3ibAOUw0LH93WjZLsM,29550
80
80
  mdb_engine/observability/README.md,sha256=CMgQaC1H8ESmCitfbhJifz6-XoXH_FPNE4MvuZ-oFas,13085
81
81
  mdb_engine/observability/__init__.py,sha256=jjLsrW6Gy2ayrbfLrgHsDB61NxWWkYLHwv0q-N3fxjA,1213
82
82
  mdb_engine/observability/health.py,sha256=ORjxF_rHYA9vCoxUqel5p0n9g3PLmHsHQn68Q402b6g,9212
@@ -91,9 +91,9 @@ mdb_engine/routing/__init__.py,sha256=reupjHi_RTc2ZBA4AH5XzobAmqy4EQIsfSUcTkFknU
91
91
  mdb_engine/routing/websockets.py,sha256=jgdLsrSOKyBiY4yzE7XYXV1MOChLw2CIWpT6RDL23hk,51649
92
92
  mdb_engine/utils/__init__.py,sha256=lDxQSGqkV4fVw5TWIk6FA6_eey_ZnEtMY0fir3cpAe8,236
93
93
  mdb_engine/utils/mongo.py,sha256=Oqtv4tQdpiiZzrilGLEYQPo8Vmh8WsTQypxQs8Of53s,3369
94
- mdb_engine-0.7.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
95
- mdb_engine-0.7.0.dist-info/METADATA,sha256=dSWF8HOigw-49yf_VBLhr0hA--LKqroswl9uu3MmQik,19695
96
- mdb_engine-0.7.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
97
- mdb_engine-0.7.0.dist-info/entry_points.txt,sha256=INCbYdFbBzJalwPwxliEzLmPfR57IvQ7RAXG_pn8cL8,48
98
- mdb_engine-0.7.0.dist-info/top_level.txt,sha256=PH0UEBwTtgkm2vWvC9He_EOMn7hVn_Wg_Jyc0SmeO8k,11
99
- mdb_engine-0.7.0.dist-info/RECORD,,
94
+ mdb_engine-0.7.2.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
95
+ mdb_engine-0.7.2.dist-info/METADATA,sha256=NkjWW4qrAnJs_T4NxvCvQvZkln4vRYSRa101sBbsXY4,19695
96
+ mdb_engine-0.7.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
97
+ mdb_engine-0.7.2.dist-info/entry_points.txt,sha256=INCbYdFbBzJalwPwxliEzLmPfR57IvQ7RAXG_pn8cL8,48
98
+ mdb_engine-0.7.2.dist-info/top_level.txt,sha256=PH0UEBwTtgkm2vWvC9He_EOMn7hVn_Wg_Jyc0SmeO8k,11
99
+ mdb_engine-0.7.2.dist-info/RECORD,,