Features
🛡️ Multi-Layered Content Moderation: Automatically detects AI-generated, violent, and explicit content in images and videos.
🔄️ Two Engines, One Result Shape: Use the cloud API for maximum accuracy, or the optional on-device engine to build and test locally without an API key. Both return the exact same strictly typed models.
⚡ Sync & Async Support: Natively supports both synchronous operations and async/await out of the box, making it
a perfect fit for high-performance frameworks like FastAPI.
🛠️ Comprehensive API Bindings: Typed bindings for the entire API including spaces, activities, tasks, predictors, runners, shares, and reactions. We also include token estimation, so you can price a job before you spend on it.
Installation
You can install the client in two ways, depending on whether you want to rely purely on the cloud API or include the local fallback engine.
Cloud-Only (Standard)
Installs the lightweight client. All media detection is routed to the Elhio Cloud API. This version is entirely Apache 2.0 licensed.
pip install guard-client
Cloud + Local (Hybrid)
Installs the client along with the guard-local-detector engine. This allows you to process local file paths directly
on your hardware with zero network latency.
Note: The local engine dependency is licensed under the AGPL-3.0.
pip install "guard-client[local]"
Quick Start
The analyze() method runs the entire detection lifecycle for you. It creates an activity, uploads the media, confirms
the upload, polls until processing finishes, and returns the result.
You will need an API key and a space to create the activity in. You can create a new access token in the Elhio
dashboard (under Settings > Account Settings > Access Tokens). If you do not know your space ID yet, you can
ask the API for it. The spaces.list() method returns every space the key can see.
from guard_client import GuardClient
with GuardClient(api_key="your_api_key_here") as client:
# 1. Get an available space
space = client.spaces.list()[0]
# 2. Analyze the media (creates activity, uploads, and polls for results)
result = client.analyze("photo.jpg", space_id=space.id)
# 3. Print the detection results
for item in result.results:
print(f"{item.label}: {item.score}/100")
# AI-Generated: 87/100
# Violence: 2/100
# Explicit: 1/100
Both values also resolve from the environment, so the common case needs no arguments at all:
# With GUARD_API_KEY and GUARD_SPACE_ID set (environment or .env)
with GuardClient() as client:
result = client.analyze("photo.jpg")
The analyze() method accepts a file path, raw bytes, or an open binary file object. The media type is detected
automatically from the filename or the file's magic bytes. You can pass media_type= to skip this automatic detection.
Local Detection
With the [local] extra installed, you can pass engine="local" to run entirely on-device. This requires no network
calls, no API key, and no space ID. Results use the exact same DetectionResult type as the cloud API, so the code
reading them does not need to change.
Local detection is opt-in and never automatic. The engine you get is the engine you explicitly ask for, regardless of which extras happen to be installed.
from guard_client import GuardClient
with GuardClient(engine="local") as client:
# 1. Analyze the media
result = client.analyze("/local/path/to/video.mp4")
# 2. Print the detection results
for item in result.results:
print(f"{item.label}: {item.score}/100")
# AI-Generated: 90/100
# Violence: 2/100
# Explicit: 1/100
Two fields easily tell the engines apart. The result.activity_id is None because a local run creates nothing
server-side, meaning there is nothing to share or react to. The result.detected field carries the engine's own
per-category threshold verdict, which the cloud API does not report. Reading it means you are opting into extra detail,
not into a different data shape.
Development
This project uses uv for package and environment management. A single uv sync creates
the .venv, reads uv.lock, and installs everything exactly as it was locked. The test suite is fully mocked, so
there is no API key to obtain and no network access at any point.
# set up the environment
uv sync
# run tests
uv run pytest
# build for production
uv build
The Contributing Guide covers the rest: linting and type checking, the documentation build, working against the optional local engine and its shared contract suite, and testing end-to-end against a live API.
Contributing
We welcome contributions! Please note that all contributors must sign our automated CLA. Read more in our Contributing Guide.
License
This repository and its corresponding PyPI package are licensed under the Apache v2.0 (Apache-2.0) - see the LICENSE file for details.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file guard_client-0.0.1.tar.gz.
File metadata
- Download URL: guard_client-0.0.1.tar.gz
- Upload date:
- Size: 258.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0986741169703b3d4f609d608485a9d5311e588b0a500b46f5f8a86ab384314a
|
|
| MD5 |
bf1cbc61d5edb44fa11b1018dbfeb0c8
|
|
| BLAKE2b-256 |
da062c1f52d5b7716ff413e55d87e31640a3c414a9264bd63487dbf50b4a7ee4
|
Provenance
The following attestation bundles were made for guard_client-0.0.1.tar.gz:
Publisher:
release.yml on elhio/guard-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
guard_client-0.0.1.tar.gz -
Subject digest:
0986741169703b3d4f609d608485a9d5311e588b0a500b46f5f8a86ab384314a - Sigstore transparency entry: 2420571947
- Sigstore integration time:
-
Permalink:
elhio/guard-python@85e0d37df0ba2fbbdbff30a03b186f7ac07fcb12 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/elhio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@85e0d37df0ba2fbbdbff30a03b186f7ac07fcb12 -
Trigger Event:
release
-
Statement type:
File details
Details for the file guard_client-0.0.1-py3-none-any.whl.
File metadata
- Download URL: guard_client-0.0.1-py3-none-any.whl
- Upload date:
- Size: 90.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95dc44ec8284ef8945cbe7a814d4f17ec815df77f816cba4d12c90259fc35592
|
|
| MD5 |
b7d1dd11306ed70d929556202522f194
|
|
| BLAKE2b-256 |
f24e7a67abd830ff7ea15468d57b8025fafc18f87fe5fc18cf00aa468eefcce6
|
Provenance
The following attestation bundles were made for guard_client-0.0.1-py3-none-any.whl:
Publisher:
release.yml on elhio/guard-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
guard_client-0.0.1-py3-none-any.whl -
Subject digest:
95dc44ec8284ef8945cbe7a814d4f17ec815df77f816cba4d12c90259fc35592 - Sigstore transparency entry: 2420572031
- Sigstore integration time:
-
Permalink:
elhio/guard-python@85e0d37df0ba2fbbdbff30a03b186f7ac07fcb12 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/elhio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@85e0d37df0ba2fbbdbff30a03b186f7ac07fcb12 -
Trigger Event:
release
-
Statement type: