Files
cmhub/apps/moderation/providers/base.py
T

50 lines
1.5 KiB
Python
Raw Normal View History

from __future__ import annotations
from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Protocol
class ModerationError(RuntimeError):
"""Base error for content-moderation failures."""
class ModerationUnavailableError(ModerationError):
"""Provider could not return a verdict (down / timeout / not implemented).
The orchestration layer converts this into a fail-closed BLOCK or a
fail-open PASS depending on ``MODERATION_FAIL_CLOSED`` policy.
"""
class ModerationConfigError(ModerationError):
"""Provider is misconfigured (missing credentials / biz type / endpoint)."""
class Verdict(str, Enum):
PASS = "pass" # 放行
REVIEW = "review" # 建议人工复审(是否等同拦截由 policy 决定)
BLOCK = "block" # 拦截
@dataclass(frozen=True)
class ModerationResult:
"""Normalized moderation verdict, decoupled from any vendor's response shape.
NOTE: ``raw`` is only for debugging in-process; never persist it verbatim
(may contain the moderated content / vendor internals). Compliance logging
stores a summary (verdict + labels + request_id), not ``raw``.
"""
verdict: Verdict
labels: tuple[str, ...] = ()
score: int | None = None
keywords: tuple[str, ...] = ()
request_id: str = ""
raw: Any = field(default=None, repr=False, compare=False)
class ModerationProvider(Protocol):
def moderate_text(self, text: str, *, biz_type: str = "") -> ModerationResult:
...