Azure Content Safety

Nov 15 2024 · Python 3.12, Microsoft Azure, JupyterLabs

Lesson 03: Image Moderation Using Azure Content Safety

Implementing Image Moderation Using Azure Content Safety API

Episode complete

Play next episode

Next
Transcript

In this segment, you’ll implement image moderation for your sample app, Fooder.

Open the Jupyter Lab in your browser. Then, open 03-image-moderation-with-azure-content-safety/Starter/starter.ipynb.

Start by importing the required packages for this demo. Replace # TODO: install the packages with the following:

# install the packages
%pip install azure-ai-contentsafety
%pip install python-dotenv

You may remember importing these packages in the last demo! To quickly summarize once again:

  • azure-ai-contentsafety: This will install the Azure AI Content Safety library that you’ll use to create moderation requests
  • python-dotenv: You’ll use this library to load your sensitive endpoint and api-key variable from the .env file.

Run the cell by pressing the Enter + Shift keys and wait for the installation to finish.

Next, import the packages that you’ll use in this notebook. Replace # TODO import packages with the following:

# 1
import os

# 2
from dotenv import load_dotenv

# 3
from azure.ai.contentsafety import ContentSafetyClient
from azure.ai.contentsafety.models import ImageCategory
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import HttpResponseError
from azure.ai.contentsafety.models import AnalyzeImageOptions, ImageData

Here’s the explanation of the above code:

  1. You imported the os module. You’ll use this module to read the environment variables to fetch the content safety key and endpoint.
  2. You then imported the load_dotenv function from dotenv module. This function will load the key-value pairs from the .env file into environment variables.
  3. Finally, you also imported various classes from the Azure AI contents safety package. You’ll use them to create image analysis requests, send requests, etc.

Run the cell to successfully import everything, and wait for the cell execution to finish.

Creating Content Safety Client

Next, you’ll create a content safety client, which will be used to send API requests to Azure Content Safety resources.Replace the # TODO: Create content safety client with the following code:

# 1 Load your Azure Safety API key and endpoint
load_dotenv()

# 2
key = os.environ["CONTENT_SAFETY_KEY"]
endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

# 3 Create a Content Safety client
client = ContentSafetyClient(endpoint, AzureKeyCredential(key))

In the above code:

  1. You’re using the load_dotenv function to load the content from your .env file into the environment variables of your application.
  2. Next, you’re accessing the values of CONTENT_SAFETY_KEY and CONTENT_SAFETY_ENDPOINT from the environment variables using os.environ. These are assigned to the variables key and endpoint, which will be used to authenticate the API requests.
  3. Finally, you’re creating ContentSafetyClient using endpoint and key, and assigning it to client variable.

Make sure to copy the .env file that you created in lesson 2 in the present directory. Then, run the cell to create the content safety client.

Creating Moderate Image Function

Next, create the moderate_image function. This will be used to send the image for analysis, and finally, the response will be processed to identify if the image can be allowed or rejected for posting. Replace # TODO: Implement moderate image function with the following code:

# 1
def moderate_image(image_data):
    # 2 Construct a request
    request = AnalyzeImageOptions(image=ImageData(content=image_data))

    # 3 Analyze image
    try:
        response = client.analyze_image(request)
    except HttpResponseError as e:
        print("Analyze image failed.")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

    ## TODO: Process moderation response to determine if the image
    #        is approved or rejected

    #  4 If content is appropriate
    return "Post successful"

Here’s what the following code does:

  1. It creates the function moderate_image, which takes image_data as an argument and returns whether the shared input is approved or rejected for posting.
  2. Then, it constructs the request using AnalyzeImageOptions. You’ve provided the base64-encoded image to ImageData, and is passed to AnalyzeImageOptions using an image argument. Also, by default, output_type is set to FourSeverityLevels, where you only get 0,2,4,6 as the severity level output.
  3. You’re calling the client.analyze_image and passing the above-generated request inside it. You’ve also used the try-except block on the analyze image function to catch any exception and let the user know about it.
  4. Finally, if the content is appropriate, you return status as "Post successful".

Next, it’s time to implement the logic to determine if the image is safe, and whether the request can be approved or rejected if it’s harmful/violates the platform rules. Replace ## TODO: Process moderation response to determine if the image is approved or rejected with the following code:

# 1 Extract results
categories = {
    ImageCategory.HATE: None,
    ImageCategory.SELF_HARM: None,
    ImageCategory.SEXUAL: None,
    ImageCategory.VIOLENCE: None
}

# 2
for item in response.categories_analysis:
    if item.category in categories:
        categories[item.category] = item

# 3
hate_result = categories[ImageCategory.HATE]
self_harm_result = categories[ImageCategory.SELF_HARM]
sexual_result = categories[ImageCategory.SEXUAL]
violence_result = categories[ImageCategory.VIOLENCE]

# 4 Check for inappropriate content
violations = []
if hate_result and hate_result.severity > 2:
    violations.append("hate speech")
if self_harm_result and self_harm_result.severity > 3:
    violations.append("self-harm references")
if sexual_result and sexual_result.severity > 0:
    violations.append("sexual references")
if violence_result and violence_result.severity > 2:
    violations.append("violent references")

# 5
if violations:
    return f"Your shared image contains {', '.join(violations)} that violate
      our community guidelines. Please modify your image to adhere to
      community guidelines."

Make sure to fix the indentation of the code by selecting the above code and pressing the tab key if it is not indented adequately with respect to the remaining function.

Here’s the explanation for the code:

  1. You created a dictionary of ImageCategory values, which will be utilized to extract the moderation results from the respective categories.
  2. You’re then iterating through response.categories_analysis list to extract the output category responses and storing them in the appropriate category dictionary key defined above.
  3. You then extract each category’s results in a separate variable from the category dictionary.
  4. This is the central part of the processing logic. Here, you’re determining if the image that was requested for moderation is found inappropriate for any of the different categories - hate, self-harm, violence, and sexual, based on the severity threshold defined. If the output severity level is found to be more than its respective category’s threshold value, then you append the category name to the violation list.
  5. Finally, if any violation exists on the violation list, you inform the user by returning details regarding the categories that are found to be violated from the image and asking them to change the image so that it adheres to the community guidelines. If no violation is found, the user is notified that the post is successful.

Now, run the cell to ensure the defined function is error-free.

Exploring Image Moderation Function

Here comes the fun part! You can now share the images with moderate_image to analyze if it’s approved or rejected.

Copy the code in the newly created cell:

with open(’../../sample-data/test-images/pexels-ash-craig-122861-376464.jpg’,

  'rb') as file:
    image_data = file.read()

moderation_response = moderate_image(image_data)
print(moderation_response)

In the above code, you open the image stored in the sample data shared in the repo in read binary format. Then, it’s passed to moderate_image for analysis. Finally, you print the output received from the moderate_image function.

Run the cell to see it in action:

Post successful

Congratulations! You’ve successfully implemented the Image Moderation workflow. Feel free to test the moderation function with other sample images stored in the data to see how the response varies.

That’s it for this segment. Continue towards the next segment to conclude the lesson.

See forum comments
Cinema mode Download course materials from Github
Previous: Understanding Image Moderation API Next: Conclusion