mdb-engine 0.1.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. mdb_engine/README.md +144 -0
  2. mdb_engine/__init__.py +37 -0
  3. mdb_engine/auth/README.md +631 -0
  4. mdb_engine/auth/__init__.py +128 -0
  5. mdb_engine/auth/casbin_factory.py +199 -0
  6. mdb_engine/auth/casbin_models.py +46 -0
  7. mdb_engine/auth/config_defaults.py +71 -0
  8. mdb_engine/auth/config_helpers.py +213 -0
  9. mdb_engine/auth/cookie_utils.py +158 -0
  10. mdb_engine/auth/decorators.py +350 -0
  11. mdb_engine/auth/dependencies.py +747 -0
  12. mdb_engine/auth/helpers.py +64 -0
  13. mdb_engine/auth/integration.py +578 -0
  14. mdb_engine/auth/jwt.py +225 -0
  15. mdb_engine/auth/middleware.py +241 -0
  16. mdb_engine/auth/oso_factory.py +323 -0
  17. mdb_engine/auth/provider.py +570 -0
  18. mdb_engine/auth/restrictions.py +271 -0
  19. mdb_engine/auth/session_manager.py +477 -0
  20. mdb_engine/auth/token_lifecycle.py +213 -0
  21. mdb_engine/auth/token_store.py +289 -0
  22. mdb_engine/auth/users.py +1516 -0
  23. mdb_engine/auth/utils.py +614 -0
  24. mdb_engine/cli/__init__.py +13 -0
  25. mdb_engine/cli/commands/__init__.py +7 -0
  26. mdb_engine/cli/commands/generate.py +105 -0
  27. mdb_engine/cli/commands/migrate.py +83 -0
  28. mdb_engine/cli/commands/show.py +70 -0
  29. mdb_engine/cli/commands/validate.py +63 -0
  30. mdb_engine/cli/main.py +41 -0
  31. mdb_engine/cli/utils.py +92 -0
  32. mdb_engine/config.py +217 -0
  33. mdb_engine/constants.py +160 -0
  34. mdb_engine/core/README.md +542 -0
  35. mdb_engine/core/__init__.py +42 -0
  36. mdb_engine/core/app_registration.py +392 -0
  37. mdb_engine/core/connection.py +243 -0
  38. mdb_engine/core/engine.py +749 -0
  39. mdb_engine/core/index_management.py +162 -0
  40. mdb_engine/core/manifest.py +2793 -0
  41. mdb_engine/core/seeding.py +179 -0
  42. mdb_engine/core/service_initialization.py +355 -0
  43. mdb_engine/core/types.py +413 -0
  44. mdb_engine/database/README.md +522 -0
  45. mdb_engine/database/__init__.py +31 -0
  46. mdb_engine/database/abstraction.py +635 -0
  47. mdb_engine/database/connection.py +387 -0
  48. mdb_engine/database/scoped_wrapper.py +1721 -0
  49. mdb_engine/embeddings/README.md +184 -0
  50. mdb_engine/embeddings/__init__.py +62 -0
  51. mdb_engine/embeddings/dependencies.py +193 -0
  52. mdb_engine/embeddings/service.py +759 -0
  53. mdb_engine/exceptions.py +167 -0
  54. mdb_engine/indexes/README.md +651 -0
  55. mdb_engine/indexes/__init__.py +21 -0
  56. mdb_engine/indexes/helpers.py +145 -0
  57. mdb_engine/indexes/manager.py +895 -0
  58. mdb_engine/memory/README.md +451 -0
  59. mdb_engine/memory/__init__.py +30 -0
  60. mdb_engine/memory/service.py +1285 -0
  61. mdb_engine/observability/README.md +515 -0
  62. mdb_engine/observability/__init__.py +42 -0
  63. mdb_engine/observability/health.py +296 -0
  64. mdb_engine/observability/logging.py +161 -0
  65. mdb_engine/observability/metrics.py +297 -0
  66. mdb_engine/routing/README.md +462 -0
  67. mdb_engine/routing/__init__.py +73 -0
  68. mdb_engine/routing/websockets.py +813 -0
  69. mdb_engine/utils/__init__.py +7 -0
  70. mdb_engine-0.1.6.dist-info/METADATA +213 -0
  71. mdb_engine-0.1.6.dist-info/RECORD +75 -0
  72. mdb_engine-0.1.6.dist-info/WHEEL +5 -0
  73. mdb_engine-0.1.6.dist-info/entry_points.txt +2 -0
  74. mdb_engine-0.1.6.dist-info/licenses/LICENSE +661 -0
  75. mdb_engine-0.1.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,105 @@
1
+ """
2
+ Generate command for CLI.
3
+
4
+ Generates a template manifest.json file.
5
+
6
+ This module is part of MDB_ENGINE - MongoDB Engine.
7
+ """
8
+
9
+ import sys
10
+ from pathlib import Path
11
+ from typing import Any, Dict
12
+
13
+ import click
14
+
15
+ from ...core.manifest import CURRENT_SCHEMA_VERSION
16
+ from ..utils import save_manifest_file
17
+
18
+
19
+ @click.command()
20
+ @click.option(
21
+ "--slug",
22
+ "-s",
23
+ prompt="App slug",
24
+ help="App slug (lowercase alphanumeric, underscores, hyphens)",
25
+ )
26
+ @click.option(
27
+ "--name",
28
+ "-n",
29
+ prompt="App name",
30
+ help="Human-readable app name",
31
+ )
32
+ @click.option(
33
+ "--description",
34
+ "-d",
35
+ default="",
36
+ help="App description",
37
+ )
38
+ @click.option(
39
+ "--output",
40
+ "-o",
41
+ default="manifest.json",
42
+ type=click.Path(path_type=Path),
43
+ help="Output file path (default: manifest.json)",
44
+ )
45
+ @click.option(
46
+ "--minimal",
47
+ "-m",
48
+ is_flag=True,
49
+ help="Generate minimal template (basic fields only)",
50
+ )
51
+ def generate(
52
+ slug: str,
53
+ name: str,
54
+ description: str,
55
+ output: Path,
56
+ minimal: bool,
57
+ ) -> None:
58
+ """
59
+ Generate a template manifest.json file.
60
+
61
+ Examples:
62
+ mdb generate --slug my-app --name "My App"
63
+ mdb generate --slug my-app --name "My App" --output custom.json
64
+ mdb generate --slug my-app --name "My App" --minimal
65
+ """
66
+ try:
67
+ # Validate slug format
68
+ if not slug or not all(c.isalnum() or c in ("_", "-") for c in slug):
69
+ raise click.ClickException(
70
+ "Invalid slug format. Use lowercase alphanumeric, underscores, or hyphens."
71
+ )
72
+
73
+ # Generate template manifest
74
+ manifest: Dict[str, Any] = {
75
+ "schema_version": CURRENT_SCHEMA_VERSION,
76
+ "slug": slug,
77
+ "name": name,
78
+ "status": "draft",
79
+ }
80
+
81
+ if description:
82
+ manifest["description"] = description
83
+
84
+ if not minimal:
85
+ # Add common sections
86
+ manifest["auth"] = {
87
+ "policy": {
88
+ "provider": "casbin",
89
+ "required": False,
90
+ "allow_anonymous": True,
91
+ "authorization": {
92
+ "model": "rbac",
93
+ "link_users_roles": True,
94
+ },
95
+ },
96
+ }
97
+ manifest["managed_indexes"] = {}
98
+ manifest["websockets"] = {}
99
+
100
+ # Save manifest
101
+ save_manifest_file(output, manifest)
102
+ click.echo(click.style(f"✅ Generated manifest template: {output}", fg="green"))
103
+ sys.exit(0)
104
+ except click.ClickException:
105
+ raise
@@ -0,0 +1,83 @@
1
+ """
2
+ Migrate command for CLI.
3
+
4
+ Migrates a manifest to a target schema version.
5
+
6
+ This module is part of MDB_ENGINE - MongoDB Engine.
7
+ """
8
+
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ import click
13
+
14
+ from ...core.manifest import CURRENT_SCHEMA_VERSION, migrate_manifest
15
+ from ..utils import load_manifest_file, save_manifest_file
16
+
17
+
18
+ @click.command()
19
+ @click.argument("manifest_file", type=click.Path(exists=True, path_type=Path))
20
+ @click.option(
21
+ "--target-version",
22
+ "-t",
23
+ default=CURRENT_SCHEMA_VERSION,
24
+ help=f"Target schema version (default: {CURRENT_SCHEMA_VERSION})",
25
+ )
26
+ @click.option(
27
+ "--output",
28
+ "-o",
29
+ type=click.Path(path_type=Path),
30
+ help="Output file path (default: stdout)",
31
+ )
32
+ @click.option(
33
+ "--in-place",
34
+ "-i",
35
+ is_flag=True,
36
+ help="Update manifest file in place",
37
+ )
38
+ def migrate(
39
+ manifest_file: Path,
40
+ target_version: str,
41
+ output: Path | None,
42
+ in_place: bool,
43
+ ) -> None:
44
+ """
45
+ Migrate a manifest.json file to a target schema version.
46
+
47
+ MANIFEST_FILE: Path to manifest.json file to migrate
48
+
49
+ Examples:
50
+ mdb migrate manifest.json
51
+ mdb migrate manifest.json --target-version 2.0 --output manifest.v2.json
52
+ mdb migrate manifest.json --in-place
53
+ """
54
+ try:
55
+ # Load manifest
56
+ manifest = load_manifest_file(manifest_file)
57
+
58
+ # Migrate
59
+ migrated_manifest = migrate_manifest(manifest, target_version=target_version)
60
+
61
+ # Determine output
62
+ if in_place:
63
+ output_path = manifest_file
64
+ elif output:
65
+ output_path = output
66
+ else:
67
+ # Output to stdout
68
+ import json
69
+
70
+ click.echo(json.dumps(migrated_manifest, indent=2, ensure_ascii=False))
71
+ sys.exit(0)
72
+
73
+ # Save to file
74
+ save_manifest_file(output_path, migrated_manifest)
75
+ click.echo(
76
+ click.style(
77
+ f"✅ Migrated manifest to version {target_version}: {output_path}",
78
+ fg="green",
79
+ )
80
+ )
81
+ sys.exit(0)
82
+ except click.ClickException:
83
+ raise
@@ -0,0 +1,70 @@
1
+ """
2
+ Show command for CLI.
3
+
4
+ Displays manifest information.
5
+
6
+ This module is part of MDB_ENGINE - MongoDB Engine.
7
+ """
8
+
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ import click
13
+
14
+ from ...core.manifest import ManifestValidator
15
+ from ..utils import format_manifest_output, load_manifest_file
16
+
17
+
18
+ @click.command()
19
+ @click.argument("manifest_file", type=click.Path(exists=True, path_type=Path))
20
+ @click.option(
21
+ "--format",
22
+ "-f",
23
+ type=click.Choice(["json", "yaml", "pretty"], case_sensitive=False),
24
+ default="json",
25
+ help="Output format (default: json)",
26
+ )
27
+ @click.option(
28
+ "--validate",
29
+ "-v",
30
+ is_flag=True,
31
+ help="Validate manifest before showing",
32
+ )
33
+ def show(manifest_file: Path, format: str, validate: bool) -> None:
34
+ """
35
+ Display manifest information.
36
+
37
+ MANIFEST_FILE: Path to manifest.json file to display
38
+
39
+ Examples:
40
+ mdb show manifest.json
41
+ mdb show manifest.json --format pretty
42
+ mdb show manifest.json --format yaml --validate
43
+ """
44
+ try:
45
+ # Load manifest
46
+ manifest = load_manifest_file(manifest_file)
47
+
48
+ # Validate if requested
49
+ if validate:
50
+ validator = ManifestValidator()
51
+ is_valid, error_message, error_paths = validator.validate(manifest)
52
+ if not is_valid:
53
+ click.echo(
54
+ click.style(
55
+ f"⚠️ Warning: Manifest is invalid: {error_message}",
56
+ fg="yellow",
57
+ ),
58
+ err=True,
59
+ )
60
+ if error_paths:
61
+ click.echo("Error paths:", err=True)
62
+ for path in error_paths:
63
+ click.echo(f" - {path}", err=True)
64
+
65
+ # Format and display
66
+ output = format_manifest_output(manifest, format.lower())
67
+ click.echo(output)
68
+ sys.exit(0)
69
+ except click.ClickException:
70
+ raise
@@ -0,0 +1,63 @@
1
+ """
2
+ Validate command for CLI.
3
+
4
+ Validates a manifest against the schema.
5
+
6
+ This module is part of MDB_ENGINE - MongoDB Engine.
7
+ """
8
+
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ import click
13
+
14
+ from ...core.manifest import ManifestValidator
15
+ from ..utils import load_manifest_file
16
+
17
+
18
+ @click.command()
19
+ @click.argument("manifest_file", type=click.Path(exists=True, path_type=Path))
20
+ @click.option(
21
+ "--verbose",
22
+ "-v",
23
+ is_flag=True,
24
+ help="Show detailed validation errors",
25
+ )
26
+ def validate(manifest_file: Path, verbose: bool) -> None:
27
+ """
28
+ Validate a manifest.json file against the schema.
29
+
30
+ MANIFEST_FILE: Path to manifest.json file to validate
31
+
32
+ Examples:
33
+ mdb validate manifest.json
34
+ mdb validate path/to/manifest.json --verbose
35
+ """
36
+ try:
37
+ # Load manifest
38
+ manifest = load_manifest_file(manifest_file)
39
+
40
+ # Validate
41
+ validator = ManifestValidator()
42
+ is_valid, error_message, error_paths = validator.validate(manifest)
43
+
44
+ if is_valid:
45
+ click.echo(
46
+ click.style(f"✅ Manifest '{manifest_file}' is valid!", fg="green")
47
+ )
48
+ sys.exit(0)
49
+ else:
50
+ click.echo(
51
+ click.style(f"❌ Manifest '{manifest_file}' is invalid!", fg="red")
52
+ )
53
+ if error_message:
54
+ click.echo(click.style(f"Error: {error_message}", fg="red"))
55
+ if error_paths and verbose:
56
+ click.echo("\nError paths:")
57
+ for path in error_paths:
58
+ click.echo(f" - {path}")
59
+ sys.exit(1)
60
+ except click.ClickException:
61
+ raise
62
+ except (FileNotFoundError, ValueError, KeyError) as e:
63
+ raise click.ClickException(str(e))
mdb_engine/cli/main.py ADDED
@@ -0,0 +1,41 @@
1
+ """
2
+ Main CLI entry point for MDB_ENGINE.
3
+
4
+ This module provides the command-line interface for manifest management.
5
+
6
+ This module is part of MDB_ENGINE - MongoDB Engine.
7
+ """
8
+
9
+ import click
10
+
11
+ from .commands.generate import generate
12
+ from .commands.migrate import migrate
13
+ from .commands.show import show
14
+ from .commands.validate import validate
15
+
16
+
17
+ @click.group()
18
+ @click.version_option(version="0.1.6", prog_name="mdb")
19
+ def cli() -> None:
20
+ """
21
+ MDB_ENGINE CLI - Manifest management tool.
22
+
23
+ Manage your MDB_ENGINE manifests with validation, migration, and generation.
24
+ """
25
+ pass
26
+
27
+
28
+ # Register commands
29
+ cli.add_command(validate)
30
+ cli.add_command(migrate)
31
+ cli.add_command(generate)
32
+ cli.add_command(show)
33
+
34
+
35
+ def main() -> None:
36
+ """Entry point for the CLI."""
37
+ cli()
38
+
39
+
40
+ if __name__ == "__main__":
41
+ main()
@@ -0,0 +1,92 @@
1
+ """
2
+ Utility functions for CLI commands.
3
+
4
+ This module provides shared utilities for CLI operations.
5
+
6
+ This module is part of MDB_ENGINE - MongoDB Engine.
7
+ """
8
+
9
+ import json
10
+ from pathlib import Path
11
+ from typing import Any, Dict
12
+
13
+ import click
14
+
15
+
16
+ def load_manifest_file(file_path: Path) -> Dict[str, Any]:
17
+ """
18
+ Load a manifest JSON file.
19
+
20
+ Args:
21
+ file_path: Path to manifest.json file
22
+
23
+ Returns:
24
+ Manifest dictionary
25
+
26
+ Raises:
27
+ click.ClickException: If file doesn't exist or is invalid JSON
28
+ """
29
+ if not file_path.exists():
30
+ raise click.ClickException(f"Manifest file not found: {file_path}")
31
+
32
+ try:
33
+ with open(file_path, "r", encoding="utf-8") as f:
34
+ return json.load(f)
35
+ except json.JSONDecodeError as e:
36
+ raise click.ClickException(f"Invalid JSON in manifest file: {e}")
37
+
38
+
39
+ def save_manifest_file(file_path: Path, manifest: Dict[str, Any]) -> None:
40
+ """
41
+ Save a manifest dictionary to a JSON file.
42
+
43
+ Args:
44
+ file_path: Path to save manifest.json file
45
+ manifest: Manifest dictionary
46
+
47
+ Raises:
48
+ click.ClickException: If file cannot be written
49
+ """
50
+ try:
51
+ with open(file_path, "w", encoding="utf-8") as f:
52
+ json.dump(manifest, f, indent=2, ensure_ascii=False)
53
+ except OSError as e:
54
+ raise click.ClickException(f"Failed to write manifest file: {e}")
55
+
56
+
57
+ def format_manifest_output(manifest: Dict[str, Any], format_type: str) -> str:
58
+ """
59
+ Format manifest for output.
60
+
61
+ Args:
62
+ manifest: Manifest dictionary
63
+ format_type: Output format ('json', 'yaml', 'pretty')
64
+
65
+ Returns:
66
+ Formatted string representation
67
+ """
68
+ if format_type == "json":
69
+ return json.dumps(manifest, indent=2, ensure_ascii=False)
70
+ elif format_type == "yaml":
71
+ try:
72
+ import yaml
73
+
74
+ return yaml.dump(manifest, default_flow_style=False, sort_keys=False)
75
+ except ImportError:
76
+ click.echo(
77
+ "Warning: PyYAML not installed. Falling back to JSON format.",
78
+ err=True,
79
+ )
80
+ return json.dumps(manifest, indent=2, ensure_ascii=False)
81
+ elif format_type == "pretty":
82
+ # Pretty print with key information
83
+ lines = []
84
+ lines.append(f"Schema Version: {manifest.get('schema_version', '2.0')}")
85
+ lines.append(f"Slug: {manifest.get('slug', 'N/A')}")
86
+ lines.append(f"Name: {manifest.get('name', 'N/A')}")
87
+ lines.append(f"Status: {manifest.get('status', 'draft')}")
88
+ if manifest.get("description"):
89
+ lines.append(f"Description: {manifest.get('description')}")
90
+ return "\n".join(lines)
91
+ else:
92
+ return json.dumps(manifest, indent=2, ensure_ascii=False)
mdb_engine/config.py ADDED
@@ -0,0 +1,217 @@
1
+ """
2
+ Configuration management for MDB_ENGINE.
3
+
4
+ This module provides optional configuration management using Pydantic.
5
+ It's designed to be non-breaking - the MongoDBEngine can still be used
6
+ with direct parameters as before.
7
+ """
8
+
9
+ import os
10
+ from typing import Optional
11
+
12
+ try:
13
+ from pydantic import BaseSettings, Field
14
+
15
+ PYDANTIC_AVAILABLE = True
16
+ except ImportError:
17
+ PYDANTIC_AVAILABLE = False
18
+
19
+ # Create a dummy BaseSettings for when Pydantic is not available
20
+ class BaseSettings:
21
+ pass
22
+
23
+
24
+ class EngineConfig:
25
+ """
26
+ MongoDB Engine configuration.
27
+
28
+ This class provides configuration management with environment variable
29
+ support. It's optional - MongoDBEngine can still be initialized with
30
+ direct parameters for backward compatibility.
31
+
32
+ Example:
33
+ # Using environment variables
34
+ config = EngineConfig()
35
+ engine = MongoDBEngine(
36
+ mongo_uri=config.mongo_uri,
37
+ db_name=config.db_name
38
+ )
39
+
40
+ # Or using direct parameters (backward compatible)
41
+ engine = MongoDBEngine(
42
+ mongo_uri="mongodb://localhost:27017",
43
+ db_name="my_db"
44
+ )
45
+ """
46
+
47
+ def __init__(
48
+ 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,
55
+ ):
56
+ """
57
+ Initialize configuration.
58
+
59
+ Args:
60
+ mongo_uri: MongoDB connection URI (defaults to MONGO_URI env var)
61
+ db_name: Database name (defaults to DB_NAME env var)
62
+ max_pool_size: Maximum connection pool size (defaults to 50 or MONGO_MAX_POOL_SIZE)
63
+ min_pool_size: Minimum connection pool size (defaults to 10 or MONGO_MIN_POOL_SIZE)
64
+ server_selection_timeout_ms: Server selection timeout in ms (defaults to 5000)
65
+ authz_cache_ttl: Authorization cache TTL in seconds (defaults to 300)
66
+ """
67
+ self.mongo_uri = mongo_uri or os.getenv("MONGO_URI", "")
68
+ self.db_name = db_name or os.getenv("DB_NAME", "")
69
+ self.max_pool_size = max_pool_size or int(
70
+ os.getenv("MONGO_MAX_POOL_SIZE", "50")
71
+ )
72
+ self.min_pool_size = min_pool_size or int(
73
+ os.getenv("MONGO_MIN_POOL_SIZE", "10")
74
+ )
75
+ self.server_selection_timeout_ms = server_selection_timeout_ms or int(
76
+ os.getenv("MONGO_SERVER_SELECTION_TIMEOUT_MS", "5000")
77
+ )
78
+ self.authz_cache_ttl = authz_cache_ttl or int(
79
+ os.getenv("AUTHZ_CACHE_TTL", "300")
80
+ )
81
+
82
+ def validate(self) -> None:
83
+ """
84
+ Validate configuration values.
85
+
86
+ Raises:
87
+ ValueError: If required configuration is missing or invalid
88
+ """
89
+ if not self.mongo_uri:
90
+ raise ValueError(
91
+ "mongo_uri is required (set MONGO_URI environment variable or pass directly)"
92
+ )
93
+
94
+ if not self.db_name:
95
+ raise ValueError(
96
+ "db_name is required (set DB_NAME environment variable or pass directly)"
97
+ )
98
+
99
+ if self.max_pool_size < 1:
100
+ raise ValueError(f"max_pool_size must be >= 1, got {self.max_pool_size}")
101
+
102
+ if self.min_pool_size < 1:
103
+ raise ValueError(f"min_pool_size must be >= 1, got {self.min_pool_size}")
104
+
105
+ if self.min_pool_size > self.max_pool_size:
106
+ raise ValueError(
107
+ f"min_pool_size ({self.min_pool_size}) cannot be greater than "
108
+ f"max_pool_size ({self.max_pool_size})"
109
+ )
110
+
111
+ if self.server_selection_timeout_ms < 1000:
112
+ raise ValueError(
113
+ f"server_selection_timeout_ms must be >= 1000, got "
114
+ f"{self.server_selection_timeout_ms}"
115
+ )
116
+
117
+ if self.authz_cache_ttl < 0:
118
+ raise ValueError(
119
+ f"authz_cache_ttl must be >= 0, got {self.authz_cache_ttl}"
120
+ )
121
+
122
+
123
+ # Pydantic-based configuration (optional, only if Pydantic is available)
124
+ if PYDANTIC_AVAILABLE:
125
+
126
+ class EngineConfigPydantic(BaseSettings):
127
+ """
128
+ Pydantic-based configuration with automatic validation.
129
+
130
+ This is an optional alternative to EngineConfig that provides
131
+ automatic validation and type checking via Pydantic.
132
+
133
+ Usage:
134
+ config = EngineConfigPydantic()
135
+ engine = MongoDBEngine(
136
+ mongo_uri=config.mongo_uri,
137
+ db_name=config.db_name
138
+ )
139
+ """
140
+
141
+ mongo_uri: str = Field(
142
+ ..., env="MONGO_URI", description="MongoDB connection URI"
143
+ )
144
+ db_name: str = Field(..., env="DB_NAME", description="Database name")
145
+ max_pool_size: int = Field(
146
+ 50,
147
+ env="MONGO_MAX_POOL_SIZE",
148
+ ge=1,
149
+ description="Maximum connection pool size",
150
+ )
151
+ min_pool_size: int = Field(
152
+ 10,
153
+ env="MONGO_MIN_POOL_SIZE",
154
+ ge=1,
155
+ description="Minimum connection pool size",
156
+ )
157
+ server_selection_timeout_ms: int = Field(
158
+ 5000,
159
+ env="MONGO_SERVER_SELECTION_TIMEOUT_MS",
160
+ ge=1000,
161
+ description="Server selection timeout in milliseconds",
162
+ )
163
+ authz_cache_ttl: int = Field(
164
+ 300,
165
+ env="AUTHZ_CACHE_TTL",
166
+ ge=0,
167
+ description="Authorization cache TTL in seconds",
168
+ )
169
+
170
+ class Config:
171
+ env_file = ".env"
172
+ case_sensitive = False
173
+
174
+
175
+ # ============================================================================
176
+ # DEMO MODE CONSTANTS
177
+ # ============================================================================
178
+
179
+ DEMO_ENABLED: bool = os.getenv("DEMO_ENABLED", "false").lower() == "true"
180
+ """Whether demo mode is enabled."""
181
+
182
+ DEMO_EMAIL_DEFAULT: str = os.getenv("DEMO_EMAIL_DEFAULT", "demo@example.com")
183
+ """Default email for demo user."""
184
+
185
+ DEMO_PASSWORD_DEFAULT: str = os.getenv("DEMO_PASSWORD_DEFAULT", "demo123")
186
+ """Default password for demo user."""
187
+
188
+ # MongoDB connection defaults (for backward compatibility)
189
+ MONGO_URI: str = os.getenv("MONGO_URI", "")
190
+ """MongoDB connection URI (from environment variable)."""
191
+
192
+ DB_NAME: str = os.getenv("DB_NAME", "")
193
+ """Database name (from environment variable)."""
194
+
195
+ # ============================================================================
196
+ # TOKEN MANAGEMENT CONFIGURATION
197
+ # ============================================================================
198
+
199
+ # Token lifetimes (can be overridden via environment variables)
200
+ ACCESS_TOKEN_TTL: int = int(os.getenv("ACCESS_TOKEN_TTL", "900")) # 15 minutes
201
+ """Access token TTL in seconds (default: 900 / 15 minutes)."""
202
+
203
+ REFRESH_TOKEN_TTL: int = int(os.getenv("REFRESH_TOKEN_TTL", "604800")) # 7 days
204
+ """Refresh token TTL in seconds (default: 604800 / 7 days)."""
205
+
206
+ TOKEN_ROTATION_ENABLED: bool = (
207
+ os.getenv("TOKEN_ROTATION_ENABLED", "true").lower() == "true"
208
+ )
209
+ """Whether to rotate refresh tokens on each use (default: true)."""
210
+
211
+ MAX_SESSIONS_PER_USER: int = int(os.getenv("MAX_SESSIONS_PER_USER", "10"))
212
+ """Maximum number of concurrent sessions per user (default: 10)."""
213
+
214
+ SESSION_INACTIVITY_TIMEOUT: int = int(
215
+ os.getenv("SESSION_INACTIVITY_TIMEOUT", "1800")
216
+ ) # 30 minutes
217
+ """Session inactivity timeout in seconds (default: 1800 / 30 minutes)."""