mdb-engine 0.2.1__py3-none-any.whl → 0.2.4__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 (70) hide show
  1. mdb_engine/__init__.py +7 -1
  2. mdb_engine/auth/README.md +6 -0
  3. mdb_engine/auth/audit.py +40 -40
  4. mdb_engine/auth/base.py +3 -3
  5. mdb_engine/auth/casbin_factory.py +6 -6
  6. mdb_engine/auth/config_defaults.py +5 -5
  7. mdb_engine/auth/config_helpers.py +12 -12
  8. mdb_engine/auth/cookie_utils.py +9 -9
  9. mdb_engine/auth/csrf.py +9 -8
  10. mdb_engine/auth/decorators.py +7 -6
  11. mdb_engine/auth/dependencies.py +22 -21
  12. mdb_engine/auth/integration.py +9 -9
  13. mdb_engine/auth/jwt.py +9 -9
  14. mdb_engine/auth/middleware.py +4 -3
  15. mdb_engine/auth/oso_factory.py +6 -6
  16. mdb_engine/auth/provider.py +4 -4
  17. mdb_engine/auth/rate_limiter.py +12 -11
  18. mdb_engine/auth/restrictions.py +16 -15
  19. mdb_engine/auth/session_manager.py +11 -13
  20. mdb_engine/auth/shared_middleware.py +344 -132
  21. mdb_engine/auth/shared_users.py +20 -20
  22. mdb_engine/auth/token_lifecycle.py +10 -12
  23. mdb_engine/auth/token_store.py +4 -5
  24. mdb_engine/auth/users.py +51 -52
  25. mdb_engine/auth/utils.py +29 -33
  26. mdb_engine/cli/commands/generate.py +6 -6
  27. mdb_engine/cli/utils.py +4 -4
  28. mdb_engine/config.py +6 -7
  29. mdb_engine/core/app_registration.py +12 -12
  30. mdb_engine/core/app_secrets.py +1 -2
  31. mdb_engine/core/connection.py +3 -4
  32. mdb_engine/core/encryption.py +1 -2
  33. mdb_engine/core/engine.py +43 -44
  34. mdb_engine/core/manifest.py +80 -58
  35. mdb_engine/core/ray_integration.py +10 -9
  36. mdb_engine/core/seeding.py +3 -3
  37. mdb_engine/core/service_initialization.py +10 -9
  38. mdb_engine/core/types.py +40 -40
  39. mdb_engine/database/abstraction.py +15 -16
  40. mdb_engine/database/connection.py +40 -12
  41. mdb_engine/database/query_validator.py +8 -8
  42. mdb_engine/database/resource_limiter.py +7 -7
  43. mdb_engine/database/scoped_wrapper.py +51 -58
  44. mdb_engine/dependencies.py +14 -13
  45. mdb_engine/di/container.py +12 -13
  46. mdb_engine/di/providers.py +14 -13
  47. mdb_engine/di/scopes.py +5 -5
  48. mdb_engine/embeddings/dependencies.py +2 -2
  49. mdb_engine/embeddings/service.py +67 -50
  50. mdb_engine/exceptions.py +20 -20
  51. mdb_engine/indexes/helpers.py +11 -11
  52. mdb_engine/indexes/manager.py +9 -9
  53. mdb_engine/memory/README.md +93 -2
  54. mdb_engine/memory/service.py +361 -1109
  55. mdb_engine/observability/health.py +10 -9
  56. mdb_engine/observability/logging.py +10 -10
  57. mdb_engine/observability/metrics.py +8 -7
  58. mdb_engine/repositories/base.py +25 -25
  59. mdb_engine/repositories/mongo.py +17 -17
  60. mdb_engine/repositories/unit_of_work.py +6 -6
  61. mdb_engine/routing/websockets.py +19 -18
  62. mdb_engine/utils/__init__.py +3 -1
  63. mdb_engine/utils/mongo.py +117 -0
  64. {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.4.dist-info}/METADATA +88 -13
  65. mdb_engine-0.2.4.dist-info/RECORD +97 -0
  66. {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.4.dist-info}/WHEEL +1 -1
  67. mdb_engine-0.2.1.dist-info/RECORD +0 -96
  68. {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.4.dist-info}/entry_points.txt +0 -0
  69. {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.4.dist-info}/licenses/LICENSE +0 -0
  70. {mdb_engine-0.2.1.dist-info → mdb_engine-0.2.4.dist-info}/top_level.txt +0 -0
@@ -17,7 +17,7 @@ This module is part of MDB_ENGINE - MongoDB Engine.
17
17
 
18
18
  import json
19
19
  from pathlib import Path
20
- from typing import Any, Dict, List, Optional
20
+ from typing import Any
21
21
 
22
22
  import click
23
23
 
@@ -210,7 +210,7 @@ class AppGenerator:
210
210
  output_dir: Path = Path("."),
211
211
  multi_site: bool = False,
212
212
  enable_ray: bool = False,
213
- read_scopes: Optional[List[str]] = None,
213
+ read_scopes: list[str] | None = None,
214
214
  ) -> Path:
215
215
  """
216
216
  Generate a new app with proper structure.
@@ -283,10 +283,10 @@ class AppGenerator:
283
283
  description: str,
284
284
  multi_site: bool,
285
285
  enable_ray: bool,
286
- read_scopes: List[str],
287
- ) -> Dict[str, Any]:
286
+ read_scopes: list[str],
287
+ ) -> dict[str, Any]:
288
288
  """Generate manifest.json content."""
289
- manifest: Dict[str, Any] = {
289
+ manifest: dict[str, Any] = {
290
290
  "schema_version": CURRENT_SCHEMA_VERSION,
291
291
  "slug": app_slug,
292
292
  "name": app_name,
@@ -476,7 +476,7 @@ def generate_manifest(
476
476
  )
477
477
 
478
478
  # Generate template manifest
479
- manifest: Dict[str, Any] = {
479
+ manifest: dict[str, Any] = {
480
480
  "schema_version": CURRENT_SCHEMA_VERSION,
481
481
  "slug": slug,
482
482
  "name": name,
mdb_engine/cli/utils.py CHANGED
@@ -8,12 +8,12 @@ This module is part of MDB_ENGINE - MongoDB Engine.
8
8
 
9
9
  import json
10
10
  from pathlib import Path
11
- from typing import Any, Dict
11
+ from typing import Any
12
12
 
13
13
  import click
14
14
 
15
15
 
16
- def load_manifest_file(file_path: Path) -> Dict[str, Any]:
16
+ def load_manifest_file(file_path: Path) -> dict[str, Any]:
17
17
  """
18
18
  Load a manifest JSON file.
19
19
 
@@ -36,7 +36,7 @@ def load_manifest_file(file_path: Path) -> Dict[str, Any]:
36
36
  raise click.ClickException(f"Invalid JSON in manifest file: {e}") from e
37
37
 
38
38
 
39
- def save_manifest_file(file_path: Path, manifest: Dict[str, Any]) -> None:
39
+ def save_manifest_file(file_path: Path, manifest: dict[str, Any]) -> None:
40
40
  """
41
41
  Save a manifest dictionary to a JSON file.
42
42
 
@@ -54,7 +54,7 @@ def save_manifest_file(file_path: Path, manifest: Dict[str, Any]) -> None:
54
54
  raise click.ClickException(f"Failed to write manifest file: {e}") from e
55
55
 
56
56
 
57
- def format_manifest_output(manifest: Dict[str, Any], format_type: str) -> str:
57
+ def format_manifest_output(manifest: dict[str, Any], format_type: str) -> str:
58
58
  """
59
59
  Format manifest for output.
60
60
 
mdb_engine/config.py CHANGED
@@ -7,7 +7,6 @@ with direct parameters as before.
7
7
  """
8
8
 
9
9
  import os
10
- from typing import Optional
11
10
 
12
11
  try:
13
12
  from pydantic import BaseSettings, Field
@@ -46,12 +45,12 @@ class EngineConfig:
46
45
 
47
46
  def __init__(
48
47
  self,
49
- mongo_uri: Optional[str] = None,
50
- db_name: Optional[str] = None,
51
- max_pool_size: Optional[int] = None,
52
- min_pool_size: Optional[int] = None,
53
- server_selection_timeout_ms: Optional[int] = None,
54
- authz_cache_ttl: Optional[int] = None,
48
+ mongo_uri: str | None = None,
49
+ db_name: str | None = None,
50
+ max_pool_size: int | None = None,
51
+ min_pool_size: int | None = None,
52
+ server_selection_timeout_ms: int | None = None,
53
+ authz_cache_ttl: int | None = None,
55
54
  ):
56
55
  """
57
56
  Initialize configuration.
@@ -10,8 +10,9 @@ This module is part of MDB_ENGINE - MongoDB Engine.
10
10
  import asyncio
11
11
  import logging
12
12
  import time
13
+ from collections.abc import Callable
13
14
  from pathlib import Path
14
- from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple
15
+ from typing import TYPE_CHECKING, Any, Optional
15
16
 
16
17
  from jsonschema import SchemaError
17
18
  from jsonschema import ValidationError as JsonSchemaValidationError
@@ -58,11 +59,11 @@ class AppRegistrationManager:
58
59
  self._mongo_db = mongo_db
59
60
  self.manifest_validator = manifest_validator
60
61
  self.manifest_parser = manifest_parser
61
- self._apps: Dict[str, Dict[str, Any]] = {}
62
+ self._apps: dict[str, dict[str, Any]] = {}
62
63
 
63
64
  async def validate_manifest(
64
65
  self, manifest: "ManifestDict"
65
- ) -> Tuple[bool, Optional[str], Optional[List[str]]]:
66
+ ) -> tuple[bool, str | None, list[str] | None]:
66
67
  """
67
68
  Validate a manifest against the schema.
68
69
 
@@ -115,13 +116,12 @@ class AppRegistrationManager:
115
116
  async def register_app(
116
117
  self,
117
118
  manifest: "ManifestDict",
118
- create_indexes_callback: Optional[Callable[[str, "ManifestDict"], Any]] = None,
119
- seed_data_callback: Optional[Callable[[str, Dict[str, List[Dict[str, Any]]]], Any]] = None,
120
- initialize_memory_callback: Optional[Callable[[str, Dict[str, Any]], Any]] = None,
121
- register_websockets_callback: Optional[Callable[[str, Dict[str, Any]], Any]] = None,
122
- setup_observability_callback: Optional[
123
- Callable[[str, "ManifestDict", Dict[str, Any]], Any]
124
- ] = None,
119
+ create_indexes_callback: Callable[[str, "ManifestDict"], Any] | None = None,
120
+ seed_data_callback: Callable[[str, dict[str, list[dict[str, Any]]]], Any] | None = None,
121
+ initialize_memory_callback: Callable[[str, dict[str, Any]], Any] | None = None,
122
+ register_websockets_callback: Callable[[str, dict[str, Any]], Any] | None = None,
123
+ setup_observability_callback: Callable[[str, "ManifestDict", dict[str, Any]], Any]
124
+ | None = None,
125
125
  ) -> bool:
126
126
  """
127
127
  Register an app from its manifest.
@@ -142,7 +142,7 @@ class AppRegistrationManager:
142
142
  """
143
143
  start_time = time.time()
144
144
 
145
- slug: Optional[str] = manifest.get("slug")
145
+ slug: str | None = manifest.get("slug")
146
146
  if not slug:
147
147
  contextual_logger.error(
148
148
  "Cannot register app: missing 'slug' in manifest",
@@ -359,7 +359,7 @@ class AppRegistrationManager:
359
359
  """
360
360
  return self._apps.get(slug)
361
361
 
362
- def list_apps(self) -> List[str]:
362
+ def list_apps(self) -> list[str]:
363
363
  """
364
364
  List all registered app slugs.
365
365
 
@@ -13,7 +13,6 @@ import base64
13
13
  import logging
14
14
  import secrets
15
15
  from datetime import datetime
16
- from typing import Optional
17
16
 
18
17
  from motor.motor_asyncio import AsyncIOMotorDatabase
19
18
  from pymongo.errors import OperationFailure, PyMongoError
@@ -188,7 +187,7 @@ class AppSecretsManager:
188
187
  logger.warning(f"Secret verification failed for app '{app_slug}'")
189
188
  return result
190
189
 
191
- async def get_app_secret(self, app_slug: str) -> Optional[str]:
190
+ async def get_app_secret(self, app_slug: str) -> str | None:
192
191
  """
193
192
  Get decrypted app secret (for rotation purposes only).
194
193
 
@@ -9,7 +9,6 @@ This module is part of MDB_ENGINE - MongoDB Engine.
9
9
 
10
10
  import logging
11
11
  import time
12
- from typing import Optional
13
12
 
14
13
  from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase
15
14
  from pymongo.errors import ConnectionFailure, ServerSelectionTimeoutError
@@ -57,8 +56,8 @@ class ConnectionManager:
57
56
  self.min_pool_size = min_pool_size
58
57
 
59
58
  # Connection state
60
- self._mongo_client: Optional[AsyncIOMotorClient] = None
61
- self._mongo_db: Optional[AsyncIOMotorDatabase] = None
59
+ self._mongo_client: AsyncIOMotorClient | None = None
60
+ self._mongo_db: AsyncIOMotorDatabase | None = None
62
61
  self._initialized: bool = False
63
62
 
64
63
  async def initialize(self) -> None:
@@ -242,7 +241,7 @@ class ConnectionManager:
242
241
  self._mongo_db = None
243
242
 
244
243
  @mongo_db.setter
245
- def mongo_db(self, value: Optional[AsyncIOMotorDatabase]) -> None:
244
+ def mongo_db(self, value: AsyncIOMotorDatabase | None) -> None:
246
245
  """Allow setting mongo_db property for testing purposes."""
247
246
  self._mongo_db = value
248
247
 
@@ -19,7 +19,6 @@ import base64
19
19
  import logging
20
20
  import os
21
21
  import secrets
22
- from typing import Tuple
23
22
 
24
23
  import cryptography.exceptions
25
24
  from cryptography.hazmat.primitives.ciphers.aead import AESGCM
@@ -121,7 +120,7 @@ class EnvelopeEncryptionService:
121
120
  """
122
121
  return secrets.token_bytes(AES_KEY_SIZE)
123
122
 
124
- def encrypt_secret(self, secret: str, master_key: bytes | None = None) -> Tuple[bytes, bytes]:
123
+ def encrypt_secret(self, secret: str, master_key: bytes | None = None) -> tuple[bytes, bytes]:
125
124
  """
126
125
  Encrypt a secret using envelope encryption.
127
126
 
mdb_engine/core/engine.py CHANGED
@@ -28,9 +28,10 @@ Usage:
28
28
  import logging
29
29
  import os
30
30
  import secrets
31
+ from collections.abc import Awaitable, Callable
31
32
  from contextlib import asynccontextmanager
32
33
  from pathlib import Path
33
- from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, List, Optional, Tuple
34
+ from typing import TYPE_CHECKING, Any, Optional
34
35
 
35
36
  from motor.motor_asyncio import AsyncIOMotorClient
36
37
  from pymongo.errors import PyMongoError
@@ -94,7 +95,7 @@ class MongoDBEngine:
94
95
  self,
95
96
  mongo_uri: str,
96
97
  db_name: str,
97
- manifests_dir: Optional[Path] = None,
98
+ manifests_dir: Path | None = None,
98
99
  authz_provider: Optional["AuthorizationProvider"] = None,
99
100
  max_pool_size: int = DEFAULT_MAX_POOL_SIZE,
100
101
  min_pool_size: int = DEFAULT_MIN_POOL_SIZE,
@@ -142,17 +143,17 @@ class MongoDBEngine:
142
143
  self.manifest_parser = ManifestParser()
143
144
 
144
145
  # Initialize managers (will be set up after connection is established)
145
- self._app_registration_manager: Optional[AppRegistrationManager] = None
146
- self._index_manager: Optional[IndexManager] = None
147
- self._service_initializer: Optional[ServiceInitializer] = None
148
- self._encryption_service: Optional[EnvelopeEncryptionService] = None
149
- self._app_secrets_manager: Optional[AppSecretsManager] = None
146
+ self._app_registration_manager: AppRegistrationManager | None = None
147
+ self._index_manager: IndexManager | None = None
148
+ self._service_initializer: ServiceInitializer | None = None
149
+ self._encryption_service: EnvelopeEncryptionService | None = None
150
+ self._app_secrets_manager: AppSecretsManager | None = None
150
151
 
151
152
  # Store app read_scopes mapping for validation
152
- self._app_read_scopes: Dict[str, List[str]] = {}
153
+ self._app_read_scopes: dict[str, list[str]] = {}
153
154
 
154
155
  # Store app token cache for auto-retrieval
155
- self._app_token_cache: Dict[str, str] = {}
156
+ self._app_token_cache: dict[str, str] = {}
156
157
 
157
158
  async def initialize(self) -> None:
158
159
  """
@@ -300,9 +301,9 @@ class MongoDBEngine:
300
301
  def get_scoped_db(
301
302
  self,
302
303
  app_slug: str,
303
- app_token: Optional[str] = None,
304
- read_scopes: Optional[List[str]] = None,
305
- write_scope: Optional[str] = None,
304
+ app_token: str | None = None,
305
+ read_scopes: list[str] | None = None,
306
+ write_scope: str | None = None,
306
307
  auto_index: bool = True,
307
308
  ) -> ScopedMongoWrapper:
308
309
  """
@@ -435,9 +436,9 @@ class MongoDBEngine:
435
436
  async def get_scoped_db_async(
436
437
  self,
437
438
  app_slug: str,
438
- app_token: Optional[str] = None,
439
- read_scopes: Optional[List[str]] = None,
440
- write_scope: Optional[str] = None,
439
+ app_token: str | None = None,
440
+ read_scopes: list[str] | None = None,
441
+ write_scope: str | None = None,
441
442
  auto_index: bool = True,
442
443
  ) -> ScopedMongoWrapper:
443
444
  """
@@ -540,7 +541,7 @@ class MongoDBEngine:
540
541
 
541
542
  async def validate_manifest(
542
543
  self, manifest: "ManifestDict"
543
- ) -> Tuple[bool, Optional[str], Optional[List[str]]]:
544
+ ) -> tuple[bool, str | None, list[str] | None]:
544
545
  """
545
546
  Validate a manifest against the schema.
546
547
 
@@ -604,16 +605,16 @@ class MongoDBEngine:
604
605
  if self._index_manager and create_indexes:
605
606
  await self._index_manager.create_app_indexes(slug, manifest)
606
607
 
607
- async def seed_data_callback(slug: str, initial_data: Dict[str, Any]) -> None:
608
+ async def seed_data_callback(slug: str, initial_data: dict[str, Any]) -> None:
608
609
  if self._service_initializer:
609
610
  await self._service_initializer.seed_initial_data(slug, initial_data)
610
611
 
611
- async def initialize_memory_callback(slug: str, memory_config: Dict[str, Any]) -> None:
612
+ async def initialize_memory_callback(slug: str, memory_config: dict[str, Any]) -> None:
612
613
  if self._service_initializer:
613
614
  await self._service_initializer.initialize_memory_service(slug, memory_config)
614
615
 
615
616
  async def register_websockets_callback(
616
- slug: str, websockets_config: Dict[str, Any]
617
+ slug: str, websockets_config: dict[str, Any]
617
618
  ) -> None:
618
619
  if self._service_initializer:
619
620
  await self._service_initializer.register_websockets(slug, websockets_config)
@@ -621,7 +622,7 @@ class MongoDBEngine:
621
622
  async def setup_observability_callback(
622
623
  slug: str,
623
624
  manifest: "ManifestDict",
624
- observability_config: Dict[str, Any],
625
+ observability_config: dict[str, Any],
625
626
  ) -> None:
626
627
  if self._service_initializer:
627
628
  await self._service_initializer.setup_observability(
@@ -665,7 +666,7 @@ class MongoDBEngine:
665
666
 
666
667
  return result
667
668
 
668
- def get_websocket_config(self, slug: str) -> Optional[Dict[str, Any]]:
669
+ def get_websocket_config(self, slug: str) -> dict[str, Any] | None:
669
670
  """
670
671
  Get WebSocket configuration for an app.
671
672
 
@@ -851,7 +852,7 @@ class MongoDBEngine:
851
852
  raise RuntimeError("MongoDBEngine not initialized. Call initialize() first.")
852
853
  return await self._app_registration_manager.get_manifest(slug)
853
854
 
854
- def get_memory_service(self, slug: str) -> Optional[Any]:
855
+ def get_memory_service(self, slug: str) -> Any | None:
855
856
  """
856
857
  Get Mem0 memory service for an app.
857
858
 
@@ -875,7 +876,7 @@ class MongoDBEngine:
875
876
  return self._service_initializer.get_memory_service(slug)
876
877
  return None
877
878
 
878
- def get_embedding_service(self, slug: str) -> Optional[Any]:
879
+ def get_embedding_service(self, slug: str) -> Any | None:
879
880
  """
880
881
  Get EmbeddingService for an app.
881
882
 
@@ -900,7 +901,7 @@ class MongoDBEngine:
900
901
  return get_embedding_service_for_app(slug, self)
901
902
 
902
903
  @property
903
- def _apps(self) -> Dict[str, Any]:
904
+ def _apps(self) -> dict[str, Any]:
904
905
  """
905
906
  Get the apps dictionary (for backward compatibility with tests).
906
907
 
@@ -914,7 +915,7 @@ class MongoDBEngine:
914
915
  raise RuntimeError("MongoDBEngine not initialized. Call initialize() first.")
915
916
  return self._app_registration_manager._apps
916
917
 
917
- def list_apps(self) -> List[str]:
918
+ def list_apps(self) -> list[str]:
918
919
  """
919
920
  List all registered app slugs.
920
921
 
@@ -958,9 +959,9 @@ class MongoDBEngine:
958
959
 
959
960
  def __exit__(
960
961
  self,
961
- exc_type: Optional[type[BaseException]],
962
- exc_val: Optional[BaseException],
963
- exc_tb: Optional[Any],
962
+ exc_type: type[BaseException] | None,
963
+ exc_val: BaseException | None,
964
+ exc_tb: Any | None,
964
965
  ) -> None:
965
966
  """
966
967
  Context manager exit (synchronous).
@@ -991,9 +992,9 @@ class MongoDBEngine:
991
992
 
992
993
  async def __aexit__(
993
994
  self,
994
- exc_type: Optional[type[BaseException]],
995
- exc_val: Optional[BaseException],
996
- exc_tb: Optional[Any],
995
+ exc_type: type[BaseException] | None,
996
+ exc_val: BaseException | None,
997
+ exc_tb: Any | None,
997
998
  ) -> None:
998
999
  """
999
1000
  Async context manager exit.
@@ -1007,7 +1008,7 @@ class MongoDBEngine:
1007
1008
  """
1008
1009
  await self.shutdown()
1009
1010
 
1010
- async def get_health_status(self) -> Dict[str, Any]:
1011
+ async def get_health_status(self) -> dict[str, Any]:
1011
1012
  """
1012
1013
  Get health status of the MongoDB Engine.
1013
1014
 
@@ -1069,7 +1070,7 @@ class MongoDBEngine:
1069
1070
 
1070
1071
  return await health_checker.check_all()
1071
1072
 
1072
- def get_metrics(self) -> Dict[str, Any]:
1073
+ def get_metrics(self) -> dict[str, Any]:
1073
1074
  """
1074
1075
  Get metrics for the MongoDB Engine.
1075
1076
 
@@ -1089,13 +1090,11 @@ class MongoDBEngine:
1089
1090
  self,
1090
1091
  slug: str,
1091
1092
  manifest: Path,
1092
- title: Optional[str] = None,
1093
- on_startup: Optional[
1094
- Callable[["FastAPI", "MongoDBEngine", Dict[str, Any]], Awaitable[None]]
1095
- ] = None,
1096
- on_shutdown: Optional[
1097
- Callable[["FastAPI", "MongoDBEngine", Dict[str, Any]], Awaitable[None]]
1098
- ] = None,
1093
+ title: str | None = None,
1094
+ on_startup: Callable[["FastAPI", "MongoDBEngine", dict[str, Any]], Awaitable[None]]
1095
+ | None = None,
1096
+ on_shutdown: Callable[["FastAPI", "MongoDBEngine", dict[str, Any]], Awaitable[None]]
1097
+ | None = None,
1099
1098
  **fastapi_kwargs: Any,
1100
1099
  ) -> "FastAPI":
1101
1100
  """
@@ -1170,7 +1169,7 @@ class MongoDBEngine:
1170
1169
  app_title = title or pre_manifest.get("name", slug)
1171
1170
 
1172
1171
  # State that will be populated during initialization
1173
- app_manifest: Dict[str, Any] = {}
1172
+ app_manifest: dict[str, Any] = {}
1174
1173
  is_multi_site = False
1175
1174
 
1176
1175
  @asynccontextmanager
@@ -1506,7 +1505,7 @@ class MongoDBEngine:
1506
1505
  async def _initialize_shared_user_pool(
1507
1506
  self,
1508
1507
  app: "FastAPI",
1509
- manifest: Optional[Dict[str, Any]] = None,
1508
+ manifest: dict[str, Any] | None = None,
1510
1509
  ) -> None:
1511
1510
  """
1512
1511
  Initialize shared user pool, audit log, and set them on app.state.
@@ -1644,7 +1643,7 @@ class MongoDBEngine:
1644
1643
 
1645
1644
  return _lifespan
1646
1645
 
1647
- async def auto_retrieve_app_token(self, slug: str) -> Optional[str]:
1646
+ async def auto_retrieve_app_token(self, slug: str) -> str | None:
1648
1647
  """
1649
1648
  Auto-retrieve app token from environment or database.
1650
1649
 
@@ -1697,7 +1696,7 @@ class MongoDBEngine:
1697
1696
  )
1698
1697
  return None
1699
1698
 
1700
- def get_app_token(self, slug: str) -> Optional[str]:
1699
+ def get_app_token(self, slug: str) -> str | None:
1701
1700
  """
1702
1701
  Get cached app token for a slug.
1703
1702