Hello, Jarvis 👋
Eleven lines of Python that talk to a language model. We will write them, run them, and then take every one apart, because the whole rest of the build is variations on this.
Make your first API call and understand every single line of it.
about 25 minutesThe whole program
Create hello.py:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=300,
messages=[
{"role": "user", "content": "In one sentence, what is Python?"}
],
)
for block in response.content:
if block.type == "text":
print(block.text)
Run it:
python3 hello.py
After a second or two you get a sentence about Python. You just paid about a fifth of a cent. Now let us make sure you know exactly what happened.
Line by line
import anthropic
Pulls in the library you installed. It is ordinary Python; you could read its source. All it really does is send HTTP requests and parse the replies, which you already learned about in Lesson 43.
client = anthropic.Anthropic()
Makes the object that knows how to talk to the API. Note the empty brackets: as
chapter 2 explained, it finds ANTHROPIC_API_KEY in your environment on its
own. Make it once and reuse it; it holds a connection pool.
client.messages.create(...)
The actual request. Everything else in this build is this call with more arguments. It sends your message off and waits for the whole reply to come back.
model="claude-haiku-4-5"
Which model answers. One string, and the only thing you change to trade cost for capability. Chapter 1 has the table.
max_tokens=300
The ceiling on the reply length, in tokens (about three quarters of a word each). This is a safety limit, not a target: the model stops when it has finished, and you only pay for what it actually writes. Set it too low and answers get cut off mid-sentence.
messages=[...]
The conversation, as a list. Each entry is a dictionary with a role and
some content. "user" is you. Right now there is exactly one
message, which is why the model has no idea who you are or what you asked before.
The loop at the end
This is the part that surprises people. response.content is
a list, not a string, because a reply can contain several kinds of block:
text, a request to use a tool (chapter 8), and others. So you check each block's
type before reading .text off it.
You will see that shortcut everywhere and it works right up until it does not. The moment you add tools, block zero may be a tool request with no .text at all, and your program dies with an AttributeError you will not enjoy debugging. Checking the type costs one line and never breaks.
Seeing the shape of a reply
The response object has more on it than the text. This prints the useful parts:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=300,
messages=[{"role": "user", "content": "Say hello in exactly three words."}],
)
print("model used :", response.model)
print("why stopped:", response.stop_reason)
print("tokens in :", response.usage.input_tokens)
print("tokens out :", response.usage.output_tokens)
print("blocks :", [b.type for b in response.content])
for block in response.content:
if block.type == "text":
print("text :", block.text)
Output looks roughly like this (your numbers will differ slightly):
model used : claude-haiku-4-5
why stopped: end_turn
tokens in : 16
tokens out : 8
blocks : ['text']
text : Hello there, friend.
stop_reason is worth knowing now because you will meet it properly in
chapter 8:
| stop_reason | What it means |
|---|---|
end_turn | It finished naturally. The normal case. |
max_tokens | It hit your ceiling and got cut off. Raise max_tokens. |
tool_use | It wants to use a tool you gave it. All of chapter 8. |
refusal | It declined on safety grounds. |
The cost, for real this time
You now have real token counts, so you can compute what that call actually cost. This function is one you will reuse in chapter 12:
def cost_of(tokens_in, tokens_out, price_in=1.00, price_out=5.00):
"""Dollar cost of one call. Prices are per million tokens."""
return (tokens_in / 1_000_000) * price_in + (tokens_out / 1_000_000) * price_out
# the numbers printed above
print(f"that call cost ${cost_of(16, 8):.6f}")
print(f"a thousand like it: ${cost_of(16, 8) * 1000:.4f}")
that call cost $0.000056
a thousand like it: $0.0560
Five and a half cents for a thousand short exchanges. This is why the honest answer to "can I afford to learn this?" is yes.
If it went wrong
anthropic.AuthenticationErrorThe key is missing, mistyped, or from a different account. Re-runcheck_key.pyfrom chapter 2.- Something about credit or billing The account has no funds. Add a few dollars in the console.
anthropic.NotFoundErrorThe model name is wrong or retired. Check the current list in Anthropic's docs.anthropic.APIConnectionErrorYour network, a proxy, or a firewall. It is not your code.
Chapter 12 turns every one of those into a friendly sentence instead of a stack trace.
python3 hello.py prints a sentence written by a language model, and you can point at any line in the file and say what it does.