Files
arc53-machine f882ef49a7 refactor: read settings directly instead of getattr with a second default
About 85 call sites read a setting as getattr(settings, "NAME", fallback),
each carrying its own copy of the default. Every one of those names is a
field with a default on the model, so the fallback could never apply to
the real settings object; it only masked drift. Two had drifted:

- OPENAI_PROMPT_CACHE_KEY defaults to True on the model but the reader
  fell back to False, and two test stubs relied on that.
- SharePoint's MICROSOFT_AUTHORITY fallback to
  https://login.microsoftonline.com/<tenant> never fired, because the
  attribute always exists (as None), so MSAL got authority=None. The
  connector now derives the tenant authority when the setting is unset,
  as its test always assumed.

Four places read EMBEDDINGS_KEY straight from os.environ, skipping the
"None"/"" normalisation the model applies; they read the setting now.
Test stubs that replaced a module's settings with a SimpleNamespace list
every setting the code under test reads.
2026-09-17 11:14:34 +01:00

64 lines
2.0 KiB
Python

"""Registry of guardrail checks."""
from __future__ import annotations
from typing import Any, Dict, List, Optional, Type
from docsgpt.core.settings import settings
from docsgpt.guardrails.base import GuardrailCheck
class GuardrailCreator:
"""Dict registry with lazy builtin bootstrap, mirroring ``ChunkerCreator``."""
checks: Dict[str, Type[GuardrailCheck]] = {}
_bootstrapped = False
@classmethod
def _ensure_builtin(cls) -> None:
if cls._bootstrapped:
return
cls._bootstrapped = True
import docsgpt.guardrails.checks # noqa: F401
@classmethod
def register(cls, key: str, check_class: Type[GuardrailCheck]) -> None:
cls.checks[key] = check_class
@classmethod
def is_registered(cls, key: str) -> bool:
cls._ensure_builtin()
return key in cls.checks
@classmethod
def get(cls, key: str) -> Type[GuardrailCheck]:
cls._ensure_builtin()
check_class = cls.checks.get(key)
if not check_class:
raise ValueError(f"No guardrail check found for key {key}")
return check_class
@classmethod
def create(cls, key: str, settings_dict: Optional[Dict[str, Any]] = None) -> GuardrailCheck:
if key not in cls.enabled_keys():
raise ValueError(f"guardrail check {key} is disabled on this instance")
return cls.get(key)(settings_dict or {})
@classmethod
def enabled_keys(cls) -> List[str]:
"""Registry keys permitted by ``GUARDRAILS_CHECKS_ENABLED``.
An empty allowlist means "everything registered", so adding a check
does not require an operator to also edit their env.
"""
cls._ensure_builtin()
allowlist = settings.GUARDRAILS_CHECKS_ENABLED or []
if not allowlist:
return sorted(cls.checks)
return sorted(k for k in cls.checks if k in set(allowlist))
@classmethod
def catalog(cls) -> List[Dict[str, Any]]:
cls._ensure_builtin()
return [cls.checks[k].describe() for k in cls.enabled_keys()]