Python + Claude API: Your First AI App in Neovim | Episode 1
Video: Python + Claude API: Your First AI App in Neovim | Episode 1 by Taught by Celeste AI - AI Coding Coach
Student code: github.com/GoCelesteAI/build-ai-apps-python/tree/main/episode01 One file. Twenty lines. Your first working AI app.
If you can write Python — variables, functions, pip install, a requirements.txt — you can build AI applications. You don't need a machine-learning degree. You don't need a GPU. You don't need to read a paper. The hard part has already been done by the model; your job is to send it a question over HTTP and read the answer.
That's what this episode is. By the end of the next four minutes, you'll have a Python script that asks Claude a question and prints the answer to your terminal. From there, the rest of the series — thirty-two episodes — is about turning that one script into chatbots, tools, retrieval pipelines, and full agents.
Let's get there in one sitting.
What the Claude API actually is
Before any code, the mental model.
When people hear "AI" they often picture training. Datasets. Loss curves. A 70-billion-parameter model that takes weeks to fit. None of that is what we're doing. The model has already been trained — that's Anthropic's job. What you and I get is an endpoint. A URL that accepts a JSON body containing your question and returns a JSON body containing the answer.
That endpoint is the Claude API. The anthropic Python package is a thin wrapper around it: it serialises your message into JSON, signs the request with your API key, parses the response, and hands you back a Python object. That's the entire integration.
So when you "build an AI app," what you're really doing is:
- Construct a message in the shape the API expects.
- Send it.
- Do something interesting with the answer.
Step 1 and step 2 are five lines of code. Step 3 is the rest of your career as an AI engineer.
What you need before you start
A working Python install — anything 3.9 or newer. A terminal. A code editor (we're using Neovim throughout this series, but the code is identical in VS Code or PyCharm). And an Anthropic API key.
If you don't have a key yet, sign in at console.anthropic.com, create a new key, and copy it somewhere safe. Treat it like a password: anyone with this string can spend money against your account.
We'll use two libraries:
anthropic— the official Python SDKpython-dotenv— loads environment variables from a.envfile so we never hardcode the key
Set up an isolated environment and install both:
mkdir ai_practice && cd ai_practice
python3 -m venv venv
source venv/bin/activate
pip install anthropic python-dotenv
A virtual environment isn't strictly required to make the call work, but it's the right habit. Each project gets its own dependency tree; nothing leaks into your global Python.
The .env file
The first thing we create — before any Python — is a file named .env containing your API key:
ANTHROPIC_API_KEY=sk-ant-...your-real-key-here...
That's the entire file. One line. No quotes around the value. No export keyword.
There are two reasons we do this instead of putting the key directly in the script:
You don't accidentally commit secrets. Your .env belongs in .gitignore from day one. If the key is in .env and .env is gitignored, you can push your code to a public repo and the key stays on your machine. The moment you hardcode client = Anthropic(api_key="sk-ant-...") into a .py file, you're one absent-minded git push away from someone else's bill.
You get environment-specific config for free. Your laptop has a dev key. Production has a different key. The same code reads os.getenv("ANTHROPIC_API_KEY") in both places and gets the right one. No conditionals. No edits when you deploy.
The anthropic SDK is even kinder than that: if the environment variable is set, you don't have to pass it explicitly. Anthropic() with no arguments will pick it up automatically.
The script, line by line
Here's the whole thing. Twenty lines including blank ones.
# Episode 1: Your First AI API Call
# Build AI Apps with Python in Neovim
import os
from dotenv import load_dotenv
from anthropic import Anthropic
load_dotenv()
client = Anthropic()
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{"role": "user", "content": "What is Python in one sentence?"}
],
)
print(message.content[0].text)
Let's walk it.
import os
from dotenv import load_dotenv
from anthropic import Anthropic
Three imports. os is standard library — we don't actually need it in this script (the SDK reads the env var for us), but it's the conventional companion to load_dotenv and you'll need it the moment you want to read other env vars by hand. load_dotenv is the function that pulls .env into os.environ. Anthropic is the SDK's main client class.
load_dotenv()
Calling load_dotenv() with no arguments looks for a .env file in the current working directory and loads each KEY=value line into the process's environment. After this call, ANTHROPIC_API_KEY is set as if you had exported it in your shell.
client = Anthropic()
This builds the client. Internally it reads ANTHROPIC_API_KEY from the environment (the one we just loaded) and prepares an HTTPS connection to Anthropic's servers. No network call has happened yet — the client is just configured.
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[
{"role": "user", "content": "What is Python in one sentence?"}
],
)
This is the actual API call. Three parameters do the work.
model says which Claude to talk to. The string "claude-sonnet-4-20250514" is a versioned model ID — it pins behaviour to a specific model snapshot so your code doesn't drift when Anthropic releases a newer one. We'll use Sonnet for nearly all of this series; it's fast, cheap, and capable.
max_tokens is the maximum length of the response, measured in tokens (roughly four characters or three-quarters of a word in English). 1024 is comfortably more than a one-sentence answer needs. Setting it stops a runaway response from costing you a surprise; the model will stop generating once it hits this ceiling.
messages is the conversation. It's a list because future episodes will append more turns — for now we send one user message. Each item has a role ("user" or "assistant") and a content string. This is the format Claude expects: a transcript, not a single prompt blob.
When create() returns, message is a Python object representing the API's response.
print(message.content[0].text)
The response's content is a list of "content blocks" — Claude can return text, tool-use requests, images, and more. For a plain text answer it's a one-element list, and [0].text gives you the string. We print it.
That's the whole script.
Running it
Save the file as first_call.py. From Neovim, type :!python % and press Enter. The % expands to the current file's name; the ! runs a shell command. A few seconds later — the request crosses the internet and a model on the other side composes a sentence — and Claude's reply prints in your terminal:
Python is a high-level, interpreted programming language known for its clean, readable syntax and versatility across web development, data science, automation, and artificial intelligence applications.
That's it. You just made an AI API call from Python.
Changing the question
The whole point of an API is parameterisation. Open the file again. Change the question:
{"role": "user", "content": "Explain what an API is in simple terms"}
Save. Run it again. The response is different — same model, same code, different output, because the input changed. That single line is the lever every AI feature you'll ever build pulls on. Want a translator? Put text in the user message and ask for the translation. Want a code reviewer? Paste a function and ask for feedback. Want a study buddy? Ask it to quiz you on a topic.
You don't write new code to do new things. You write new prompts.
Errors you'll hit at least once
Three things go wrong on the first call. All three have one-line fixes.
AuthenticationError: invalid x-api-key. Your .env doesn't have the right key, or load_dotenv() didn't find the file. Confirm the file is named exactly .env (not env.txt), is in the same directory as the Python script, and that the key starts with sk-ant-. Run echo $ANTHROPIC_API_KEY in your shell after activating the venv to check what the process sees.
NotFoundError: model: claude-.... The model ID is wrong or has been deprecated. Check console.anthropic.com for the current model list and copy the exact string. Model IDs are case-sensitive and date-stamped.
RateLimitError. You're calling the API faster than your account tier allows. New accounts get a low limit; you can raise it in the console. For local development you'll almost never hit it unless you're in a tight loop.
If you see a generic ConnectionError, your machine can't reach api.anthropic.com. Corporate firewalls and VPNs are the usual culprits.
Why this matters more than it looks
Twenty lines of Python and a credit card now buy you a model that, five years ago, would have required a research lab. The economic shift here is the entire reason this series exists.
Every interesting AI feature in 2026 — code completion, customer support agents, document summarisers, the chatbot in your bank's app — sits on top of an API call that looks structurally identical to the one you just wrote. The differences live in three places: what you put in messages, what you do with the response, and what tools you give the model access to. We'll cover all three.
What's coming in the rest of the series
Thirty-two episodes. Four phases. Same Neovim, same Python, same Claude API throughout.
| Phase | Episodes | What you'll be able to build |
|---|---|---|
| 1. API fundamentals | 1–6 | Single-call scripts, system prompts, streaming chatbots, multi-turn conversation |
| 2. Tools & structured output | 7–14 | Function-calling, JSON outputs, retrieval-augmented Q&A over your own files |
| 3. Agents | 15–22 | Autonomous loops, planning, multi-tool agents, error recovery |
| 4. Production | 23–32 | Cost control, observability, deployment, rate limiting, evaluation |
By Ep6 you have a streaming chatbot that holds a conversation. By Ep14 you have an agent that can search a folder of PDFs and answer questions with citations. By Ep22 you have an autonomous task-runner. By Ep32 you have a deployed app with logging, retries, eval harness, and a cost dashboard.
The skill compounds. Every episode produces a working script you can run. Every script becomes the starting point for the next one.
Recap
What we did today. Created a virtual environment. Installed anthropic and python-dotenv. Put an API key in a .env file. Wrote twenty lines of Python that send "What is Python in one sentence?" to Claude and print the response. Changed the question and ran it again to prove the API is just a function with text as input and text as output.
You haven't built an AI app yet. You've built the cell every AI app is made of. Everything in the rest of the series is a different shape made from the same cell.
Next episode: System prompts. The single parameter that turns "ask Claude a question" into "ask a chef a question" — or a pirate, or a tax accountant, or a code reviewer. Same API, same model, dramatically different behaviour.
See you in the next one.