openmoderate
Open-source, self-hosted image and video content moderation for Python. Detect nudity, sexual content, violence, gore, weapons, hate symbols, drugs, self-harm, alcohol and tobacco in uploaded images and videos — with one pip install, no cloud account, no per-image fees, and no ML experience needed.
Think of it as an open alternative to Amazon Rekognition's DetectModerationLabels that runs inside your own app.
from openmoderate import Moderator
mod = Moderator()
result = mod.analyze("upload.jpg")
if not result.is_safe:
print(result.violations)
# [Label(name='weapons', confidence=0.9612, parent='violence', threshold=0.5)]
Documentation · Benchmarks · Changelog · Security
Install
pip install openmoderate
Python 3.9+. The first call downloads the CLIP model weights (~600 MB) once; after that everything runs offline, on CPU, CUDA or Apple Silicon. Extras: openmoderate[server], [video], [fastapi], [flask], [django]. See the install notes for CPU-only servers.
What you can do with it
Tune the policy — thresholds, categories and your own categories as plain text, no training data needed (guide):
mod = Moderator(thresholds={"weapons": 0.3}, exclude=["alcohol", "tobacco"])
mod = Moderator("policy.yaml") # custom categories like "gambling" in YAML
Scan from the command line — folders, URLs and videos; --fail-on-violation for CI (guide):
openmoderate scan ./uploads
Train on your own images for better accuracy in your domain (guide):
openmoderate train ./dataset -o my_head.omh # dataset/<label>/*.jpg + dataset/safe/
Moderate videos with timestamped segments (guide):
Moderator().analyze_video("clip.mp4").segments # weapons 0:03–0:06, violence 0:09–0:12
Protect uploads in FastAPI, Flask or Django with one line (guide):
async def avatar(file: ModeratedFile): ... # FastAPI
avatar = models.ImageField(validators=[ModerationValidator()]) # Django
Call it over HTTP from any language — REST server and Docker image (guide):
docker run -p 8000:8000 -e OPENMODERATE_API_KEY=change-me ghcr.io/karammm/openmoderate
curl -H "X-API-Key: change-me" -F file=@upload.jpg localhost:8000/v1/moderate
Accuracy
Measured on a held-out set of hand-reviewed, openly licensed photos (full results and method, reproducible with python benchmark/run.py):
| Category | Recall | Precision |
|---|---|---|
drugs |
85% | 82% |
alcohol |
84% | 100% |
violence |
82% | 100% |
weapons |
79% | 100% |
hate_symbols |
61% | 100% |
tobacco |
59% | 89% |
6% of safe images (including look-alikes such as kitchen knives, milk and medicine) were flagged. Sets are small, so read these as ±10 points. Nudity, sexual content, gore and self-harm are not benchmarked by the maintainers — evaluate them on your own data.
Zero-shot moderation is good at clear-cut cases and will miss subtle ones. Evaluate on a sample of your own traffic, adjust thresholds, and send borderline scores to human review for high-stakes decisions. How it works and its limits.
Contributing
Contributions are welcome — better prompts, new categories, benchmark images and bug reports especially. See CONTRIBUTING.md. Report security issues privately (SECURITY.md).
Responsible use
openmoderate is meant to help keep platforms safe. Do not use it to surveil individuals or to profile people by protected characteristics. Moderation models make mistakes; give users a way to appeal automated decisions.
License
Apache 2.0. Benchmark images keep their own licences (see benchmark/manifest.csv).
Metadata
Release files for openmoderate 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| openmoderate-1.0.1.tar.gz | 419.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| openmoderate-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 470.1 kB
Release files / openmoderate-1.0.1.tar.gz
| Download URL | openmoderate-1.0.1.tar.gz |
|---|---|
| Size | 419.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6877eec762a8436a2bdcd21990c3320f3e3875100d798143bf01b05501556ab1
|
|
BLAKE2b-256 checksum How to use checksums |
8ecbcbd963794dc8af02ada7281c4cae8db4f164daa75fa7c29525779a33214c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / openmoderate-1.0.1-py3-none-any.whl
| Download URL | openmoderate-1.0.1-py3-none-any.whl |
|---|---|
| Size | 50.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
059fe1c4a4584988b175c0d714bb92095ddaa4346ec8fab3ad92e8dedf8b543f
|
|
BLAKE2b-256 checksum How to use checksums |
56df6c84291a443eaaf2a1c728f9d29fd9195cd97f14879954e5225a285ddc9c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency log