mdb-engine 0.1.6__py3-none-any.whl → 0.4.12__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 (92) hide show
  1. mdb_engine/__init__.py +116 -11
  2. mdb_engine/auth/ARCHITECTURE.md +112 -0
  3. mdb_engine/auth/README.md +654 -11
  4. mdb_engine/auth/__init__.py +136 -29
  5. mdb_engine/auth/audit.py +592 -0
  6. mdb_engine/auth/base.py +252 -0
  7. mdb_engine/auth/casbin_factory.py +265 -70
  8. mdb_engine/auth/config_defaults.py +5 -5
  9. mdb_engine/auth/config_helpers.py +19 -18
  10. mdb_engine/auth/cookie_utils.py +12 -16
  11. mdb_engine/auth/csrf.py +483 -0
  12. mdb_engine/auth/decorators.py +10 -16
  13. mdb_engine/auth/dependencies.py +69 -71
  14. mdb_engine/auth/helpers.py +3 -3
  15. mdb_engine/auth/integration.py +61 -88
  16. mdb_engine/auth/jwt.py +11 -15
  17. mdb_engine/auth/middleware.py +79 -35
  18. mdb_engine/auth/oso_factory.py +21 -41
  19. mdb_engine/auth/provider.py +270 -171
  20. mdb_engine/auth/rate_limiter.py +505 -0
  21. mdb_engine/auth/restrictions.py +21 -36
  22. mdb_engine/auth/session_manager.py +24 -41
  23. mdb_engine/auth/shared_middleware.py +977 -0
  24. mdb_engine/auth/shared_users.py +775 -0
  25. mdb_engine/auth/token_lifecycle.py +10 -12
  26. mdb_engine/auth/token_store.py +17 -32
  27. mdb_engine/auth/users.py +99 -159
  28. mdb_engine/auth/utils.py +236 -42
  29. mdb_engine/cli/commands/generate.py +546 -10
  30. mdb_engine/cli/commands/validate.py +3 -7
  31. mdb_engine/cli/utils.py +7 -7
  32. mdb_engine/config.py +13 -28
  33. mdb_engine/constants.py +65 -0
  34. mdb_engine/core/README.md +117 -6
  35. mdb_engine/core/__init__.py +39 -7
  36. mdb_engine/core/app_registration.py +31 -50
  37. mdb_engine/core/app_secrets.py +289 -0
  38. mdb_engine/core/connection.py +20 -12
  39. mdb_engine/core/encryption.py +222 -0
  40. mdb_engine/core/engine.py +2862 -115
  41. mdb_engine/core/index_management.py +12 -16
  42. mdb_engine/core/manifest.py +628 -204
  43. mdb_engine/core/ray_integration.py +436 -0
  44. mdb_engine/core/seeding.py +13 -21
  45. mdb_engine/core/service_initialization.py +20 -30
  46. mdb_engine/core/types.py +40 -43
  47. mdb_engine/database/README.md +140 -17
  48. mdb_engine/database/__init__.py +17 -6
  49. mdb_engine/database/abstraction.py +37 -50
  50. mdb_engine/database/connection.py +51 -30
  51. mdb_engine/database/query_validator.py +367 -0
  52. mdb_engine/database/resource_limiter.py +204 -0
  53. mdb_engine/database/scoped_wrapper.py +747 -237
  54. mdb_engine/dependencies.py +427 -0
  55. mdb_engine/di/__init__.py +34 -0
  56. mdb_engine/di/container.py +247 -0
  57. mdb_engine/di/providers.py +206 -0
  58. mdb_engine/di/scopes.py +139 -0
  59. mdb_engine/embeddings/README.md +54 -24
  60. mdb_engine/embeddings/__init__.py +31 -24
  61. mdb_engine/embeddings/dependencies.py +38 -155
  62. mdb_engine/embeddings/service.py +78 -75
  63. mdb_engine/exceptions.py +104 -12
  64. mdb_engine/indexes/README.md +30 -13
  65. mdb_engine/indexes/__init__.py +1 -0
  66. mdb_engine/indexes/helpers.py +11 -11
  67. mdb_engine/indexes/manager.py +59 -123
  68. mdb_engine/memory/README.md +95 -4
  69. mdb_engine/memory/__init__.py +1 -2
  70. mdb_engine/memory/service.py +363 -1168
  71. mdb_engine/observability/README.md +4 -2
  72. mdb_engine/observability/__init__.py +26 -9
  73. mdb_engine/observability/health.py +17 -17
  74. mdb_engine/observability/logging.py +10 -10
  75. mdb_engine/observability/metrics.py +40 -19
  76. mdb_engine/repositories/__init__.py +34 -0
  77. mdb_engine/repositories/base.py +325 -0
  78. mdb_engine/repositories/mongo.py +233 -0
  79. mdb_engine/repositories/unit_of_work.py +166 -0
  80. mdb_engine/routing/README.md +1 -1
  81. mdb_engine/routing/__init__.py +1 -3
  82. mdb_engine/routing/websockets.py +41 -75
  83. mdb_engine/utils/__init__.py +3 -1
  84. mdb_engine/utils/mongo.py +117 -0
  85. mdb_engine-0.4.12.dist-info/METADATA +492 -0
  86. mdb_engine-0.4.12.dist-info/RECORD +97 -0
  87. {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/WHEEL +1 -1
  88. mdb_engine-0.1.6.dist-info/METADATA +0 -213
  89. mdb_engine-0.1.6.dist-info/RECORD +0 -75
  90. {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/entry_points.txt +0 -0
  91. {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/licenses/LICENSE +0 -0
  92. {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,206 @@
1
+ """
2
+ Service Providers for Dependency Injection
3
+
4
+ Providers are responsible for creating and managing service instances
5
+ according to their configured scope.
6
+ """
7
+
8
+ import inspect
9
+ import logging
10
+ from abc import ABC, abstractmethod
11
+ from collections.abc import Callable
12
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar
13
+
14
+ from .scopes import Scope, ScopeManager
15
+
16
+ if TYPE_CHECKING:
17
+ from .container import Container
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+ T = TypeVar("T")
22
+
23
+
24
+ class Provider(ABC, Generic[T]):
25
+ """
26
+ Abstract base class for service providers.
27
+
28
+ Providers know how to create instances of a service and manage
29
+ their lifecycle according to the configured scope.
30
+ """
31
+
32
+ def __init__(
33
+ self,
34
+ service_type: type[T],
35
+ scope: Scope,
36
+ factory: Callable[..., T] | None = None,
37
+ ):
38
+ self.service_type = service_type
39
+ self.scope = scope
40
+ self._factory = factory or service_type
41
+
42
+ @abstractmethod
43
+ def get(self, container: "Container") -> T:
44
+ """
45
+ Get or create a service instance.
46
+
47
+ Args:
48
+ container: The DI container for resolving dependencies
49
+
50
+ Returns:
51
+ Service instance
52
+ """
53
+ pass
54
+
55
+ def _create_instance(self, container: "Container") -> T:
56
+ """
57
+ Create a new instance, injecting dependencies.
58
+
59
+ Inspects the factory/constructor signature and resolves
60
+ any type-hinted parameters from the container.
61
+ """
62
+ # Get constructor signature
63
+ sig = inspect.signature(self._factory)
64
+ kwargs: dict[str, Any] = {}
65
+
66
+ for param_name, param in sig.parameters.items():
67
+ if param_name == "self":
68
+ continue
69
+
70
+ # Check if parameter has a type annotation
71
+ if param.annotation != inspect.Parameter.empty:
72
+ param_type = param.annotation
73
+
74
+ # Skip primitive types and Optional markers
75
+ if param_type in (str, int, float, bool, type(None)):
76
+ continue
77
+
78
+ # Handle Optional[X] - extract X
79
+ origin = getattr(param_type, "__origin__", None)
80
+ if origin is type(None):
81
+ continue
82
+
83
+ # Try to resolve from container
84
+ try:
85
+ kwargs[param_name] = container.resolve(param_type)
86
+ except KeyError:
87
+ # If not registered and has default, skip
88
+ if param.default != inspect.Parameter.empty:
89
+ continue
90
+ # If not registered and no default, re-raise
91
+ raise
92
+
93
+ return self._factory(**kwargs)
94
+
95
+
96
+ class SingletonProvider(Provider[T]):
97
+ """
98
+ Provider that creates a single instance shared across the application.
99
+
100
+ The instance is created lazily on first request and cached forever.
101
+ """
102
+
103
+ def __init__(
104
+ self,
105
+ service_type: type[T],
106
+ factory: Callable[..., T] | None = None,
107
+ ):
108
+ super().__init__(service_type, Scope.SINGLETON, factory)
109
+ self._instance: T | None = None
110
+
111
+ def get(self, container: "Container") -> T:
112
+ if self._instance is None:
113
+ self._instance = self._create_instance(container)
114
+ logger.debug(f"Created singleton: {self.service_type.__name__}")
115
+ return self._instance
116
+
117
+ def reset(self) -> None:
118
+ """Reset the singleton (useful for testing)."""
119
+ self._instance = None
120
+
121
+
122
+ class RequestProvider(Provider[T]):
123
+ """
124
+ Provider that creates one instance per request.
125
+
126
+ Uses ScopeManager to cache instances within the request scope.
127
+ """
128
+
129
+ def __init__(
130
+ self,
131
+ service_type: type[T],
132
+ factory: Callable[..., T] | None = None,
133
+ ):
134
+ super().__init__(service_type, Scope.REQUEST, factory)
135
+
136
+ def get(self, container: "Container") -> T:
137
+ return ScopeManager.get_or_create(
138
+ self.service_type, lambda: self._create_instance(container)
139
+ )
140
+
141
+
142
+ class TransientProvider(Provider[T]):
143
+ """
144
+ Provider that creates a new instance every time.
145
+ """
146
+
147
+ def __init__(
148
+ self,
149
+ service_type: type[T],
150
+ factory: Callable[..., T] | None = None,
151
+ ):
152
+ super().__init__(service_type, Scope.TRANSIENT, factory)
153
+
154
+ def get(self, container: "Container") -> T:
155
+ instance = self._create_instance(container)
156
+ logger.debug(f"Created transient: {self.service_type.__name__}")
157
+ return instance
158
+
159
+
160
+ class FactoryProvider(Provider[T]):
161
+ """
162
+ Provider that uses a custom factory function.
163
+
164
+ The factory is called with the container as the first argument,
165
+ allowing manual dependency resolution.
166
+
167
+ Usage:
168
+ def create_user_service(container: Container) -> UserService:
169
+ db = container.resolve(Database)
170
+ return UserService(db, custom_config=...)
171
+
172
+ container.register_factory(UserService, create_user_service, Scope.REQUEST)
173
+ """
174
+
175
+ def __init__(
176
+ self,
177
+ service_type: type[T],
178
+ factory: Callable[["Container"], T],
179
+ scope: Scope,
180
+ ):
181
+ super().__init__(service_type, scope, None)
182
+ self._custom_factory = factory
183
+ self._singleton_instance: T | None = None
184
+
185
+ def get(self, container: "Container") -> T:
186
+ if self.scope == Scope.SINGLETON:
187
+ if self._singleton_instance is None:
188
+ self._singleton_instance = self._custom_factory(container)
189
+ return self._singleton_instance
190
+
191
+ elif self.scope == Scope.REQUEST:
192
+ return ScopeManager.get_or_create(
193
+ self.service_type, lambda: self._custom_factory(container)
194
+ )
195
+
196
+ else: # TRANSIENT
197
+ return self._custom_factory(container)
198
+
199
+
200
+ __all__ = [
201
+ "Provider",
202
+ "SingletonProvider",
203
+ "RequestProvider",
204
+ "TransientProvider",
205
+ "FactoryProvider",
206
+ ]
@@ -0,0 +1,139 @@
1
+ """
2
+ Service Scopes for Dependency Injection
3
+
4
+ Defines service lifetime scopes following enterprise patterns:
5
+ - SINGLETON: Created once, shared across all requests
6
+ - REQUEST: Created once per HTTP request, disposed after
7
+ - TRANSIENT: Created fresh on every injection
8
+ """
9
+
10
+ import logging
11
+ from contextvars import ContextVar
12
+ from enum import Enum
13
+ from typing import Any
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ # Context variable for request-scoped instances
18
+ _request_scope: ContextVar[dict[type, Any] | None] = ContextVar("request_scope", default=None)
19
+
20
+
21
+ class Scope(Enum):
22
+ """
23
+ Service lifetime scopes.
24
+
25
+ SINGLETON: One instance for the entire application lifetime.
26
+ Use for: Database connections, configuration, caches.
27
+
28
+ REQUEST: One instance per HTTP request. Automatically disposed
29
+ when the request ends.
30
+ Use for: Unit of Work, request context, user session.
31
+
32
+ TRANSIENT: New instance created every time it's requested.
33
+ Use for: Stateless services, utilities.
34
+ """
35
+
36
+ SINGLETON = "singleton"
37
+ REQUEST = "request"
38
+ TRANSIENT = "transient"
39
+
40
+
41
+ class ScopeManager:
42
+ """
43
+ Manages request-scoped instance lifecycles.
44
+
45
+ Usage with FastAPI middleware:
46
+ @app.middleware("http")
47
+ async def scope_middleware(request: Request, call_next):
48
+ async with ScopeManager.request_scope():
49
+ response = await call_next(request)
50
+ return response
51
+ """
52
+
53
+ @classmethod
54
+ def begin_request(cls) -> dict[type, Any]:
55
+ """
56
+ Begin a new request scope.
57
+
58
+ Returns the scope dictionary for manual management if needed.
59
+ """
60
+ scope_dict: dict[type, Any] = {}
61
+ _request_scope.set(scope_dict)
62
+ logger.debug("Request scope started")
63
+ return scope_dict
64
+
65
+ @classmethod
66
+ def end_request(cls) -> None:
67
+ """
68
+ End the current request scope and cleanup instances.
69
+
70
+ Calls dispose() on any instances that have it.
71
+ """
72
+ scope_dict = _request_scope.get()
73
+ if scope_dict:
74
+ for instance in scope_dict.values():
75
+ if hasattr(instance, "dispose"):
76
+ try:
77
+ instance.dispose()
78
+ except (AttributeError, RuntimeError, TypeError) as e:
79
+ logger.warning(f"Error disposing {type(instance).__name__}: {e}")
80
+ scope_dict.clear()
81
+ _request_scope.set(None)
82
+ logger.debug("Request scope ended")
83
+
84
+ @classmethod
85
+ def get_request_scope(cls) -> dict[type, Any] | None:
86
+ """Get the current request scope dictionary."""
87
+ return _request_scope.get()
88
+
89
+ @classmethod
90
+ def get_or_create(cls, key: type, factory: callable) -> Any:
91
+ """
92
+ Get an existing instance from request scope or create one.
93
+
94
+ Args:
95
+ key: The type to use as cache key
96
+ factory: Callable to create a new instance if not cached
97
+
98
+ Returns:
99
+ The cached or newly created instance
100
+
101
+ Raises:
102
+ RuntimeError: If called outside a request scope
103
+ """
104
+ scope_dict = _request_scope.get()
105
+ if scope_dict is None:
106
+ raise RuntimeError(
107
+ "No active request scope. Ensure ScopeManager.begin_request() "
108
+ "was called (usually via middleware)."
109
+ )
110
+
111
+ if key not in scope_dict:
112
+ scope_dict[key] = factory()
113
+ logger.debug(f"Created request-scoped instance: {key.__name__}")
114
+
115
+ return scope_dict[key]
116
+
117
+ @classmethod
118
+ async def request_scope(cls):
119
+ """
120
+ Async context manager for request scope.
121
+
122
+ Usage:
123
+ async with ScopeManager.request_scope():
124
+ # Request-scoped services available here
125
+ pass
126
+ """
127
+ return _RequestScopeContext()
128
+
129
+
130
+ class _RequestScopeContext:
131
+ """Async context manager for request scope."""
132
+
133
+ async def __aenter__(self):
134
+ ScopeManager.begin_request()
135
+ return self
136
+
137
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
138
+ ScopeManager.end_request()
139
+ return False
@@ -9,6 +9,7 @@ Semantic text splitting and embedding generation for MDB_ENGINE applications.
9
9
  - **Token-Aware**: Never exceeds model token limits
10
10
  - **Batch Processing**: Efficient batch embedding generation
11
11
  - **MongoDB Integration**: Built-in support for storing embeddings with metadata
12
+ - **Request-Scoped Dependencies**: Clean FastAPI integration via `mdb_engine.dependencies`
12
13
 
13
14
  ## Installation
14
15
 
@@ -38,7 +39,44 @@ Enable embedding service in your `manifest.json`:
38
39
 
39
40
  ## Usage
40
41
 
41
- ### 1. Basic Usage (Auto-Detection)
42
+ ### 1. FastAPI Routes (Recommended)
43
+
44
+ Use request-scoped dependencies from `mdb_engine.dependencies`:
45
+
46
+ ```python
47
+ from fastapi import Depends
48
+ from mdb_engine import MongoDBEngine
49
+ from mdb_engine.dependencies import get_embedding_service, get_scoped_db
50
+
51
+ engine = MongoDBEngine(mongo_uri=..., db_name=...)
52
+ app = engine.create_app(slug="my_app", manifest=Path("manifest.json"))
53
+
54
+ @app.post("/embed")
55
+ async def embed_endpoint(
56
+ db=Depends(get_scoped_db),
57
+ embedding_service=Depends(get_embedding_service),
58
+ ):
59
+ # Services are automatically bound to the current app
60
+ result = await embedding_service.process_and_store(
61
+ text_content="Hello world",
62
+ source_id="doc_1",
63
+ collection=db.knowledge_base,
64
+ )
65
+ return {"chunks_created": result["chunks_created"]}
66
+
67
+ @app.post("/search")
68
+ async def search(
69
+ query: str,
70
+ db=Depends(get_scoped_db),
71
+ embedding_service=Depends(get_embedding_service),
72
+ ):
73
+ # Generate query embedding
74
+ vectors = await embedding_service.embed_chunks([query])
75
+ # Use vectors for vector search...
76
+ return {"query_vector_dims": len(vectors[0])}
77
+ ```
78
+
79
+ ### 2. Basic Usage (Standalone)
42
80
 
43
81
  ```python
44
82
  from mdb_engine.embeddings import EmbeddingService
@@ -56,7 +94,7 @@ chunks = await embedding_service.chunk_text(
56
94
  vectors = await embedding_service.embed_chunks(chunks, model="text-embedding-3-small")
57
95
  ```
58
96
 
59
- ### 2. Process and Store in MongoDB
97
+ ### 3. Process and Store in MongoDB
60
98
 
61
99
  ```python
62
100
  from mdb_engine.embeddings import EmbeddingService
@@ -75,36 +113,28 @@ result = await embedding_service.process_and_store(
75
113
  print(f"Created {result['chunks_created']} chunks")
76
114
  ```
77
115
 
78
- ### 3. Explicit Provider
116
+ ### 4. Utility Function (Background Tasks/CLI)
117
+
118
+ For use outside of FastAPI request handlers:
79
119
 
80
120
  ```python
81
- from mdb_engine.embeddings import EmbeddingService, OpenAIEmbeddingProvider, EmbeddingProvider
121
+ from mdb_engine.embeddings.dependencies import get_embedding_service_for_app
82
122
 
83
- # Use OpenAI explicitly
84
- openai_provider = OpenAIEmbeddingProvider(default_model="text-embedding-3-small")
85
- provider = EmbeddingProvider(embedding_provider=openai_provider)
86
- embedding_service = EmbeddingService(embedding_provider=provider)
123
+ # In a background task or CLI tool
124
+ service = get_embedding_service_for_app("my_app", engine)
125
+ if service:
126
+ embeddings = await service.embed_chunks(["Hello world"])
87
127
  ```
88
128
 
89
- ### 4. In FastAPI Routes
129
+ ### 5. Explicit Provider
90
130
 
91
131
  ```python
92
- from fastapi import FastAPI, Depends
93
- from mdb_engine.embeddings.dependencies import get_embedding_service_dependency
94
- from mdb_engine.embeddings import EmbeddingService
95
-
96
- app = FastAPI()
97
-
98
- # Set global engine during startup
99
- from mdb_engine.embeddings.dependencies import set_global_engine
100
- set_global_engine(engine, app_slug="my_app")
132
+ from mdb_engine.embeddings import EmbeddingService, OpenAIEmbeddingProvider, EmbeddingProvider
101
133
 
102
- @app.post("/embed")
103
- async def embed_endpoint(
104
- embedding_service: EmbeddingService = Depends(get_embedding_service_dependency("my_app"))
105
- ):
106
- embeddings = await embedding_service.embed_chunks(["Hello world"])
107
- return {"embeddings": embeddings}
134
+ # Use OpenAI explicitly
135
+ openai_provider = OpenAIEmbeddingProvider(default_model="text-embedding-3-small")
136
+ provider = EmbeddingProvider(embedding_provider=openai_provider)
137
+ embedding_service = EmbeddingService(embedding_provider=provider)
108
138
  ```
109
139
 
110
140
  ## Environment Variables
@@ -7,6 +7,22 @@ Examples should implement their own LLM clients directly using the OpenAI SDK.
7
7
  For memory functionality, use mdb_engine.memory.Mem0MemoryService which
8
8
  handles embeddings and LLM via environment variables (.env).
9
9
 
10
+ FastAPI Dependency Injection:
11
+ # RECOMMENDED: Use request-scoped dependencies
12
+ from mdb_engine.dependencies import get_embedding_service
13
+
14
+ @app.post("/embed")
15
+ async def embed_text(embedding_service=Depends(get_embedding_service)):
16
+ embeddings = await embedding_service.embed_chunks(["Hello world"])
17
+ return {"embeddings": embeddings}
18
+
19
+ Standalone Usage:
20
+ from mdb_engine.embeddings import EmbeddingService, get_embedding_service
21
+
22
+ # Auto-detects OpenAI or Azure from environment variables
23
+ service = get_embedding_service(config={"default_embedding_model": "text-embedding-3-small"})
24
+ embeddings = await service.embed_chunks(["Hello world"])
25
+
10
26
  Example LLM implementation:
11
27
  from openai import AzureOpenAI
12
28
  from dotenv import load_dotenv
@@ -24,39 +40,30 @@ Example LLM implementation:
24
40
  model=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"),
25
41
  messages=[...]
26
42
  )
27
-
28
- Example EmbeddingService usage:
29
- from mdb_engine.embeddings import EmbeddingService, get_embedding_service
30
-
31
- # In FastAPI route
32
- @app.post("/embed")
33
- async def embed_text(embedding_service: EmbeddingService = Depends(get_embedding_service)):
34
- embeddings = await embedding_service.embed_chunks(["Hello world"])
35
- return {"embeddings": embeddings}
36
43
  """
37
44
 
38
- from .dependencies import (create_embedding_dependency,
39
- get_embedding_service_dep,
40
- get_embedding_service_dependency,
41
- get_embedding_service_for_app, get_global_engine,
42
- set_global_engine)
43
- from .service import (AzureOpenAIEmbeddingProvider, BaseEmbeddingProvider,
44
- EmbeddingProvider, EmbeddingService,
45
- EmbeddingServiceError, OpenAIEmbeddingProvider,
46
- get_embedding_service)
45
+ from .dependencies import get_embedding_service_for_app
46
+ from .service import (
47
+ AzureOpenAIEmbeddingProvider,
48
+ BaseEmbeddingProvider,
49
+ EmbeddingProvider,
50
+ EmbeddingService,
51
+ EmbeddingServiceError,
52
+ OpenAIEmbeddingProvider,
53
+ get_embedding_service,
54
+ )
47
55
 
48
56
  __all__ = [
57
+ # Core service classes
49
58
  "EmbeddingService",
50
59
  "EmbeddingServiceError",
60
+ "EmbeddingProvider",
61
+ # Embedding providers
51
62
  "BaseEmbeddingProvider",
52
63
  "OpenAIEmbeddingProvider",
53
64
  "AzureOpenAIEmbeddingProvider",
54
- "EmbeddingProvider",
65
+ # Factory function
55
66
  "get_embedding_service",
67
+ # Utility for standalone usage
56
68
  "get_embedding_service_for_app",
57
- "create_embedding_dependency",
58
- "set_global_engine",
59
- "get_global_engine",
60
- "get_embedding_service_dependency",
61
- "get_embedding_service_dep",
62
69
  ]