Advent of 2024, Day 15 – Microsoft Azure AI – Content safety Python SDK
This article is originally published at https://tomaztsql.wordpress.com
In this Microsoft Azure AI series:
- Dec 01: Microsoft Azure AI – What is Foundry?
- Dec 02: Microsoft Azure AI – Working with Azure AI Foundry
- Dec 03: Microsoft Azure AI – Creating project in Azure AI Foundry
- Dec 04: Microsoft Azure AI – Deployment in Azure AI Foundry
- Dec 05: Microsoft Azure AI – Deployment parameters in Azure AI Foundry
- Dec 06: Microsoft Azure AI – AI Services in Azure AI Foundry
- Dec 07: Microsoft Azure AI – Speech service in AI Services
- Dec 08: Microsoft Azure AI – Speech Studio in Azure with AI Services
- Dec 09: Microsoft Azure AI – Speech SDK with Python
- Dec 10: Microsoft Azure AI – Language and Translation in Azure AI Foundry
- Dec 11: Microsoft Azure AI – Language and Translation Python SDK
- Dec 12: Microsoft Azure AI – Vision and Document AI Service
- Dec 13: Microsoft Azure AI – Vision and Document Python SDK
- Dec 14: Microsoft Azure AI – Content safety AI service
Content safety Azure AI service for detects harmful user-generated and AI-generated content has also a lot programming functions available. C#, Java and Python – all are available to add the use of services to your application.
The Python SDK contains several functions to analyze text, images, and manage blocklists in text moderation. With the SDK you can cover the following scenarios:
- Text moderation: Detect hate speech, sexual, selfharm, violence content in text.
- Image moderation: Detect hate speech, sexual, selfharm, violence content in images.
Coming back to example we covered yesterday – moderating the text content – we can alternate the filtering to suit your needs. Before going into the code, you will need to add also the:
- region
- Resource Key
- API Key
import enum
import json
import requests
from typing import Union
class MediaType(enum.Enum):
Text = 1
Image = 2
class Category(enum.Enum):
Hate = 1
SelfHarm = 2
Sexual = 3
Violence = 4
class Action(enum.Enum):
Accept = 1
Reject = 2
class DetectionError(Exception):
def __init__(self, code: str, message: str) -> None:
self.code = code
self.message = message
def __repr__(self) -> str:
return f"DetectionError(code={self.code}, message={self.message})"
class Decision(object):
def __init__(
self, suggested_action: Action, action_by_category: dict[Category, Action]
) -> None:
self.suggested_action = suggested_action
self.action_by_category = action_by_category
class ContentSafety(object):
def __init__(self, endpoint: str, subscription_key: str, api_version: str) -> None:
self.endpoint = endpoint
self.subscription_key = subscription_key
self.api_version = api_version
def build_url(self, media_type: MediaType) -> str:
if media_type == MediaType.Text:
return f"{self.endpoint}/contentsafety/text:analyze?api-version={self.api_version}"
elif media_type == MediaType.Image:
return f"{self.endpoint}/contentsafety/image:analyze?api-version={self.api_version}"
else:
raise ValueError(f"Invalid Media Type {media_type}")
def build_headers(self) -> dict[str, str]:
"""
Builds the headers for the Content Safety API request.
Returns:
- dict[str, str]: The headers for the Content Safety API request.
"""
return {
"Ocp-Apim-Subscription-Key": self.subscription_key,
"Content-Type": "application/json",
}
def build_request_body(
self,
media_type: MediaType,
content: str,
blocklists: list[str],
) -> dict:
if media_type == MediaType.Text:
return {
"text": content,
"blocklistNames": blocklists,
}
elif media_type == MediaType.Image:
return {"image": {"content": content}}
else:
raise ValueError(f"Invalid Media Type {media_type}")
def detect(
self,
media_type: MediaType,
content: str,
blocklists: list[str] = [],
) -> dict:
url = self.build_url(media_type)
headers = self.build_headers()
request_body = self.build_request_body(media_type, content, blocklists)
payload = json.dumps(request_body)
response = requests.post(url, headers=headers, data=payload)
print(response.status_code)
print(response.headers)
print(response.text)
res_content = response.json()
if response.status_code != 200:
raise DetectionError(
res_content["error"]["code"], res_content["error"]["message"]
)
return res_content
def get_detect_result_by_category(
self, category: Category, detect_result: dict
) -> Union[int, None]:
category_res = detect_result.get("categoriesAnalysis", None)
for res in category_res:
if category.name == res.get("category", None):
return res
raise ValueError(f"Invalid Category {category}")
def make_decision(
self,
detection_result: dict,
reject_thresholds: dict[Category, int],
) -> Decision:
action_result = {}
final_action = Action.Accept
for category, threshold in reject_thresholds.items():
if threshold not in (-1, 0, 2, 4, 6):
raise ValueError("RejectThreshold can only be in (-1, 0, 2, 4, 6)")
cate_detect_res = self.get_detect_result_by_category(
category, detection_result
)
if cate_detect_res is None or "severity" not in cate_detect_res:
raise ValueError(f"Can not find detection result for {category}")
severity = cate_detect_res["severity"]
action = (
Action.Reject
if threshold != -1 and severity >= threshold
else Action.Accept
)
action_result[category] = action
if action.value > final_action.value:
final_action = action
if (
"blocklistsMatch" in detection_result
and detection_result["blocklistsMatch"]
and len(detection_result["blocklistsMatch"]) > 0
):
final_action = Action.Reject
print(final_action.name)
print(action_result)
return Decision(final_action, action_result)
if __name__ == "__main__":
# Replace the placeholders with your own values
endpoint = "<endpoint>"
subscription_key = "<subscription_key>"
api_version = "2024-09-01"
# Initialize the ContentSafety object
content_safety = ContentSafety(endpoint, subscription_key, api_version)
# Set the media type and blocklists
media_type = MediaType.Text
blocklists = []
# Set the content to be tested
content = "<test_content>"
# Detect content safety
detection_result = content_safety.detect(media_type, content, blocklists)
# Set the reject thresholds for each category
reject_thresholds = {
Category.Hate: 3,
Category.SelfHarm: 3,
Category.Sexual: 3,
Category.Violence: 3,
}
# Make a decision based on the detection result and reject thresholds
decision_result = content_safety.make_decision(detection_result, reject_thresholds)
In such manner, you will always be able to build filters, set different thresholds and connect them to actions.
Tomorrow we will look into the Fine-tuning a model by training it on your own data.
All of the code samples will be available on my Github.
Thanks for visiting r-craft.org
This article is originally published at https://tomaztsql.wordpress.com
Please visit source website for post related comments.