DEV Community

Cover image for Claude API Tutorial: Complete Beginner's Guide (Python, 2026)
Serhii Kalyna
Serhii Kalyna

Posted on • Originally published at kalyna.pro

Claude API Tutorial: Complete Beginner's Guide (Python, 2026)

Originally published at kalyna.pro

The Claude API gives you direct access to Anthropic's language models from any Python application. Whether you want to generate text, analyze images, stream responses token by token, or wire up tools so Claude can call your own functions — all of it goes through the same client.messages.create() call. This tutorial walks through every major feature with working code, from your first "Hello!" to a full tool-use loop.

Prerequisites

You need Python 3.8 or later and an Anthropic API key. If you do not have a key yet, follow the step-by-step guide at How to Get a Claude API Key — it takes about two minutes.

export ANTHROPIC_API_KEY="sk-ant-..."   # add to ~/.bashrc or ~/.zshrc
Enter fullscreen mode Exit fullscreen mode

Installation and First Call

pip install anthropic
Enter fullscreen mode Exit fullscreen mode

Make your first API call — the SDK reads ANTHROPIC_API_KEY automatically:

from anthropic import Anthropic

client = Anthropic()

msg = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)

print(msg.content[0].text)
Enter fullscreen mode Exit fullscreen mode

The Messages API

Every call to client.messages.create() accepts the same core parameters:

  • model — the Claude model to use (e.g. "claude-sonnet-4-6")
  • max_tokens — the upper limit on output tokens
  • messages — a list of turn objects with role ("user" or "assistant") and content
  • system — an optional system prompt string

The content field can be a plain string or a list of content blocks — objects with a type field ("text", "image", "tool_use", "tool_result"). The response exposes msg.content[0].text, msg.stop_reason, and msg.usage for token counts.

Your First Chat App

The Messages API is stateless. Append each exchange to the messages list to maintain conversation history:

from anthropic import Anthropic

client = Anthropic()
conversation = []

print("Chat with Claude (type 'quit' to exit)\n")

while True:
    user_input = input("You: ").strip()
    if user_input.lower() in ("quit", "exit", "q"):
        break
    if not user_input:
        continue

    conversation.append({"role": "user", "content": user_input})

    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=conversation,
    )

    assistant_text = response.content[0].text
    conversation.append({"role": "assistant", "content": assistant_text})

    print(f"Claude: {assistant_text}\n")
Enter fullscreen mode Exit fullscreen mode

Streaming Responses

Use client.messages.stream() to display tokens as they arrive:

from anthropic import Anthropic

client = Anthropic()

with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Explain quantum entanglement simply."}],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

print()
Enter fullscreen mode Exit fullscreen mode

Call stream.get_final_message() after the loop if you need the complete Message object.

Analyzing Images with Vision

Pass images as base64-encoded content blocks:

import base64
from anthropic import Anthropic

client = Anthropic()

with open("screenshot.png", "rb") as f:
    image_data = base64.standard_b64encode(f.read()).decode("utf-8")

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/png",
                        "data": image_data,
                    },
                },
                {
                    "type": "text",
                    "text": "Describe what you see in this image.",
                },
            ],
        }
    ],
)

print(response.content[0].text)
Enter fullscreen mode Exit fullscreen mode

Supported types: image/jpeg, image/png, image/gif, image/webp. You can also pass images by URL using "type": "url".

Tool Use (Function Calling)

Define tools with JSON Schema, handle stop_reason == "tool_use", and return results as tool_result blocks:

from anthropic import Anthropic

client = Anthropic()

tools = [
    {
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "City name, e.g. 'Kyiv'"},
            },
            "required": ["city"],
        },
    }
]


def get_weather(city: str) -> str:
    return f"The weather in {city} is 22°C and sunny."


messages = [{"role": "user", "content": "What's the weather in Kyiv?"}]

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    tools=tools,
    messages=messages,
)

if response.stop_reason == "tool_use":
    tool_block = next(b for b in response.content if b.type == "tool_use")
    tool_result = get_weather(**tool_block.input)

    messages.append({"role": "assistant", "content": response.content})
    messages.append({
        "role": "user",
        "content": [
            {
                "type": "tool_result",
                "tool_use_id": tool_block.id,
                "content": tool_result,
            }
        ],
    })

    final = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        tools=tools,
        messages=messages,
    )
    print(final.content[0].text)
else:
    print(response.content[0].text)
Enter fullscreen mode Exit fullscreen mode

System Prompts

The system parameter sets a persistent instruction outside the turn list:

from anthropic import Anthropic

client = Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system=(
        "You are a senior Python engineer. "
        "Always respond with concise, production-quality code. "
        "Prefer explicit error handling and type hints."
    ),
    messages=[{"role": "user", "content": "Write a function to retry a failed HTTP request."}],
)

print(response.content[0].text)
Enter fullscreen mode Exit fullscreen mode

Tips: be specific about format, state constraints positively, keep the system prompt stable across turns, and use prompt caching on long system prompts to cut costs.

Choosing a Model

  • claude-opus-4-7 — most capable; best for complex reasoning and multi-step agentic tasks
  • claude-sonnet-4-6 — balanced quality, cost, and speed; the right default for most apps
  • claude-haiku-4-5 — fastest and cheapest; ideal for high-volume, real-time, or extraction tasks

All three support the same API surface. Start with claude-sonnet-4-6 and adjust from there.

Summary

  • Install with pip install anthropic; the SDK reads ANTHROPIC_API_KEY automatically
  • Every feature goes through client.messages.create()
  • Multi-turn chat: append each exchange to the messages list
  • Streaming: use client.messages.stream() and iterate stream.text_stream
  • Vision: pass base64-encoded images as content blocks
  • Tool use: define tools with JSON Schema, handle tool_use stop reason, return tool_result blocks
  • System prompts: use the system parameter outside the messages list
  • Default to claude-sonnet-4-6; upgrade to Opus for quality, downgrade to Haiku for speed

Further reading:

Top comments (0)