infrasynth-backend-kit/infrasynth/configs/__init__.py
jcv-dev a2930426b4 feat: tenant configs, live signals, and automatic permission management
- infrasynth.configs: typed multi-tenant config store (registry, service,
  secrets, cache) + public config_changed/config_reset signals and API
- emit the declared-but-dead signals (features flags/overrides, scheduler
  task_completed/task_failed, tenancy tenant_updated, audit model_changed)
  and per-model audit field exclusions
- security: permission catalog (security_permission), Django-style
  model-derived AutoPermission, PermissionRegistry, RoleAssignment,
  global-or-tenant Grant/Revoke, catalog API
- consolidate the permission surface: PermissionRegistry only (drop the
  settings dict), IsAuthenticatedAndPermitted aliases HybridPermission,
  require_permission replaced by required_permissions + require_all
- packaging: add [build-system]; add Forgejo publish workflow (.forgejo)
2026-09-29 17:06:54 -05:00

49 lines
1.4 KiB
Python

"""Public surface of ``infrasynth.configs``.
The exports are resolved lazily (PEP 562) so importing this package never
triggers Django model imports before the app registry is ready. Import from
here::
from infrasynth.configs import ConfigService, ConfigRegistry, config_changed
"""
from __future__ import annotations
from importlib import import_module
from typing import Any
__all__ = [
"ConfigDefinition",
"ConfigRegistry",
"ConfigService",
"ConfigType",
"ConfigValue",
"config_changed",
"config_reset",
]
# public name -> module (relative to the ``infrasynth`` package) that defines it
_EXPORTS: dict[str, str] = {
"ConfigDefinition": "configs.registry",
"ConfigRegistry": "configs.registry",
"ConfigService": "configs.services",
"ConfigType": "configs.registry",
"ConfigValue": "configs.models",
"config_changed": "configs.signals",
"config_reset": "configs.signals",
}
def __getattr__(name: str) -> Any:
module_path = _EXPORTS.get(name)
if module_path is not None:
return getattr(import_module(f"infrasynth.{module_path}"), name)
# Let ``infrasynth.<app>.<submodule>`` resolve as usual.
try:
return import_module(f"{__name__}.{name}")
except ModuleNotFoundError as exc:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from exc
def __dir__() -> list[str]:
return sorted(set(__all__) | set(globals()))