How to Build Your First AI Application with Python (Part 1: Setup and First Call)
Every part so far has built the real, conceptual foundation. This part starts the real, hands-on project this series has been building toward — a genuine, working Python application answering customer questions for Bright Leaf Coffee, using everything covered in parts 1 through 15.
Real, practical setup
mkdir bright-leaf-support
cd bright-leaf-support
python -m venv venv
source venv/bin/activate # on Windows: venv\Scripts\activate
pip install anthropic python-dotenvanthropic is the real, official Python SDK for Claude's API — a real, practical wrapper around the raw HTTPS requests described conceptually in part 14, handling authentication headers and response parsing for you. python-dotenv loads real environment variables from a local file, the real, correct way to handle the API key security concern flagged in part 14.
Storing the real API key correctly
# .env (never committed to version control)
ANTHROPIC_API_KEY=your-real-api-key-here# .gitignore
.envThis directly implements part 14's security guidance concretely — the real key lives in a local, uncommitted file, loaded into the environment at runtime, never hardcoded directly into a real, committed Python file.
The real, first working API call
import os
from dotenv import load_dotenv
from anthropic import Anthropic
load_dotenv()
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
system=(
"You are a customer support assistant for Bright Leaf Coffee, "
"a small-batch coffee subscription business. Only answer using "
"real information provided in this conversation. If you don't "
"have the information needed, say so directly rather than "
"guessing. Keep responses to 2-3 sentences."
),
messages=[
{"role": "user", "content": "What subscriptions do you offer?"}
],
)
print(response.content[0].text)This is a real, complete, runnable request — every piece maps directly to a concept already covered: system is exactly part 11's system role, messages follows the exact real structure from part 11, max_tokens bounds the real, generated response per part 8's token discussion, and model selects a specific real Claude model.
Notice the system prompt here is the exact, real one designed in part 11 and part 13 — not a new example. This is deliberate: every real design decision made conceptually earlier in this series (grounding in provided data, permission to say "I don't know," explicit tone and length constraints) shows up directly in this actual, working code, rather than being abstract advice disconnected from a real implementation.
A real problem with this first version: no actual data
Asking "What subscriptions do you offer?" right now gets an answer
based on the model's own real reasoning about what a coffee
subscription business PROBABLY offers — not Bright Leaf Coffee's
actual, real plans, since none were included in the promptThis is a deliberate, real gap this first version has — exactly the hallucination risk covered in part 13, made concrete. The fix is straightforward and directly follows part 13's grounding technique:
messages=[
{
"role": "user",
"content": (
"Our real, current plans are:\n"
"- Gift Subscription: $18/mo, 1 bag, free shipping\n"
"- Monthly Subscription: $16/mo, 1 bag, free shipping\n\n"
"Customer question: What subscriptions do you offer?"
),
}
],With the real, actual plan data included directly in the message, the model's answer is now genuinely grounded in real facts rather than a plausible-sounding guess — exactly the practical payoff of part 13's core mitigation technique, now working in real, running code.
What this real, first version is still missing
No error handling for a real, failed request (network issue, rate
limit from part 15)
No streaming — the full response is generated before anything prints
No real conversation memory across multiple messagesThese are exactly what parts 17 and 18 build on top of this real, working foundation — not new, separate examples, but direct extensions of this exact code.
Next: building your first AI application, part 2 — real error handling and streaming responses, making this actual code production-ready.