# platform/config.py
import importlib.abc
import importlib.util
import sys
import os
from cryptography.fernet import Fernet
class TypedSetting:
"""Descriptor-based typed setting with optional encryption."""
def __init__(self, expected_type, default=None, encrypted=False, required=True):
self.expected_type = expected_type
self.default = default
self.encrypted = encrypted
self.required = required
self.name = None
self.private = None
def __set_name__(self, owner, name):
self.name = name
self.private = f"_cfg_{name}"
def __get__(self, obj, objtype=None):
if obj is None:
return self
return getattr(obj, self.private, self.default)
def __set__(self, obj, value):
if value is not None and not isinstance(value, self.expected_type):
raise TypeError(
f"Config '{self.name}': expected {self.expected_type.__name__}, "
f"got {type(value).__name__}"
)
setattr(obj, self.private, value)
class PlatformConfig:
"""Production configuration with typed descriptors."""
app_name = TypedSetting(str, default="platform-api")
host = TypedSetting(str, default="0.0.0.0")
port = TypedSetting(int, default=8080)
debug = TypedSetting(bool, default=False)
db_url = TypedSetting(str, encrypted=True, required=True)
api_key = TypedSetting(str, encrypted=True, required=True)
max_conns = TypedSetting(int, default=100)
def __init__(self, **kwargs):
for k, v in kwargs.items():
if hasattr(type(self), k):
setattr(self, k, v)
def to_dict(self, mask_secrets=True) -> dict:
result = {}
for name in dir(type(self)):
attr = getattr(type(self), name)
if isinstance(attr, TypedSetting):
val = getattr(self, name)
if mask_secrets and attr.encrypted and val:
val = "***"
result[name] = val
return result
# Config import hook
class ConfigFinder(importlib.abc.MetaPathFinder):
"""Load configuration from environment when importing 'platform_config'."""
def find_spec(self, fullname, path, target=None):
if fullname == "platform_config":
loader = ConfigLoader()
return importlib.util.spec_from_loader(fullname, loader)
return None
class ConfigLoader(importlib.abc.Loader):
def create_module(self, spec): return None
def exec_module(self, module):
module.config = PlatformConfig(
app_name=os.environ.get("APP_NAME", "platform-api"),
host=os.environ.get("HOST", "0.0.0.0"),
port=int(os.environ.get("PORT", "8080")),
debug=os.environ.get("DEBUG", "false").lower() == "true",
db_url=os.environ.get("DB_URL", "postgresql://localhost/app"),
api_key=os.environ.get("API_KEY", "default-dev-key"),
)
sys.meta_path.insert(0, ConfigFinder())
# Test config
import platform_config
cfg = platform_config.config
print(f"Config loaded: app={cfg.app_name}, port={cfg.port}, debug={cfg.debug}")
print(f"Config (masked): {cfg.to_dict(mask_secrets=True)}")