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.
- mdb_engine/README.md +144 -0
- mdb_engine/__init__.py +37 -0
- mdb_engine/auth/README.md +631 -0
- mdb_engine/auth/__init__.py +128 -0
- mdb_engine/auth/casbin_factory.py +199 -0
- mdb_engine/auth/casbin_models.py +46 -0
- mdb_engine/auth/config_defaults.py +71 -0
- mdb_engine/auth/config_helpers.py +213 -0
- mdb_engine/auth/cookie_utils.py +158 -0
- mdb_engine/auth/decorators.py +350 -0
- mdb_engine/auth/dependencies.py +747 -0
- mdb_engine/auth/helpers.py +64 -0
- mdb_engine/auth/integration.py +578 -0
- mdb_engine/auth/jwt.py +225 -0
- mdb_engine/auth/middleware.py +241 -0
- mdb_engine/auth/oso_factory.py +323 -0
- mdb_engine/auth/provider.py +570 -0
- mdb_engine/auth/restrictions.py +271 -0
- mdb_engine/auth/session_manager.py +477 -0
- mdb_engine/auth/token_lifecycle.py +213 -0
- mdb_engine/auth/token_store.py +289 -0
- mdb_engine/auth/users.py +1516 -0
- mdb_engine/auth/utils.py +614 -0
- mdb_engine/cli/__init__.py +13 -0
- mdb_engine/cli/commands/__init__.py +7 -0
- mdb_engine/cli/commands/generate.py +105 -0
- mdb_engine/cli/commands/migrate.py +83 -0
- mdb_engine/cli/commands/show.py +70 -0
- mdb_engine/cli/commands/validate.py +63 -0
- mdb_engine/cli/main.py +41 -0
- mdb_engine/cli/utils.py +92 -0
- mdb_engine/config.py +217 -0
- mdb_engine/constants.py +160 -0
- mdb_engine/core/README.md +542 -0
- mdb_engine/core/__init__.py +42 -0
- mdb_engine/core/app_registration.py +392 -0
- mdb_engine/core/connection.py +243 -0
- mdb_engine/core/engine.py +749 -0
- mdb_engine/core/index_management.py +162 -0
- mdb_engine/core/manifest.py +2793 -0
- mdb_engine/core/seeding.py +179 -0
- mdb_engine/core/service_initialization.py +355 -0
- mdb_engine/core/types.py +413 -0
- mdb_engine/database/README.md +522 -0
- mdb_engine/database/__init__.py +31 -0
- mdb_engine/database/abstraction.py +635 -0
- mdb_engine/database/connection.py +387 -0
- mdb_engine/database/scoped_wrapper.py +1721 -0
- mdb_engine/embeddings/README.md +184 -0
- mdb_engine/embeddings/__init__.py +62 -0
- mdb_engine/embeddings/dependencies.py +193 -0
- mdb_engine/embeddings/service.py +759 -0
- mdb_engine/exceptions.py +167 -0
- mdb_engine/indexes/README.md +651 -0
- mdb_engine/indexes/__init__.py +21 -0
- mdb_engine/indexes/helpers.py +145 -0
- mdb_engine/indexes/manager.py +895 -0
- mdb_engine/memory/README.md +451 -0
- mdb_engine/memory/__init__.py +30 -0
- mdb_engine/memory/service.py +1285 -0
- mdb_engine/observability/README.md +515 -0
- mdb_engine/observability/__init__.py +42 -0
- mdb_engine/observability/health.py +296 -0
- mdb_engine/observability/logging.py +161 -0
- mdb_engine/observability/metrics.py +297 -0
- mdb_engine/routing/README.md +462 -0
- mdb_engine/routing/__init__.py +73 -0
- mdb_engine/routing/websockets.py +813 -0
- mdb_engine/utils/__init__.py +7 -0
- mdb_engine-0.1.6.dist-info/METADATA +213 -0
- mdb_engine-0.1.6.dist-info/RECORD +75 -0
- mdb_engine-0.1.6.dist-info/WHEEL +5 -0
- mdb_engine-0.1.6.dist-info/entry_points.txt +2 -0
- mdb_engine-0.1.6.dist-info/licenses/LICENSE +661 -0
- mdb_engine-0.1.6.dist-info/top_level.txt +1 -0
mdb_engine/constants.py
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Constants for MDB_ENGINE.
|
|
3
|
+
|
|
4
|
+
This module contains all shared constants used across the codebase to avoid
|
|
5
|
+
magic numbers and improve maintainability.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Final
|
|
9
|
+
|
|
10
|
+
# ============================================================================
|
|
11
|
+
# INDEX MANAGEMENT CONSTANTS
|
|
12
|
+
# ============================================================================
|
|
13
|
+
|
|
14
|
+
# Polling intervals (in seconds)
|
|
15
|
+
DEFAULT_POLL_INTERVAL: Final[int] = 5
|
|
16
|
+
"""Default polling interval for checking index status (seconds)."""
|
|
17
|
+
|
|
18
|
+
# Timeouts (in seconds)
|
|
19
|
+
DEFAULT_SEARCH_TIMEOUT: Final[int] = 600 # 10 minutes
|
|
20
|
+
"""Default timeout for waiting for search indexes to become ready (seconds)."""
|
|
21
|
+
|
|
22
|
+
DEFAULT_DROP_TIMEOUT: Final[int] = 300 # 5 minutes
|
|
23
|
+
"""Default timeout for waiting for search indexes to be dropped (seconds)."""
|
|
24
|
+
|
|
25
|
+
# Auto-indexing constants
|
|
26
|
+
AUTO_INDEX_HINT_THRESHOLD: Final[int] = 3
|
|
27
|
+
"""Number of times a query pattern must be seen before creating an index."""
|
|
28
|
+
|
|
29
|
+
MAX_INDEX_FIELDS: Final[int] = 4
|
|
30
|
+
"""Maximum number of fields in a compound index (MongoDB best practice)."""
|
|
31
|
+
|
|
32
|
+
MAX_CACHE_SIZE: Final[int] = 1000
|
|
33
|
+
"""Maximum size of authorization and validation caches before eviction."""
|
|
34
|
+
|
|
35
|
+
# ============================================================================
|
|
36
|
+
# DATABASE CONSTANTS
|
|
37
|
+
# ============================================================================
|
|
38
|
+
|
|
39
|
+
# Connection pool defaults
|
|
40
|
+
DEFAULT_MAX_POOL_SIZE: Final[int] = 50
|
|
41
|
+
"""Default maximum MongoDB connection pool size."""
|
|
42
|
+
|
|
43
|
+
DEFAULT_MIN_POOL_SIZE: Final[int] = 10
|
|
44
|
+
"""Default minimum MongoDB connection pool size."""
|
|
45
|
+
|
|
46
|
+
DEFAULT_SERVER_SELECTION_TIMEOUT_MS: Final[int] = 5000
|
|
47
|
+
"""Default server selection timeout in milliseconds."""
|
|
48
|
+
|
|
49
|
+
DEFAULT_MAX_IDLE_TIME_MS: Final[int] = 45000
|
|
50
|
+
"""Default maximum idle time before closing connections (milliseconds)."""
|
|
51
|
+
|
|
52
|
+
# ============================================================================
|
|
53
|
+
# VALIDATION CONSTANTS
|
|
54
|
+
# ============================================================================
|
|
55
|
+
|
|
56
|
+
# Collection name constraints
|
|
57
|
+
MAX_COLLECTION_NAME_LENGTH: Final[int] = 255
|
|
58
|
+
"""Maximum length for MongoDB collection names."""
|
|
59
|
+
|
|
60
|
+
# App slug constraints
|
|
61
|
+
MAX_APP_SLUG_LENGTH: Final[int] = 100
|
|
62
|
+
"""Maximum length for app slugs."""
|
|
63
|
+
|
|
64
|
+
# TTL index constraints
|
|
65
|
+
MIN_TTL_SECONDS: Final[int] = 1
|
|
66
|
+
"""Minimum TTL value in seconds."""
|
|
67
|
+
|
|
68
|
+
MAX_TTL_SECONDS: Final[int] = 31536000 # 1 year
|
|
69
|
+
"""Maximum recommended TTL value in seconds (1 year)."""
|
|
70
|
+
|
|
71
|
+
# Vector index constraints
|
|
72
|
+
MIN_VECTOR_DIMENSIONS: Final[int] = 1
|
|
73
|
+
"""Minimum number of dimensions for vector indexes."""
|
|
74
|
+
|
|
75
|
+
MAX_VECTOR_DIMENSIONS: Final[int] = 10000
|
|
76
|
+
"""Maximum number of dimensions for vector indexes."""
|
|
77
|
+
|
|
78
|
+
# ============================================================================
|
|
79
|
+
# CACHING CONSTANTS
|
|
80
|
+
# ============================================================================
|
|
81
|
+
|
|
82
|
+
AUTHZ_CACHE_TTL: Final[int] = 300 # 5 minutes
|
|
83
|
+
"""Authorization cache TTL in seconds."""
|
|
84
|
+
|
|
85
|
+
# ============================================================================
|
|
86
|
+
# TOKEN MANAGEMENT CONSTANTS
|
|
87
|
+
# ============================================================================
|
|
88
|
+
|
|
89
|
+
# Token lifetimes (in seconds)
|
|
90
|
+
ACCESS_TOKEN_TTL: Final[int] = 900 # 15 minutes
|
|
91
|
+
"""Default access token TTL in seconds."""
|
|
92
|
+
|
|
93
|
+
REFRESH_TOKEN_TTL: Final[int] = 604800 # 7 days
|
|
94
|
+
"""Default refresh token TTL in seconds."""
|
|
95
|
+
|
|
96
|
+
# Token management settings
|
|
97
|
+
TOKEN_ROTATION_ENABLED: Final[bool] = True
|
|
98
|
+
"""Whether to rotate refresh tokens on each use."""
|
|
99
|
+
|
|
100
|
+
MAX_SESSIONS_PER_USER: Final[int] = 10
|
|
101
|
+
"""Maximum number of concurrent sessions per user."""
|
|
102
|
+
|
|
103
|
+
SESSION_INACTIVITY_TIMEOUT: Final[int] = 1800 # 30 minutes
|
|
104
|
+
"""Session inactivity timeout in seconds before automatic cleanup."""
|
|
105
|
+
|
|
106
|
+
# Token versioning
|
|
107
|
+
CURRENT_TOKEN_VERSION: Final[str] = "1.0"
|
|
108
|
+
"""Current token schema version for migration support."""
|
|
109
|
+
|
|
110
|
+
# ============================================================================
|
|
111
|
+
# SCHEMA CONSTANTS
|
|
112
|
+
# ============================================================================
|
|
113
|
+
|
|
114
|
+
CURRENT_SCHEMA_VERSION: Final[str] = "2.0"
|
|
115
|
+
"""Current manifest schema version."""
|
|
116
|
+
|
|
117
|
+
DEFAULT_SCHEMA_VERSION: Final[str] = "1.0"
|
|
118
|
+
"""Default schema version for manifests without version field."""
|
|
119
|
+
|
|
120
|
+
# ============================================================================
|
|
121
|
+
# INDEX TYPE CONSTANTS
|
|
122
|
+
# ============================================================================
|
|
123
|
+
|
|
124
|
+
INDEX_TYPE_REGULAR: Final[str] = "regular"
|
|
125
|
+
INDEX_TYPE_VECTOR_SEARCH: Final[str] = "vectorSearch"
|
|
126
|
+
INDEX_TYPE_SEARCH: Final[str] = "search"
|
|
127
|
+
INDEX_TYPE_TEXT: Final[str] = "text"
|
|
128
|
+
INDEX_TYPE_GEOSPATIAL: Final[str] = "geospatial"
|
|
129
|
+
INDEX_TYPE_TTL: Final[str] = "ttl"
|
|
130
|
+
INDEX_TYPE_PARTIAL: Final[str] = "partial"
|
|
131
|
+
INDEX_TYPE_HYBRID: Final[str] = "hybrid"
|
|
132
|
+
|
|
133
|
+
# Supported index types
|
|
134
|
+
SUPPORTED_INDEX_TYPES: Final[tuple[str, ...]] = (
|
|
135
|
+
INDEX_TYPE_REGULAR,
|
|
136
|
+
INDEX_TYPE_VECTOR_SEARCH,
|
|
137
|
+
INDEX_TYPE_SEARCH,
|
|
138
|
+
INDEX_TYPE_TEXT,
|
|
139
|
+
INDEX_TYPE_GEOSPATIAL,
|
|
140
|
+
INDEX_TYPE_TTL,
|
|
141
|
+
INDEX_TYPE_PARTIAL,
|
|
142
|
+
INDEX_TYPE_HYBRID,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# ============================================================================
|
|
146
|
+
# APP STATUS CONSTANTS
|
|
147
|
+
# ============================================================================
|
|
148
|
+
|
|
149
|
+
APP_STATUS_ACTIVE: Final[str] = "active"
|
|
150
|
+
APP_STATUS_DRAFT: Final[str] = "draft"
|
|
151
|
+
APP_STATUS_ARCHIVED: Final[str] = "archived"
|
|
152
|
+
APP_STATUS_INACTIVE: Final[str] = "inactive"
|
|
153
|
+
|
|
154
|
+
# Supported app statuses
|
|
155
|
+
SUPPORTED_APP_STATUSES: Final[tuple[str, ...]] = (
|
|
156
|
+
APP_STATUS_ACTIVE,
|
|
157
|
+
APP_STATUS_DRAFT,
|
|
158
|
+
APP_STATUS_ARCHIVED,
|
|
159
|
+
APP_STATUS_INACTIVE,
|
|
160
|
+
)
|
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
# Core MongoDB Engine Module
|
|
2
|
+
|
|
3
|
+
The central orchestration engine for MDB_ENGINE that manages database connections, app registration, manifest validation, index management, and resource lifecycle.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **MongoDBEngine**: Central orchestration for all engine components
|
|
8
|
+
- **Manifest System**: JSON schema validation with versioning (v1.0, v2.0)
|
|
9
|
+
- **App Registration**: Automatic app setup with isolation and indexing
|
|
10
|
+
- **Health Checks**: Built-in health monitoring and status reporting
|
|
11
|
+
- **Connection Management**: Efficient MongoDB connection pooling
|
|
12
|
+
- **Schema Migration**: Automatic migration between manifest schema versions
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
The core module is part of MDB_ENGINE. No additional installation required.
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### Basic Usage
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from mdb_engine import MongoDBEngine
|
|
24
|
+
|
|
25
|
+
# Initialize engine
|
|
26
|
+
engine = MongoDBEngine(
|
|
27
|
+
mongo_uri="mongodb://localhost:27017",
|
|
28
|
+
db_name="my_database"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Initialize connection
|
|
32
|
+
await engine.initialize()
|
|
33
|
+
|
|
34
|
+
# Load and register app from manifest
|
|
35
|
+
manifest = await engine.load_manifest("manifest.json")
|
|
36
|
+
await engine.register_app(manifest)
|
|
37
|
+
|
|
38
|
+
# Get scoped database for app
|
|
39
|
+
db = engine.get_scoped_db("my_app")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## MongoDBEngine
|
|
43
|
+
|
|
44
|
+
The `MongoDBEngine` class is the central component that orchestrates all engine functionality.
|
|
45
|
+
|
|
46
|
+
### Initialization
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from mdb_engine import MongoDBEngine
|
|
50
|
+
|
|
51
|
+
engine = MongoDBEngine(
|
|
52
|
+
mongo_uri="mongodb://localhost:27017",
|
|
53
|
+
db_name="my_database",
|
|
54
|
+
manifests_dir=Path("./manifests"), # Optional
|
|
55
|
+
authz_provider=authz_provider, # Optional
|
|
56
|
+
max_pool_size=10, # Optional
|
|
57
|
+
min_pool_size=1 # Optional
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
await engine.initialize()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Get Scoped Database
|
|
64
|
+
|
|
65
|
+
Get a database wrapper that automatically isolates data by app:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
# Basic usage - all operations scoped to "my_app"
|
|
69
|
+
db = engine.get_scoped_db("my_app")
|
|
70
|
+
|
|
71
|
+
# Read from multiple apps, write to one
|
|
72
|
+
db = engine.get_scoped_db(
|
|
73
|
+
app_slug="my_app",
|
|
74
|
+
read_scopes=["my_app", "shared_app"], # Can read from multiple apps
|
|
75
|
+
write_scope="my_app" # Write to single app
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# Disable automatic indexing
|
|
79
|
+
db = engine.get_scoped_db("my_app", auto_index=False)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### App Registration
|
|
83
|
+
|
|
84
|
+
Register an app with the MongoDB Engine:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
# Load manifest from file
|
|
88
|
+
manifest = await engine.load_manifest("manifest.json")
|
|
89
|
+
|
|
90
|
+
# Register app (creates indexes, sets up auth, etc.)
|
|
91
|
+
await engine.register_app(manifest)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Health Checks
|
|
95
|
+
|
|
96
|
+
Check engine and MongoDB health:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from mdb_engine.observability import check_engine_health, check_mongodb_health
|
|
100
|
+
|
|
101
|
+
# Check MongoDB connection
|
|
102
|
+
mongodb_status = await check_mongodb_health(engine.mongo_client)
|
|
103
|
+
print(mongodb_status)
|
|
104
|
+
|
|
105
|
+
# Check engine health
|
|
106
|
+
engine_status = await check_engine_health(engine)
|
|
107
|
+
print(engine_status)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Get Registered Apps
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
# Get all registered apps
|
|
114
|
+
apps = engine.get_registered_apps()
|
|
115
|
+
for slug, app_info in apps.items():
|
|
116
|
+
print(f"App: {slug}, Status: {app_info['status']}")
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Manifest System
|
|
120
|
+
|
|
121
|
+
The manifest system provides JSON schema validation, versioning, and migration.
|
|
122
|
+
|
|
123
|
+
### Manifest Schema Versions
|
|
124
|
+
|
|
125
|
+
- **v1.0**: Initial schema (default for manifests without version field)
|
|
126
|
+
- **v2.0**: Current schema with all features (auth.policy, auth.users, managed_indexes, etc.)
|
|
127
|
+
|
|
128
|
+
### Manifest Structure
|
|
129
|
+
|
|
130
|
+
A basic manifest.json:
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"schema_version": "2.0",
|
|
135
|
+
"slug": "my_app",
|
|
136
|
+
"name": "My Application",
|
|
137
|
+
"description": "Application description",
|
|
138
|
+
"status": "active",
|
|
139
|
+
"auth_required": true,
|
|
140
|
+
"collections": {
|
|
141
|
+
"users": {
|
|
142
|
+
"indexes": [
|
|
143
|
+
{
|
|
144
|
+
"name": "email_idx",
|
|
145
|
+
"type": "regular",
|
|
146
|
+
"keys": {"email": 1},
|
|
147
|
+
"unique": true
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Manifest Validation
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from mdb_engine.core import ManifestValidator, validate_manifest
|
|
159
|
+
|
|
160
|
+
# Using MongoDBEngine
|
|
161
|
+
is_valid, error, paths = await engine.validate_manifest(manifest)
|
|
162
|
+
|
|
163
|
+
# Using validator directly
|
|
164
|
+
validator = ManifestValidator()
|
|
165
|
+
is_valid, error, paths = validator.validate(manifest)
|
|
166
|
+
|
|
167
|
+
# Using convenience function
|
|
168
|
+
is_valid, error, paths = validate_manifest(manifest)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Manifest Parsing
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
from mdb_engine.core import ManifestParser
|
|
175
|
+
|
|
176
|
+
parser = ManifestParser()
|
|
177
|
+
|
|
178
|
+
# Parse manifest (handles version detection and migration)
|
|
179
|
+
parsed = parser.parse(manifest)
|
|
180
|
+
|
|
181
|
+
# Get schema version
|
|
182
|
+
version = parser.get_schema_version(manifest)
|
|
183
|
+
|
|
184
|
+
# Migrate manifest to target version
|
|
185
|
+
migrated = parser.migrate(manifest, target_version="2.0")
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Schema Migration
|
|
189
|
+
|
|
190
|
+
Manifests are automatically migrated to the current schema version:
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from mdb_engine.core import migrate_manifest, get_schema_version
|
|
194
|
+
|
|
195
|
+
# Get current schema version
|
|
196
|
+
version = get_schema_version(manifest) # Returns "1.0" or "2.0"
|
|
197
|
+
|
|
198
|
+
# Migrate to latest version
|
|
199
|
+
migrated = migrate_manifest(manifest)
|
|
200
|
+
|
|
201
|
+
# Migrate to specific version
|
|
202
|
+
migrated = migrate_manifest(manifest, target_version="2.0")
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Parallel Manifest Validation
|
|
206
|
+
|
|
207
|
+
Validate multiple manifests in parallel:
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
from mdb_engine.core import validate_manifests_parallel
|
|
211
|
+
|
|
212
|
+
manifests = [
|
|
213
|
+
{"slug": "app1", ...},
|
|
214
|
+
{"slug": "app2", ...},
|
|
215
|
+
{"slug": "app3", ...}
|
|
216
|
+
]
|
|
217
|
+
|
|
218
|
+
results = await validate_manifests_parallel(manifests)
|
|
219
|
+
for slug, (is_valid, error, paths) in results.items():
|
|
220
|
+
print(f"{slug}: {'valid' if is_valid else 'invalid'}")
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Validation Cache
|
|
224
|
+
|
|
225
|
+
Validation results are cached for performance:
|
|
226
|
+
|
|
227
|
+
```python
|
|
228
|
+
from mdb_engine.core import clear_validation_cache
|
|
229
|
+
|
|
230
|
+
# Clear validation cache (useful after schema updates)
|
|
231
|
+
clear_validation_cache()
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## ManifestParser
|
|
235
|
+
|
|
236
|
+
The `ManifestParser` class handles manifest parsing, version detection, and migration.
|
|
237
|
+
|
|
238
|
+
### Basic Usage
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
from mdb_engine.core import ManifestParser
|
|
242
|
+
|
|
243
|
+
parser = ManifestParser()
|
|
244
|
+
|
|
245
|
+
# Parse manifest (auto-detects version and migrates if needed)
|
|
246
|
+
parsed = parser.parse(manifest)
|
|
247
|
+
|
|
248
|
+
# Get schema version
|
|
249
|
+
version = parser.get_schema_version(manifest)
|
|
250
|
+
|
|
251
|
+
# Check if migration is needed
|
|
252
|
+
needs_migration = parser.needs_migration(manifest)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## ManifestValidator
|
|
256
|
+
|
|
257
|
+
The `ManifestValidator` class provides schema validation with caching.
|
|
258
|
+
|
|
259
|
+
### Basic Usage
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
from mdb_engine.core import ManifestValidator
|
|
263
|
+
|
|
264
|
+
validator = ManifestValidator()
|
|
265
|
+
|
|
266
|
+
# Validate manifest
|
|
267
|
+
is_valid, error_message, error_paths = validator.validate(manifest)
|
|
268
|
+
|
|
269
|
+
if not is_valid:
|
|
270
|
+
print(f"Validation failed: {error_message}")
|
|
271
|
+
print(f"Error paths: {error_paths}")
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Validation with Database
|
|
275
|
+
|
|
276
|
+
Validate manifest and check against database:
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
from mdb_engine.core import validate_manifest_with_db
|
|
280
|
+
|
|
281
|
+
is_valid, error, paths = await validate_manifest_with_db(
|
|
282
|
+
manifest=manifest,
|
|
283
|
+
db=db
|
|
284
|
+
)
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## API Reference
|
|
288
|
+
|
|
289
|
+
### MongoDBEngine
|
|
290
|
+
|
|
291
|
+
#### Methods
|
|
292
|
+
|
|
293
|
+
- `initialize()` - Initialize MongoDB connection and engine
|
|
294
|
+
- `get_scoped_db(app_slug, read_scopes=None, write_scope=None, auto_index=True)` - Get scoped database wrapper
|
|
295
|
+
- `validate_manifest(manifest)` - Validate manifest against schema
|
|
296
|
+
- `load_manifest(path)` - Load and validate manifest from file
|
|
297
|
+
- `register_app(manifest)` - Register app with engine
|
|
298
|
+
- `get_registered_apps()` - Get all registered apps
|
|
299
|
+
- `get_app_info(app_slug)` - Get information about registered app
|
|
300
|
+
- `unregister_app(app_slug)` - Unregister an app
|
|
301
|
+
|
|
302
|
+
#### Properties
|
|
303
|
+
|
|
304
|
+
- `mongo_client` - MongoDB client instance
|
|
305
|
+
- `mongo_db` - MongoDB database instance
|
|
306
|
+
- `initialized` - Whether engine is initialized
|
|
307
|
+
|
|
308
|
+
### ManifestValidator
|
|
309
|
+
|
|
310
|
+
#### Methods
|
|
311
|
+
|
|
312
|
+
- `validate(manifest)` - Validate manifest against schema
|
|
313
|
+
- Returns: `(is_valid, error_message, error_paths)`
|
|
314
|
+
|
|
315
|
+
### ManifestParser
|
|
316
|
+
|
|
317
|
+
#### Methods
|
|
318
|
+
|
|
319
|
+
- `parse(manifest)` - Parse manifest (auto-migrates if needed)
|
|
320
|
+
- `get_schema_version(manifest)` - Get schema version of manifest
|
|
321
|
+
- `needs_migration(manifest)` - Check if migration is needed
|
|
322
|
+
- `migrate(manifest, target_version=None)` - Migrate manifest to target version
|
|
323
|
+
|
|
324
|
+
### Functions
|
|
325
|
+
|
|
326
|
+
- `validate_manifest(manifest)` - Convenience function for validation
|
|
327
|
+
- `validate_manifest_with_db(manifest, db)` - Validate with database checks
|
|
328
|
+
- `validate_managed_indexes(manifest)` - Validate managed index definitions
|
|
329
|
+
- `validate_index_definition(index_def, index_name)` - Validate single index definition
|
|
330
|
+
- `get_schema_version(manifest)` - Get schema version
|
|
331
|
+
- `migrate_manifest(manifest, target_version=None)` - Migrate manifest
|
|
332
|
+
- `get_schema_for_version(version)` - Get schema definition for version
|
|
333
|
+
- `clear_validation_cache()` - Clear validation cache
|
|
334
|
+
- `validate_manifests_parallel(manifests)` - Validate multiple manifests in parallel
|
|
335
|
+
|
|
336
|
+
## Configuration
|
|
337
|
+
|
|
338
|
+
### Environment Variables
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
# MongoDB connection pool settings
|
|
342
|
+
export MONGO_ACTOR_MAX_POOL_SIZE=10
|
|
343
|
+
export MONGO_ACTOR_MIN_POOL_SIZE=1
|
|
344
|
+
|
|
345
|
+
# Server selection timeout
|
|
346
|
+
export MONGO_SERVER_SELECTION_TIMEOUT_MS=5000
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### MongoDBEngine Parameters
|
|
350
|
+
|
|
351
|
+
- `mongo_uri` (required): MongoDB connection URI
|
|
352
|
+
- `db_name` (required): Database name
|
|
353
|
+
- `manifests_dir` (optional): Directory containing manifest files
|
|
354
|
+
- `authz_provider` (optional): Authorization provider instance
|
|
355
|
+
- `max_pool_size` (optional): Maximum connection pool size (default: 10)
|
|
356
|
+
- `min_pool_size` (optional): Minimum connection pool size (default: 1)
|
|
357
|
+
|
|
358
|
+
## Manifest Schema Features
|
|
359
|
+
|
|
360
|
+
### Collections
|
|
361
|
+
|
|
362
|
+
Define collections with indexes:
|
|
363
|
+
|
|
364
|
+
```json
|
|
365
|
+
{
|
|
366
|
+
"collections": {
|
|
367
|
+
"users": {
|
|
368
|
+
"indexes": [
|
|
369
|
+
{
|
|
370
|
+
"name": "email_idx",
|
|
371
|
+
"type": "regular",
|
|
372
|
+
"keys": {"email": 1},
|
|
373
|
+
"unique": true
|
|
374
|
+
}
|
|
375
|
+
]
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Authentication & Authorization
|
|
382
|
+
|
|
383
|
+
Configure unified authentication and authorization:
|
|
384
|
+
|
|
385
|
+
```json
|
|
386
|
+
{
|
|
387
|
+
"auth_required": true,
|
|
388
|
+
"auth_policy": {
|
|
389
|
+
"provider": "casbin",
|
|
390
|
+
"required": true,
|
|
391
|
+
"allow_anonymous": false,
|
|
392
|
+
"authorization": {
|
|
393
|
+
"model": "rbac",
|
|
394
|
+
"policies_collection": "casbin_policies",
|
|
395
|
+
"link_users_roles": true,
|
|
396
|
+
"default_roles": ["user", "admin"]
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
**Key Features:**
|
|
403
|
+
- **Auto-created Provider:** Casbin provider automatically created from manifest (default)
|
|
404
|
+
- **MongoDB-backed:** Policies stored in MongoDB collection
|
|
405
|
+
- **App-Level User Management:** App-level users automatically get Casbin roles
|
|
406
|
+
- **Extensible:** Supports custom providers, models, and manual setup
|
|
407
|
+
|
|
408
|
+
**Extensibility:**
|
|
409
|
+
- Use `"provider": "oso"` for OSO/Polar-based authorization
|
|
410
|
+
- Use `"provider": "custom"` and set `app.state.authz_provider` manually
|
|
411
|
+
- Provide custom Casbin model files via `authorization.model` path
|
|
412
|
+
- Implement `AuthorizationProvider` protocol for fully custom authorization logic
|
|
413
|
+
|
|
414
|
+
### App-Level User Management
|
|
415
|
+
|
|
416
|
+
Configure app-level user management:
|
|
417
|
+
|
|
418
|
+
```json
|
|
419
|
+
{
|
|
420
|
+
"auth": {
|
|
421
|
+
"users": {
|
|
422
|
+
"strategy": "app_users",
|
|
423
|
+
"allow_registration": true,
|
|
424
|
+
"demo_users": [
|
|
425
|
+
{
|
|
426
|
+
"email": "demo@example.com",
|
|
427
|
+
"password": "demo123",
|
|
428
|
+
"role": "user"
|
|
429
|
+
}
|
|
430
|
+
]
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Indexes
|
|
437
|
+
|
|
438
|
+
Define various index types:
|
|
439
|
+
|
|
440
|
+
```json
|
|
441
|
+
{
|
|
442
|
+
"collections": {
|
|
443
|
+
"documents": {
|
|
444
|
+
"indexes": [
|
|
445
|
+
{
|
|
446
|
+
"name": "text_search",
|
|
447
|
+
"type": "text",
|
|
448
|
+
"keys": {"title": "text", "content": "text"}
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
"name": "vector_search",
|
|
452
|
+
"type": "vector_search",
|
|
453
|
+
"definition": {
|
|
454
|
+
"fields": [{
|
|
455
|
+
"type": "vector",
|
|
456
|
+
"path": "embedding",
|
|
457
|
+
"numDimensions": 1536
|
|
458
|
+
}]
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
]
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Best Practices
|
|
468
|
+
|
|
469
|
+
1. **Always validate manifests** - Use `validate_manifest()` before registration
|
|
470
|
+
2. **Use schema versioning** - Specify `schema_version` in manifests
|
|
471
|
+
3. **Initialize once** - Create one MongoDBEngine instance per application
|
|
472
|
+
4. **Use scoped databases** - Always use `get_scoped_db()` for data isolation
|
|
473
|
+
5. **Monitor health** - Regularly check engine and MongoDB health
|
|
474
|
+
6. **Cache validation** - Validation results are cached automatically
|
|
475
|
+
7. **Handle errors** - Wrap initialization in try/except blocks
|
|
476
|
+
8. **Clean up** - Unregister apps when no longer needed
|
|
477
|
+
|
|
478
|
+
## Error Handling
|
|
479
|
+
|
|
480
|
+
```python
|
|
481
|
+
from mdb_engine.exceptions import InitializationError
|
|
482
|
+
|
|
483
|
+
try:
|
|
484
|
+
await engine.initialize()
|
|
485
|
+
except InitializationError as e:
|
|
486
|
+
print(f"Initialization failed: {e}")
|
|
487
|
+
print(f"MongoDB URI: {e.mongo_uri}")
|
|
488
|
+
except Exception as e:
|
|
489
|
+
print(f"Unexpected error: {e}")
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Integration Examples
|
|
493
|
+
|
|
494
|
+
### FastAPI Integration
|
|
495
|
+
|
|
496
|
+
```python
|
|
497
|
+
from fastapi import FastAPI
|
|
498
|
+
from mdb_engine import MongoDBEngine
|
|
499
|
+
|
|
500
|
+
app = FastAPI()
|
|
501
|
+
engine = None
|
|
502
|
+
|
|
503
|
+
@app.on_event("startup")
|
|
504
|
+
async def startup():
|
|
505
|
+
global engine
|
|
506
|
+
engine = MongoDBEngine(mongo_uri="...", db_name="...")
|
|
507
|
+
await engine.initialize()
|
|
508
|
+
|
|
509
|
+
manifest = await engine.load_manifest("manifest.json")
|
|
510
|
+
await engine.register_app(manifest)
|
|
511
|
+
|
|
512
|
+
@app.get("/data")
|
|
513
|
+
async def get_data():
|
|
514
|
+
db = engine.get_scoped_db("my_app")
|
|
515
|
+
docs = await db.collection.find({}).to_list(length=10)
|
|
516
|
+
return {"data": docs}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### Multiple Apps
|
|
520
|
+
|
|
521
|
+
```python
|
|
522
|
+
# Register multiple apps
|
|
523
|
+
manifests = [
|
|
524
|
+
await engine.load_manifest("app1/manifest.json"),
|
|
525
|
+
await engine.load_manifest("app2/manifest.json"),
|
|
526
|
+
await engine.load_manifest("app3/manifest.json")
|
|
527
|
+
]
|
|
528
|
+
|
|
529
|
+
for manifest in manifests:
|
|
530
|
+
await engine.register_app(manifest)
|
|
531
|
+
|
|
532
|
+
# Access different apps
|
|
533
|
+
db1 = engine.get_scoped_db("app1")
|
|
534
|
+
db2 = engine.get_scoped_db("app2")
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
## Related Modules
|
|
538
|
+
|
|
539
|
+
- **`database/`** - Database abstraction and scoped wrappers
|
|
540
|
+
- **`auth/`** - Authentication and authorization
|
|
541
|
+
- **`indexes/`** - Index management
|
|
542
|
+
- **`observability/`** - Health checks and metrics
|