All Products
Search
Document Center

AI Guardrails:Image moderation

Last Updated:Mar 31, 2026

Use AI Guardrails SDK for Python to detect risky content in images across multiple moderation scenarios.

How it works

Submit an image URL to a moderation operation. AI Guardrails processes each image task and returns a suggestion value (pass or block) along with the detected scene. Based on these values, take action in your application — for example, reject images flagged as block.

Image moderation supports two detection modes:

  • Synchronous detection: results are returned in the API response immediately. Use this for real-time moderation of user-uploaded images.

  • Asynchronous detection: submit the task, then either poll for results using ImageAsyncScanResultsRequest or configure a callback notification. Use this for batch processing or large image volumes.

This SDK accepts image URLs only. Local files and binary data are not supported directly. To moderate a local file or binary stream, upload it to the server first using the Extension.Uploader utility class, then submit the returned URL.

Supported URL format: HTTP or HTTPS URLs up to 2,048 characters.

Prerequisites

Before you begin, make sure you have:

  1. Installed the Python dependencies using the required Python version. See Installation for version requirements. Using an incompatible version causes operation calls to fail.

  2. Downloaded the Extension.Uploader utility class and imported it into your project.

  3. Set your RAM user credentials as environment variables:

    Important

    Never hardcode your AccessKey ID and AccessKey secret in source code or commit them to version control. Always load credentials from environment variables.

    export ALIBABA_CLOUD_ACCESS_KEY_ID=<your-access-key-id>
    export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your-access-key-secret>

Submit synchronous image moderation tasks

ImageSyncScanRequest sends a synchronous request and returns moderation results in real time.

PropertyValue
Supported regionscn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1
Supported scenariospornography, terrorist content, ad, QR code, undesirable scene, logo detection
Billing is calculated per scenario per image. Moderating two images for both pornography and terrorist content counts as four moderation units.

Before running the examples below, replace the following placeholders:

PlaceholderDescriptionExample
<your-access-key-id>AccessKey ID of your RAM userLTAI5tXxx...
<your-access-key-secret>AccessKey secret of your RAM userxXxXxXx...
<image-url>URL of the image to moderatehttps://example.com/photo.jpg
Reuse the AcsClient instance across requests to improve performance and avoid repeated connection setup. Create a new request object for each request — request objects cannot be reused.

Submit an online image URL

# coding=utf-8
import os
import json
import uuid
from aliyunsdkcore import client
from aliyunsdkgreen.request.v20180509 import ImageSyncScanRequest

# Reuse this client instance across multiple requests.
clt = client.AcsClient(
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_ID"),
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
    "cn-shanghai"
)

# Create a new request object for each request.
request = ImageSyncScanRequest.ImageSyncScanRequest()
request.set_accept_format("JSON")

task = {
    "dataId": str(uuid.uuid1()),
    "url": "<image-url>"  # Replace with your image URL.
}

# Specify one or more scenarios. Each scenario is billed separately.
# Example: ["porn", "terrorism"] checks for both pornography and terrorist content.
request.set_content(json.dumps({"tasks": [task], "scenes": ["porn"]}))

response = clt.do_action_with_exception(request)
result = json.loads(response)

if result["code"] == 200:
    for task_result in result["data"]:
        if task_result["code"] == 200:
            for scene_result in task_result["results"]:
                scene = scene_result["scene"]
                suggestion = scene_result["suggestion"]
                # suggestion is "pass" (safe) or "block" (violation detected).
                print(f"Scene: {scene}, Suggestion: {suggestion}")

Submit a local image

Use the Extension.Uploader utility class to upload the local file first, then submit the returned URL.

# coding=utf-8
import os
import json
import uuid
import sys
from aliyunsdkcore import client
from aliyunsdkgreen.request.v20180509 import ImageSyncScanRequest
from aliyunsdkgreenextension.request.extension import ClientUploader
from aliyunsdkgreenextension.request.extension import HttpContentHelper

# Python 2 only: set default encoding for paths containing non-ASCII characters.
if sys.version_info[0] == 2:
    reload(sys)
    sys.setdefaultencoding("utf-8")

clt = client.AcsClient(
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_ID"),
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
    "cn-shanghai"
)

request = ImageSyncScanRequest.ImageSyncScanRequest()
request.set_accept_format("JSON")

# Upload the local image and get a URL to submit for moderation.
uploader = ClientUploader.getImageClientUploader(clt)
url = uploader.uploadFile("/path/to/your/image.jpg")  # Replace with your local file path.

task = {
    "dataId": str(uuid.uuid1()),
    "url": url
}

request.set_content(HttpContentHelper.toValue({"tasks": [task], "scenes": ["porn"]}))

response = clt.do_action_with_exception(request)
result = json.loads(response)

if result["code"] == 200:
    for task_result in result["data"]:
        if task_result["code"] == 200:
            for scene_result in task_result["results"]:
                scene = scene_result["scene"]
                suggestion = scene_result["suggestion"]
                print(f"Scene: {scene}, Suggestion: {suggestion}")

Submit a binary image stream

Read the image as binary data, upload it to the server, then submit the returned URL.

# coding=utf-8
import os
import json
import uuid
import sys
from aliyunsdkcore import client
from aliyunsdkgreen.request.v20180509 import ImageSyncScanRequest
from aliyunsdkgreenextension.request.extension import ClientUploader
from aliyunsdkgreenextension.request.extension import HttpContentHelper

if sys.version_info[0] == 2:
    reload(sys)
    sys.setdefaultencoding("utf-8")

clt = client.AcsClient(
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_ID"),
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
    "cn-shanghai"
)

request = ImageSyncScanRequest.ImageSyncScanRequest()
request.set_accept_format("JSON")

# Read the image as binary data.
with open("/path/to/your/image.jpg", "rb") as f:  # Replace with your file path.
    image_bytes = f.read()

# Upload the binary data and get a URL to submit for moderation.
uploader = ClientUploader.getImageClientUploader(clt)
url = uploader.uploadBytes(image_bytes)

task = {
    "dataId": str(uuid.uuid1()),
    "url": url
}

request.set_content(HttpContentHelper.toValue({"tasks": [task], "scenes": ["porn"]}))

response = clt.do_action_with_exception(request)
result = json.loads(response)

if result["code"] == 200:
    for task_result in result["data"]:
        if task_result["code"] == 200:
            for scene_result in task_result["results"]:
                scene = scene_result["scene"]
                suggestion = scene_result["suggestion"]
                print(f"Scene: {scene}, Suggestion: {suggestion}")

Submit asynchronous image moderation tasks

ImageAsyncScanRequest submits a moderation task and returns a task ID. Retrieve results by polling with ImageAsyncScanResultsRequest or by configuring a callback notification.

All three image input methods (online URL, local file, binary stream) are supported. The example below uses an online URL.

Supported regions: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1

# coding=utf-8
import os
import json
import uuid
from aliyunsdkcore import client
from aliyunsdkcore.profile import region_provider
from aliyunsdkgreen.request.v20180509 import ImageAsyncScanRequest
from aliyunsdkgreenextension.request.extension import HttpContentHelper

clt = client.AcsClient(
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_ID"),
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
    "cn-shanghai"
)
region_provider.modify_point("Green", "cn-shanghai", "green.cn-shanghai.aliyuncs.com")

request = ImageAsyncScanRequest.ImageAsyncScanRequest()
request.set_accept_format("JSON")

task = {
    "dataId": str(uuid.uuid1()),
    "url": "<image-url>"  # Replace with your image URL.
}

request.set_content(HttpContentHelper.toValue({"tasks": [task], "scenes": ["porn"]}))

response = clt.do_action_with_exception(request)
result = json.loads(response)

if result["code"] == 200:
    for task_result in result["data"]:
        if task_result["code"] == 200:
            task_id = task_result["taskId"]
            # Record this task ID to poll for results later.
            print(f"Task submitted. Task ID: {task_id}")

Query asynchronous moderation results

Use ImageAsyncScanResultsRequest to poll for results by task ID. Submit one or more task IDs in a single request.

Supported regions: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1

# coding=utf-8
import os
import json
from aliyunsdkcore import client
from aliyunsdkcore.profile import region_provider
from aliyunsdkgreen.request.v20180509 import ImageAsyncScanResultsRequest
from aliyunsdkgreenextension.request.extension import HttpContentHelper

clt = client.AcsClient(
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_ID"),
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
    "cn-shanghai"
)
region_provider.modify_point("Green", "cn-shanghai", "green.cn-shanghai.aliyuncs.com")

request = ImageAsyncScanResultsRequest.ImageAsyncScanResultsRequest()
request.set_accept_format("JSON")

# Replace with the task IDs returned by ImageAsyncScanRequest.
task_ids = ["img5sO$Zsssss7RYuz4Yyhhe-1q51iZ"]
request.set_content(HttpContentHelper.toValue(task_ids))

response = clt.do_action_with_exception(request)
result = json.loads(response)

if result["code"] == 200:
    for task_result in result["data"]:
        if task_result["code"] == 200:
            for scene_result in task_result["results"]:
                scene = scene_result["scene"]
                suggestion = scene_result["suggestion"]
                # suggestion is "pass" (safe) or "block" (violation detected).
                print(f"Scene: {scene}, Suggestion: {suggestion}")

Submit feedback on moderation results

If moderation results don't match your expectations, use ImageScanFeedbackRequest to correct them. AI Guardrails adds the image to the similar image blacklist or whitelist based on your feedback, and applies that label to similar images in future moderation requests.

For parameter details, see /green/image/feedback.

Supported regions: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1

# coding=utf-8
import os
import json
from aliyunsdkcore import client
from aliyunsdkcore.profile import region_provider
from aliyunsdkgreen.request.v20180509 import ImageScanFeedbackRequest

clt = client.AcsClient(
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_ID"),
    os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_SECRET"),
    "cn-shanghai"
)
region_provider.modify_point("Green", "cn-shanghai", "green.cn-shanghai.aliyuncs.com")

request = ImageScanFeedbackRequest.ImageScanFeedbackRequest()
request.set_accept_format("JSON")

# suggestion: "pass" to add to whitelist, "block" to add to blacklist.
# scenes: one or more moderation scenarios to apply the feedback to.
# url: the URL of the image you are providing feedback on.
request.set_content(json.dumps({
    "suggestion": "block",
    "scenes": ["ad", "terrorism"],
    "url": "<image-url>"  # Replace with the image URL.
}))

try:
    response = clt.do_action_with_exception(request)
    result = json.loads(response)
    if result["code"] == 200:
        print("Feedback submitted successfully.")
except Exception as err:
    print(f"Feedback submission failed: {err}")

What's next