~/TechPurAI
~/tutorials/ai-fundamentals/building-your-first-ai-application-setup-and-first-api-call
intermediate·part 16 of 22·3 min read

How to Build Your First AI Application with Python (Part 1: Setup and First Call)

Updated Aug 16, 2026AI

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

bash
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-dotenv

anthropic 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

text
# .env (never committed to version control)
ANTHROPIC_API_KEY=your-real-api-key-here
text
# .gitignore
.env

This 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

python
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.

Why it matters

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

text
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 prompt

This 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:

python
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

text
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 messages

These 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.

VK

Vijay Kumar

Founder of TechPurAI — writing hands-on tutorials and honest tool breakdowns.

LinkedIn ↗
← previous15. Reading Real AI API Documentation: Endpoints, Auth, and Rate Limitsnext →17. How to Build Your First AI Application with Python (Part 2: Error Handling and Streaming)