81 lines
3 KiB
Python
81 lines
3 KiB
Python
from pydantic_settings import BaseSettings
|
|
from typing import Optional, List
|
|
from pydantic import field_validator, ConfigDict
|
|
import json
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
# Database
|
|
database_url: str = "sqlite+aiosqlite:///./mockapi.db"
|
|
|
|
# Application
|
|
debug: bool = False
|
|
title: str = "Mock API Server"
|
|
version: str = "1.0.0"
|
|
log_level: str = "INFO"
|
|
host: str = "0.0.0.0"
|
|
port: int = 8000
|
|
|
|
# Admin authentication
|
|
admin_username: str = "admin"
|
|
admin_password: str = "admin123"
|
|
secret_key: str = "your-secret-key-here-change-me"
|
|
|
|
# Security
|
|
session_cookie_name: str = "mockapi_session"
|
|
session_max_age: int = 24 * 60 * 60 # 24 hours
|
|
|
|
# OAuth2 Settings
|
|
oauth2_issuer: str = "http://localhost:8000" # Used for discovery
|
|
oauth2_access_token_expire_minutes: int = 30
|
|
oauth2_refresh_token_expire_days: int = 7
|
|
oauth2_authorization_code_expire_minutes: int = 10
|
|
oauth2_supported_grant_types: List[str] = ["authorization_code", "client_credentials", "refresh_token"]
|
|
oauth2_supported_scopes: List[str] = ["openid", "profile", "email", "api:read", "api:write"]
|
|
oauth2_pkce_required: bool = False # Future enhancement
|
|
|
|
@field_validator('admin_password')
|
|
def validate_admin_password(cls, v, info):
|
|
if not info.data.get('debug', True) and v == "admin123":
|
|
raise ValueError(
|
|
'admin_password must be set via environment variable in production (debug=False)'
|
|
)
|
|
return v
|
|
|
|
@field_validator('secret_key')
|
|
def validate_secret_key(cls, v, info):
|
|
if not info.data.get('debug', True) and v == "your-secret-key-here-change-me":
|
|
raise ValueError(
|
|
'secret_key must be set via environment variable in production (debug=False)'
|
|
)
|
|
return v
|
|
|
|
@field_validator('oauth2_supported_scopes', 'oauth2_supported_grant_types', mode='before')
|
|
@classmethod
|
|
def parse_list_from_string(cls, v):
|
|
"""Parse list from either JSON string or space/comma-separated string."""
|
|
if isinstance(v, list):
|
|
return v
|
|
if isinstance(v, str):
|
|
# Try to parse as JSON first
|
|
try:
|
|
return json.loads(v)
|
|
except json.JSONDecodeError:
|
|
# If not JSON, try comma-separated or space-separated
|
|
# Remove quotes and split by commas or spaces
|
|
v = v.strip()
|
|
if ',' in v:
|
|
# Comma-separated
|
|
items = [item.strip().strip('"\'') for item in v.split(',')]
|
|
else:
|
|
# Space-separated
|
|
items = [item.strip().strip('"\'') for item in v.split()]
|
|
# Filter out empty strings
|
|
return [item for item in items if item]
|
|
# Return as-is for other types (should be list)
|
|
return v
|
|
|
|
model_config = ConfigDict(env_file=".env", extra="allow")
|
|
|
|
|
|
settings = Settings()
|