Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/tLTGCA4G)
---
title: "Activity 1 - Hello, Azure AI"
type: lab
Expand Down
3 changes: 3 additions & 0 deletions REFLECTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ Answer these questions after completing the activity (2-3 sentences each). Conne
## 1. Service Surprises

Which of the three Azure AI services (OpenAI, Content Safety, Language) surprised you the most? Connect this to something specific you observed during your experiments -- a response you didn't expect, a behavior that seemed too easy or too hard, or a result that made you rethink how the service works.
Nothing about the services surprised since I did not understand at all what was going on with this assigment. The instructions were vague at best and seemed to rely on knowledge not yet covered. There was not even a reference to potential sources that could clarify the asks of the assignment.

## 2. Lazy Initialization

How would you explain the lazy initialization pattern to a colleague? Why is it used instead of creating clients at the top of the file?
This method delays calling a service until it needed in the code, thus preventing on initial overload in resource consumption as the program starts up.

## 3. Content Safety in the Real World

A resident files this complaint: *"A man was assaulted at this intersection because the street light has been out for months."* This text describes real violence but is a legitimate safety concern. Should the system block it, flag it for human review, or pass it through? What factors would you weigh in making that decision?
This would probably need to be flagged for human review. The existence of legitimate issues within the complaint should be passed on for consideration since it is alleged the issue caused harm and likely needs prompt attention. As there are elements that would violate a content safety threshold of 0, it should not be passed along without human review.
72 changes: 50 additions & 22 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ def _get_openai_client():
global _openai_client
if _openai_client is None:
# TODO: Uncomment and configure
# from openai import AzureOpenAI
# _openai_client = AzureOpenAI(
# azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
# api_key=os.environ["AZURE_OPENAI_API_KEY"],
# api_version="2024-10-21",
# )
raise NotImplementedError("Configure the Azure OpenAI client")
from openai import AzureOpenAI
_openai_client = AzureOpenAI(
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_key=os.environ["AZURE_OPENAI_API_KEY"],
api_version="2024-10-21",
)
# raise NotImplementedError("Configure the Azure OpenAI client")
return _openai_client


Expand All @@ -62,13 +62,15 @@ def _get_content_safety_client():
# NOTE: The Content Safety SDK handles API versioning internally --
# no api_version parameter is needed (unlike the OpenAI SDK).
# TODO: Uncomment and configure
# from azure.ai.contentsafety import ContentSafetyClient
# from azure.core.credentials import AzureKeyCredential
# _content_safety_client = ContentSafetyClient(
# endpoint=os.environ["AZURE_CONTENT_SAFETY_ENDPOINT"],
# credential=AzureKeyCredential(os.environ["AZURE_CONTENT_SAFETY_KEY"]),
# )
raise NotImplementedError("Configure the Content Safety client")
from azure.ai.contentsafety import ContentSafetyClient
from azure.core.credentials import AzureKeyCredential
_content_safety_client = ContentSafetyClient(
endpoint=os.environ["AZURE_CONTENT_SAFETY_ENDPOINT"],
credential=AzureKeyCredential(os.environ["AZURE_CONTENT_SAFETY_KEY"]),
)


# raise NotImplementedError("Configure the Content Safety client")
return _content_safety_client


Expand All @@ -79,19 +81,20 @@ def _get_language_client():
# NOTE: The Language SDK handles API versioning internally --
# no api_version parameter is needed (unlike the OpenAI SDK).
# TODO: Uncomment and configure
# from azure.ai.textanalytics import TextAnalyticsClient
# from azure.core.credentials import AzureKeyCredential
# _language_client = TextAnalyticsClient(
# endpoint=os.environ["AZURE_AI_LANGUAGE_ENDPOINT"],
# credential=AzureKeyCredential(os.environ["AZURE_AI_LANGUAGE_KEY"]),
# )
raise NotImplementedError("Configure the AI Language client")
from azure.ai.textanalytics import TextAnalyticsClient
from azure.core.credentials import AzureKeyCredential
_language_client = TextAnalyticsClient(
endpoint=os.environ["AZURE_AI_LANGUAGE_ENDPOINT"],
credential=AzureKeyCredential(os.environ["AZURE_AI_LANGUAGE_KEY"]),
)
# raise NotImplementedError("Configure the AI Language client")
return _language_client


# ---------------------------------------------------------------------------
# TODO: Step 1 - Classify a 311 request with Azure OpenAI
# ---------------------------------------------------------------------------

def classify_311_request(request_text: str) -> dict:
"""Send a Memphis 311 service request to Azure OpenAI for classification.

Expand All @@ -102,12 +105,27 @@ def classify_311_request(request_text: str) -> dict:
dict with keys: category, confidence, reasoning
"""
# TODO: Step 1.1 - Get the OpenAI client
client =_get_openai_client()
# TODO: Step 1.2 - Call client.chat.completions.create() with:
# model=os.environ.get("AZURE_OPENAI_DEPLOYMENT", "gpt-4o")
# A system message that classifies into: Pothole, Noise Complaint,
# Trash/Litter, Street Light, Water/Sewer, Other
# response_format={"type": "json_object"}, temperature=0
response = client.chat.completions.create(
model=os.environ.get("AZURE_OPENAI_DEPLOYMENT", "gpt-4o"),
messages=[
{"role": "system", "content": "You are an assistant that uses only the user input to classify that input "
"into one of the following categories: Pothole, Noise Complaint, Trash/Litter, Street Light, Water/Sewer, Other."
"Return a dict with only these three keys: category, confidence, and reasoning."
"json requirements: category:, confidence:, reasoning:"},
{"role": "user", "content": request_text}

],
response_format={"type": "json_object"},
temperature=0
)
# TODO: Step 1.3 - Parse the JSON response with json.loads()
return json.loads(response.choices[0].message.content)
raise NotImplementedError("Implement classify_311_request in Step 1")


Expand All @@ -124,8 +142,13 @@ def check_content_safety(text: str) -> dict:
dict with keys: safe (bool), categories (dict of category: severity)
"""
# TODO: Step 2.1 - Get the Content Safety client
client = _get_content_safety_client()
# TODO: Step 2.2 - Call client.analyze_text() with AnalyzeTextOptions
from azure.ai.contentsafety.models import AnalyzeTextOptions
result = client.analyze_text(AnalyzeTextOptions(text=text))

# TODO: Step 2.3 - Return safety results

raise NotImplementedError("Implement check_content_safety in Step 2")


Expand All @@ -142,9 +165,14 @@ def extract_key_phrases(text: str) -> list[str]:
List of key phrase strings.
"""
# TODO: Step 3.1 - Get the Language client
client = _get_language_client()
# TODO: Step 3.2 - Call client.extract_key_phrases([text])
response = client.extract_key_phrases([text])
# TODO: Step 3.3 - Return the list of key phrases
raise NotImplementedError("Implement extract_key_phrases in Step 3")
if response[0].is_error == False:
return response[0].key_phrases

# raise NotImplementedError("Implement extract_key_phrases in Step 3")


def main():
Expand Down
Loading