Capstone: your first AI API call

This is it! You have learned variables, functions, classes, async, generators, and modern Python. Now you will put it ALL together: load config from .env, call a real LLM with LiteLLM, and parse the response. This is the exact pattern at the heart of every advanced course.

AI API call lifecycle

The flow from config to response in every AI application.

capstone_ai_api_call.py
python
import os
from dotenv import load_dotenv

# Step 1: Load configuration
load_dotenv()
DEFAULT_MODEL = os.getenv("DEFAULT_MODEL", "gemini/gemini-2.0-flash")
print(f"Using model: {DEFAULT_MODEL}")

Step 1: Load your .env file and read the model name. This is the first 3 lines of every AI script.

Config is loaded. Now import LiteLLM and make the actual API call. Notice how the messages list uses the exact dict-in-a-list pattern you learned earlier.

capstone_ai_api_call.py
python
# Step 2: Import the universal LLM library
from litellm import completion

# Step 3: Make your first API call!
question = "Explain what RAG (Retrieval-Augmented Generation) is in 2 sentences."

try:
    response = completion(
        model=DEFAULT_MODEL,
        messages=[
            {"role": "system", "content": "You are a helpful AI tutor. Be concise."},
            {"role": "user", "content": question},
        ],
        temperature=0.7,
    )
except Exception as e:
    print(f"API call failed: {e}")
    print("Check your .env file. Is your API key set correctly?")
    exit(1)

Step 2-3: Import LiteLLM and call the API. Notice the messages list pattern you learned earlier. The try/except from earlier handles errors gracefully.

The API call is done. Now extract the actual text from the response object and inspect the metadata. The path response.choices[0].message.content is the same across all LLM providers.

capstone_ai_api_call.py
python
# Step 4: Extract the answer
answer = response.choices[0].message.content
print(f"Answer:\n{answer}")

# Step 5: Inspect the response metadata
print(f"\n--- Response metadata ---")
print(f"Model: {response.model}")
print(f"Tokens used: {response.usage.total_tokens}")
print(f"Finish reason: {response.choices[0].finish_reason}")

Step 4-5: Extract the text from the response and inspect metadata. response.choices[0].message.content is the universal pattern across all LLM providers.

Exactly! This load_dotenv + completion() + parse response pattern is the foundation of: the text-to-sql agent, the RAG pipeline, the Claude Code agent, and every other AI application. You now have the core skill. Everything else builds on top of this.

capstone_ai_api_call.py
python
import os
from dotenv import load_dotenv
from litellm import completion

# Complete capstone: your first AI API call
load_dotenv()
DEFAULT_MODEL = os.getenv("DEFAULT_MODEL", "gemini/gemini-2.0-flash")

try:
    response = completion(
        model=DEFAULT_MODEL,
        messages=[
            {"role": "system", "content": "You are a helpful AI tutor. Be concise."},
            {"role": "user", "content": "Explain what RAG is in 2 sentences."},
        ],
        temperature=0.7,
    )
    answer = response.choices[0].message.content
    print(f"Answer: {answer}")
    print(f"Tokens: {response.usage.total_tokens}")
except Exception as e:
    print(f"Error: {e}")

The complete capstone script. Every concept from the course is here: imports, dotenv, functions, dicts, try/except, string formatting, and the completion API.

AI prompt: Try it with AI

Loading practiceโ€ฆ

Quiz: Quiz

Loading practiceโ€ฆ

Validation checklist: Capstone validation

Loading practiceโ€ฆ