Skip to content

Commit de63136

Browse files
Initial commit
0 parents  commit de63136

File tree

17 files changed

+1558
-0
lines changed

17 files changed

+1558
-0
lines changed

.devcontainer/devcontainer.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "Activity 1 - Hello, Azure AI",
3+
"image": "mcr.microsoft.com/devcontainers/python:3.11",
4+
"postCreateCommand": "python -m pip install -r requirements.txt",
5+
"customizations": {
6+
"vscode": {
7+
"extensions": [
8+
"ms-python.python",
9+
"ms-python.vscode-pylance",
10+
"github.copilot",
11+
"github.copilot-chat"
12+
]
13+
}
14+
}
15+
}

.env.example

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# --- Azure OpenAI (GPT-4o) ---
2+
# Domain: openai.azure.com (OpenAI-specific endpoint)
3+
AZURE_OPENAI_ENDPOINT=https://your-openai-resource.openai.azure.com/
4+
AZURE_OPENAI_API_KEY=your-openai-key-here
5+
AZURE_OPENAI_DEPLOYMENT=gpt-4o
6+
7+
# --- Azure Content Safety ---
8+
# Domain: cognitiveservices.azure.com (shared Cognitive Services endpoint)
9+
AZURE_CONTENT_SAFETY_ENDPOINT=https://your-ai-services-resource.cognitiveservices.azure.com/
10+
AZURE_CONTENT_SAFETY_KEY=your-content-safety-key-here
11+
12+
# --- Azure AI Language ---
13+
# Domain: cognitiveservices.azure.com (shared Cognitive Services endpoint)
14+
AZURE_AI_LANGUAGE_ENDPOINT=https://your-ai-services-resource.cognitiveservices.azure.com/
15+
AZURE_AI_LANGUAGE_KEY=your-language-key-here
16+
17+
# NOTE: Content Safety and Language often share the same multi-service
18+
# Azure AI Services resource, so the endpoint and key may be identical.
19+
# OpenAI uses a separate resource with a different domain.

.github/copilot-instructions.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Copilot Instructions for Activity 1 - Hello, Azure AI
2+
3+
You are a Socratic tutor helping students make their first Azure AI API calls.
4+
5+
## Rules
6+
- NEVER provide complete function implementations
7+
- NEVER show more than 3 lines of code at once
8+
- Ask guiding questions instead of giving answers
9+
- Reference the README sections for step-by-step guidance
10+
- Stay within Activity 1 topics: Azure OpenAI, Content Safety, AI Language
11+
12+
## Activity Context
13+
Students are calling three Azure AI services: Azure OpenAI (classification), Content Safety (text analysis), and AI Language (key phrase extraction). They produce result.json with all three responses.
14+
15+
## Common Questions
16+
- "How do I call Azure OpenAI?" -> Ask: "What parameters does chat.completions.create() need? Check the openai SDK docs."
17+
- "My API call fails" -> Ask: "Are your environment variables set? Try print(os.environ.get('AZURE_OPENAI_ENDPOINT'))"
18+
- "What is lazy initialization?" -> Ask: "Why might creating a client at import time cause problems?"
19+
- "How do Content Safety categories work?" -> Ask: "What does AnalyzeTextOptions expect? Check the SDK."

.github/workflows/autograde.yml

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
name: Autograding
2+
on:
3+
push:
4+
branches: [main]
5+
workflow_dispatch:
6+
7+
env:
8+
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
9+
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
10+
AZURE_CONTENT_SAFETY_ENDPOINT: ${{ secrets.AZURE_CONTENT_SAFETY_ENDPOINT }}
11+
AZURE_CONTENT_SAFETY_KEY: ${{ secrets.AZURE_CONTENT_SAFETY_KEY }}
12+
AZURE_AI_LANGUAGE_ENDPOINT: ${{ secrets.AZURE_AI_LANGUAGE_ENDPOINT }}
13+
AZURE_AI_LANGUAGE_KEY: ${{ secrets.AZURE_AI_LANGUAGE_KEY }}
14+
STUDENT_CORPUS_SEED: ${{ github.actor }}
15+
16+
jobs:
17+
grade:
18+
runs-on: ubuntu-latest
19+
timeout-minutes: 15
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- uses: actions/setup-python@v5
24+
with:
25+
python-version: "3.11"
26+
27+
- name: Install dependencies
28+
run: pip install -r requirements.txt
29+
30+
- name: Run student code
31+
run: python app/main.py
32+
continue-on-error: true
33+
34+
- name: Clone autograder
35+
uses: actions/checkout@v4
36+
with:
37+
repository: Tech901/ai102-autograder-tests
38+
token: ${{ secrets.AUTOGRADER_PAT }}
39+
path: .autograder
40+
41+
# --- 15 tests, 100 points ---
42+
- name: "test_canary_not_default"
43+
id: test1
44+
uses: classroom-resources/autograding-command-grader@v1
45+
with:
46+
test-name: "test_canary_not_default"
47+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_canary_not_default -v --tb=short"
48+
timeout: "5"
49+
max-score: "7"
50+
51+
- name: "test_task_name"
52+
id: test2
53+
uses: classroom-resources/autograding-command-grader@v1
54+
with:
55+
test-name: "test_task_name"
56+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_task_name -v --tb=short"
57+
timeout: "5"
58+
max-score: "7"
59+
60+
- name: "test_status_not_error"
61+
id: test3
62+
uses: classroom-resources/autograding-command-grader@v1
63+
with:
64+
test-name: "test_status_not_error"
65+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_status_not_error -v --tb=short"
66+
timeout: "5"
67+
max-score: "7"
68+
69+
- name: "test_classification_has_required_keys"
70+
id: test4
71+
uses: classroom-resources/autograding-command-grader@v1
72+
with:
73+
test-name: "test_classification_has_required_keys"
74+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_classification_has_required_keys -v --tb=short"
75+
timeout: "5"
76+
max-score: "7"
77+
78+
- name: "test_classification_valid_category"
79+
id: test5
80+
uses: classroom-resources/autograding-command-grader@v1
81+
with:
82+
test-name: "test_classification_valid_category"
83+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_classification_valid_category -v --tb=short"
84+
timeout: "5"
85+
max-score: "7"
86+
87+
- name: "test_content_safety_structure"
88+
id: test6
89+
uses: classroom-resources/autograding-command-grader@v1
90+
with:
91+
test-name: "test_content_safety_structure"
92+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_content_safety_structure -v --tb=short"
93+
timeout: "5"
94+
max-score: "7"
95+
96+
- name: "test_key_phrases_not_empty"
97+
id: test7
98+
uses: classroom-resources/autograding-command-grader@v1
99+
with:
100+
test-name: "test_key_phrases_not_empty"
101+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_key_phrases_not_empty -v --tb=short"
102+
timeout: "5"
103+
max-score: "7"
104+
105+
- name: "test_metadata_has_timestamp"
106+
id: test8
107+
uses: classroom-resources/autograding-command-grader@v1
108+
with:
109+
test-name: "test_metadata_has_timestamp"
110+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_metadata_has_timestamp -v --tb=short"
111+
timeout: "5"
112+
max-score: "7"
113+
114+
- name: "test_content_safety_categories_complete"
115+
id: test9
116+
uses: classroom-resources/autograding-command-grader@v1
117+
with:
118+
test-name: "test_content_safety_categories_complete"
119+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_content_safety_categories_complete -v --tb=short"
120+
timeout: "5"
121+
max-score: "7"
122+
123+
- name: "test_key_phrases_are_relevant"
124+
id: test10
125+
uses: classroom-resources/autograding-command-grader@v1
126+
with:
127+
test-name: "test_key_phrases_are_relevant"
128+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_key_phrases_are_relevant -v --tb=short"
129+
timeout: "5"
130+
max-score: "7"
131+
132+
- name: "test_classification_confidence_range"
133+
id: test11
134+
uses: classroom-resources/autograding-command-grader@v1
135+
with:
136+
test-name: "test_classification_confidence_range"
137+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_classification_confidence_range -v --tb=short"
138+
timeout: "5"
139+
max-score: "6"
140+
141+
- name: "test_result_status_is_success"
142+
id: test12
143+
uses: classroom-resources/autograding-command-grader@v1
144+
with:
145+
test-name: "test_result_status_is_success"
146+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_result_status_is_success -v --tb=short"
147+
timeout: "5"
148+
max-score: "6"
149+
150+
- name: "test_classify_novel_input_noise"
151+
id: test13
152+
uses: classroom-resources/autograding-command-grader@v1
153+
with:
154+
test-name: "test_classify_novel_input_noise"
155+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_classify_novel_input_noise -v --tb=short"
156+
timeout: "5"
157+
max-score: "6"
158+
159+
- name: "test_content_safety_novel_input_water"
160+
id: test14
161+
uses: classroom-resources/autograding-command-grader@v1
162+
with:
163+
test-name: "test_content_safety_novel_input_water"
164+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_content_safety_novel_input_water -v --tb=short"
165+
timeout: "5"
166+
max-score: "6"
167+
168+
- name: "test_extract_key_phrases_novel_input_water"
169+
id: test15
170+
uses: classroom-resources/autograding-command-grader@v1
171+
with:
172+
test-name: "test_extract_key_phrases_novel_input_water"
173+
command: "python -m pytest .autograder/activity01-hello-azure-ai/test_hidden.py::test_extract_key_phrases_novel_input_water -v --tb=short"
174+
timeout: "5"
175+
max-score: "6"
176+
177+
- name: Autograding Reporter
178+
uses: classroom-resources/autograding-grading-reporter@v1
179+
env:
180+
TEST1_RESULTS: "${{ steps.test1.outputs.result }}"
181+
TEST2_RESULTS: "${{ steps.test2.outputs.result }}"
182+
TEST3_RESULTS: "${{ steps.test3.outputs.result }}"
183+
TEST4_RESULTS: "${{ steps.test4.outputs.result }}"
184+
TEST5_RESULTS: "${{ steps.test5.outputs.result }}"
185+
TEST6_RESULTS: "${{ steps.test6.outputs.result }}"
186+
TEST7_RESULTS: "${{ steps.test7.outputs.result }}"
187+
TEST8_RESULTS: "${{ steps.test8.outputs.result }}"
188+
TEST9_RESULTS: "${{ steps.test9.outputs.result }}"
189+
TEST10_RESULTS: "${{ steps.test10.outputs.result }}"
190+
TEST11_RESULTS: "${{ steps.test11.outputs.result }}"
191+
TEST12_RESULTS: "${{ steps.test12.outputs.result }}"
192+
TEST13_RESULTS: "${{ steps.test13.outputs.result }}"
193+
TEST14_RESULTS: "${{ steps.test14.outputs.result }}"
194+
TEST15_RESULTS: "${{ steps.test15.outputs.result }}"
195+
with:
196+
runners: test1,test2,test3,test4,test5,test6,test7,test8,test9,test10,test11,test12,test13,test14,test15

.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
*.egg-info/
7+
dist/
8+
build/
9+
*.egg
10+
11+
# Virtual environments
12+
.venv/
13+
venv/
14+
ENV/
15+
16+
# IDE
17+
.vscode/
18+
.idea/
19+
*.swp
20+
*.swo
21+
*~
22+
23+
# Environment variables (NEVER commit real keys)
24+
.env
25+
.env.local
26+
.env.*.local
27+
28+
# Lab output (regenerated by running code)
29+
result.json
30+
eval_report.json
31+
design.json
32+
33+
# OS files
34+
.DS_Store
35+
Thumbs.db
36+
37+
# Autograder (cloned during CI)
38+
.autograder/

0 commit comments

Comments
 (0)