API reference¶
Generated from the docstrings. Everything on this page is public API.
Moderator ¶
Detect policy-violating content in images.
For example:
from openmoderate import Moderator
mod = Moderator()
result = mod.analyze("upload.jpg")
if not result.is_safe:
print(result.violations)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
ModerationConfig | Mapping | str | Path | None
|
A |
None
|
preset
|
str | None
|
|
None
|
thresholds
|
Mapping[str, float] | None
|
Per-category threshold overrides, e.g. |
None
|
categories
|
list[str] | None
|
Only check these categories. |
None
|
exclude
|
list[str] | None
|
Skip these categories. |
None
|
head
|
LinearHead | str | Path | None
|
A trained head ( |
None
|
head_weight
|
float
|
For labels known to both, |
1.0
|
engine
|
Engine | None
|
Custom embedding engine (defaults to OpenCLIP, loaded lazily). |
None
|
device
|
str
|
|
'auto'
|
label_specs
property
¶
label_specs: list[LabelSpec]
Every label this moderator reports, with its parent and threshold.
score_embeddings ¶
score_embeddings(image_embeddings: ndarray) -> np.ndarray
Zero-shot category scores in [0, 1), shape (n_images, n_categories).
For each category we take the margin between the image's best-matching category
prompt and its best-matching safe prompt (in CLIP logit units), then map it through
a calibrated sigmoid. Categories are scored independently, so an image can be both
weapons and violence.
score_all ¶
score_all(image_embeddings: ndarray) -> np.ndarray
Final scores for every label in category_names (zero-shot + head).
score_images ¶
score_images(images: list[Image]) -> np.ndarray
Scores for already-loaded RGB PIL images (after border trimming, if enabled).
analyze ¶
analyze(image: ImageInput) -> ModerationResult
Analyse a single image (path, URL, bytes, file object or PIL image).
analyze_video ¶
analyze_video(video: VideoInput, *, fps: float = 1.0, max_frames: int | None = None, max_duration: float | None = None, min_frames: int = 1, stop_on_violation: bool = False, batch_size: int = 16, keep_frame_scores: bool = False) -> VideoModerationResult
Moderate a video by sampling frames (needs pip install "openmoderate[video]").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
video
|
VideoInput
|
Path, bytes or file object. |
required |
fps
|
float
|
Frames sampled per second of video. |
1.0
|
max_frames
|
int | None
|
Stop after this many sampled frames. |
None
|
max_duration
|
float | None
|
Stop decoding after this many seconds ( |
None
|
min_frames
|
int
|
Ignore segments shorter than this many flagged frames, to suppress one-frame false positives. |
1
|
stop_on_violation
|
bool
|
Stop at the first violating segment, for fast rejection. |
False
|
keep_frame_scores
|
bool
|
Include every sampled frame's scores in the result. |
False
|
Returns:
| Type | Description |
|---|---|
VideoModerationResult
|
A |
VideoModerationResult
|
|
Results¶
ModerationResult
dataclass
¶
Outcome of analysing one image.
labels holds a score for every configured category (sorted by confidence),
violations holds only the labels whose score crossed their threshold.
Label
dataclass
¶
A single moderation label with its confidence score in [0, 1].
LabelSpec ¶
Bases: NamedTuple
Videos¶
VideoModerationResult
dataclass
¶
VideoSegment
dataclass
¶
A stretch of video where one label stayed above its threshold.
Configuration¶
ModerationConfig
dataclass
¶
from_preset
classmethod
¶
from_preset(name: str) -> ModerationConfig
A default configuration using one of the PRESETS ("fast", "balanced", "accurate").
default
classmethod
¶
default() -> ModerationConfig
The default configuration, honouring the OPENMODERATE_PRESET environment variable.
from_dict
classmethod
¶
from_dict(data: Mapping[str, Any]) -> ModerationConfig
Build a config from a dict (e.g. parsed YAML).
Supported keys: preset ("fast", "balanced" or "accurate"), model,
pretrained, cache_dir, safe_prompts, thresholds (name -> float),
enabled/disabled (lists of names) and custom_categories (list of
{name, prompts, threshold, parent}). model/pretrained override the preset.
Category
dataclass
¶
Trained heads¶
LinearHead
dataclass
¶
One-vs-rest logistic regression: sigmoid(embeddings @ weights.T + bias).
Errors¶
ImageLoadError ¶
Bases: ValueError
VideoLoadError ¶
Bases: ValueError
Framework integrations¶
integrations ¶
Drop-in upload moderation for web frameworks.
- FastAPI:
openmoderate.integrations.fastapi - Flask:
openmoderate.integrations.flask - Django:
openmoderate.integrations.django
ImageRejected ¶
ModerationError ¶
Bases: Exception
Base class for upload moderation failures.
UnreadableUpload ¶
UploadTooLarge ¶
check_image ¶
check_image(data: bytes, *, field: str | None = None, moderator: Moderator | None = None, on_unreadable: OnUnreadable = 'reject') -> ModerationResult | None
Moderate raw image bytes.
Returns the result for a safe image, None for an unreadable file that is allowed
through, and raises ImageRejected / UnreadableUpload otherwise.
configure ¶
configure(moderator: Moderator | None = None, /, **kwargs: Any) -> None
Set the moderator the integrations use.
Pass a ready Moderator, or keyword arguments for one (config, head,
thresholds, device, ...), which is then created lazily on first use. Call this
once at startup; calling it again replaces the shared moderator.
get_moderator ¶
get_moderator(thresholds: Mapping[str, float] | None = None, categories: list[str] | None = None, exclude: list[str] | None = None) -> Moderator
Return the shared moderator, or a variant with a different policy.
Variants reuse the shared moderator's engine, so they cost no extra model memory.
fastapi ¶
FastAPI integration: reject violating image uploads before your endpoint runs.
from fastapi import FastAPI, UploadFile
from openmoderate.integrations.fastapi import ModeratedFile, moderated
app = FastAPI()
@app.post("/avatar")
async def avatar(file: ModeratedFile): # form field "file"
... # only safe images get here
@app.post("/photos")
async def photos(photo: UploadFile = moderated("photo", thresholds={"weapons": 0.3})):
...
Violating images get a 422 response (413 if too large) and the endpoint never runs.
Moderation runs in a worker thread, so it does not block the event loop.
moderated ¶
moderated(field: str = 'file', *, moderator: Moderator | None = None, thresholds: Mapping[str, float] | None = None, categories: list[str] | None = None, exclude: list[str] | None = None, on_unreadable: OnUnreadable = 'reject', status_code: int = 422, include_scores: bool = False, max_bytes: int = MAX_BYTES) -> Any
A Depends(...) that parses form field field and moderates it.
Use as a default value: file: UploadFile = moderated("file").
moderated_files ¶
moderated_files(field: str = 'files', *, moderator: Moderator | None = None, thresholds: Mapping[str, float] | None = None, categories: list[str] | None = None, exclude: list[str] | None = None, on_unreadable: OnUnreadable = 'reject', status_code: int = 422, include_scores: bool = False, max_bytes: int = MAX_BYTES) -> Any
Like moderated for a repeated field (list[UploadFile]); every file must pass.
flask ¶
Flask integration: reject violating image uploads.
Per view, with a decorator:
from openmoderate.integrations.flask import moderate_uploads
@app.post("/avatar")
@moderate_uploads("avatar") # or no args: every file in the request
def avatar():
request.files["avatar"].save(...) # only safe images get here
Or for every request, with the extension:
from openmoderate.integrations.flask import OpenModerate
OpenModerate(app, check_all_requests=True)
Violating images get a JSON 422 response (413 if too large).
OpenModerate ¶
Flask extension.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app
|
Flask | None
|
The Flask app (or call |
None
|
moderator
|
Moderator | None
|
A ready |
None
|
check_all_requests
|
bool
|
Moderate every uploaded file on every request. |
False
|
on_unreadable
|
OnUnreadable
|
What to do with uploads that are not images. Defaults to
|
'allow'
|
moderate_uploads ¶
moderate_uploads(*fields: str, moderator: Moderator | None = None, thresholds: Mapping[str, float] | None = None, categories: list[str] | None = None, exclude: list[str] | None = None, on_unreadable: OnUnreadable = 'reject', status_code: int = 422, include_scores: bool = False, max_bytes: int = MAX_BYTES) -> Callable
Decorate a view so the named file fields (default: all of them) are moderated first.
django ¶
Django integration: a field validator and a middleware.
Validator (works in model fields, forms, the admin and Django REST Framework serializers):
from openmoderate.integrations.django import ModerationValidator
class Profile(models.Model):
avatar = models.ImageField(validators=[ModerationValidator()])
banner = models.ImageField(validators=[ModerationValidator(thresholds={"suggestive": 0.4})])
Middleware (moderates every uploaded file under the configured URL prefixes):
MIDDLEWARE = [..., "openmoderate.integrations.django.ModerationMiddleware"]
Settings, all optional:
OPENMODERATE = {
"CONFIG": BASE_DIR / "policy.yaml", # policy YAML
"HEAD": BASE_DIR / "my_head.omh", # trained head
"PRESET": "accurate", # fast (default), balanced or accurate
"DEVICE": "auto",
"PATHS": ["/uploads/", "/api/"], # middleware only; default: every path
"ON_UNREADABLE": "allow", # middleware: non-image files pass through
"STATUS_CODE": 422,
"INCLUDE_SCORES": False,
}
ModerationValidator ¶
Reject images that violate the moderation policy.
Policy overrides apply to this field only and reuse the shared model, so they cost no extra memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
thresholds
|
Mapping[str, float] | None
|
Per-category threshold overrides, e.g. |
None
|
categories
|
list[str] | None
|
Only check these categories. |
None
|
exclude
|
list[str] | None
|
Skip these categories. |
None
|
on_unreadable
|
OnUnreadable
|
|
'reject'
|
message
|
str | None
|
Error shown to the user; |
None
|
max_bytes
|
int
|
Reject files larger than this. |
MAX_BYTES
|
ModerationMiddleware ¶
Moderate every uploaded file on matching paths; reject with a JSON error.