Building with AI APIs

Expert · 18 min read · ▶ live playground · ✦ checkpoint

The model you trained in the last lesson ran locally: Python had the data, the model object, and the prediction all in one process. An AI API is different: your Python program sends a request to an external AI service, receives a response, and then decides what to trust, reject, store, or show.

This lesson makes no live API calls. You will build provider-neutral request dictionaries, placeholder secrets, canned JSON responses, validation, retry decisions, and redacted logs.

Local model or AI API?

A local model workflow keeps the model close to your code. In your first scikit-learn model, fit() trained a tiny classifier and predict() ran inside the same Python session. That shape is good for classic table-based ML when you own the data and model choice.

An AI API workflow crosses an external-system boundary. Your code sends text, settings, and authentication to a provider's API endpoint, the URL where a service accepts requests, then handles the response. That looks like the API client work from Consuming APIs & Web Scraping, with the extra AI concerns from Using AI Responsibly.

A provider-neutral request shape looks like this:

Static shape only - not run in this browser lesson:
 
POST https://api.ai-provider.test/v1/responses
Authorization: Bearer <secret from environment>
Content-Type: application/json
 
{
  "model": "provider-model-id",
  "temperature": 0.2,
  "messages": [
    {"role": "system", "content": "Return concise JSON for a study helper."},
    {"role": "user", "content": "Suggest one review topic for lists."}
  ],
  "response_format": {"type": "json_object"}
}

There is no real provider, key, model ranking, dashboard, or price claim here. The point is the contract: request in, response out, checks around both.

Prompts, roles, settings, and secrets

A prompt is the instruction or input text you send to an AI model. Many chat-style APIs wrap prompts as messages, each with a role. A user message carries the end user's request. A system or developer message, when the API supports those roles, carries app-owned instructions such as output format, tone, and safety boundaries.

Do not rely on message wording alone for safety. A user can ask for output that ignores your format, exposes private data, or invents facts. Your code still validates the response.

An API key is a secret that proves which account is making the request. It belongs in an environment variable or secret store in real projects, never in source code, screenshots, or logs. A temperature or creativity setting controls how varied the output may be at a conceptual level: lower values usually ask for steadier output; higher values invite more variation. For code, JSON, and business rules, predictable output is usually easier to validate.

Here is a safe request builder. It constructs headers and a payload, then logs a redacted version:

import json
 
api_key = "<AI_API_KEY_FROM_ENV>"
endpoint = "https://api.ai-provider.test/v1/responses"
 
payload = {
    "model": "provider-model-id",
    "temperature": 0.2,
    "messages": [
        {"role": "system", "content": "Return concise JSON for a study helper."},
        {"role": "user", "content": "Suggest one review topic for lists."},
    ],
    "response_format": {"type": "json_object"},
}
 
headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json",
}
 
safe_headers = {
    name: ("<redacted>" if name.lower() == "authorization" else value)
    for name, value in headers.items()
}
 
print("POST", endpoint)
print("headers:", json.dumps(safe_headers, sort_keys=True))
print("payload:", json.dumps(payload, indent=2))

POST https://api.ai-provider.test/v1/responses
headers: {"Authorization": "<redacted>", "Content-Type": "application/json"}
payload: {
"model": "provider-model-id",
"temperature": 0.2,
"messages": [
{
"role": "system",
"content": "Return concise JSON for a study helper."
},
{
"role": "user",
"content": "Suggest one review topic for lists."
}
],
"response_format": {
"type": "json_object"
}
}

The placeholder key is not real and the code never sends anything. Log enough to debug the request shape, not enough to leak access.

Validate structured responses

AI text can be useful and still be wrong. If your app expects JSON, treat the JSON as untrusted input. Validation means checking that the response has the fields, types, and ranges your program needs before using it.

The live playground below simulates a valid response, malformed JSON, JSON with schema/type problems, a rate limit with Retry-After, and a temporary server problem.

Try it - validate canned AI responses

This code uses only the standard library. It does not import SDKs, requests, httpx, urllib.request, or any other network tool.

python — playgroundlive
⌘/Ctrl + Enter to run

Notice the shape from Interacting with the World: bounded retries, rate-limit respect, and explicit refusal. A 429 response means slow down. A temporary 503 can be retried for a limited number of attempts, then your program should stop and surface the failure.

Cost, logs, and human review

External AI calls have operational limits even when the code is correct. Rate limits cap how many requests you can make in a time window. Cost can mean money, credits, or quota consumed by requests and generated output. Do not hide those facts behind a button that fires unlimited calls.

Good logs answer developer questions without exposing secrets: endpoint shape, request or job ID, whether a key was configured, the response status, and whether the result was accepted, rejected, retried, or sent for human review.

Human review belongs anywhere mistakes are costly: medical, legal, financial, safety, education placement, hiring, account action, or public posting. The app should make it clear when AI produced something, what evidence was checked, and who approved the final action.

This closes the Part V arc: Python can analyze data, query databases, serve APIs, automate external systems, train local models, and call AI services. The same professional habit keeps showing up: make the boundary explicit, validate what crosses it, protect secrets, and keep a human responsible for the result.

Checkpoint

Answer all three to mark this lesson complete

+50 XP on completion