Working Python code to summarize text, documents, and URLs with the Claude API in 2026. Covers bullet-point summaries, extractive key points, long-document chunking, and structured JSON output.
Claude produces high-quality summaries out of the box — no fine-tuning required. The key is a precise system prompt that specifies length, format, and perspective. Below are working patterns for the most common summarization use cases.
import anthropic
client = anthropic.Anthropic()
def summarize(text: str, max_sentences: int = 3) -> str:
response = client.messages.create(
model="claude-haiku-4-5-20251001", # cheapest model, great for summaries
max_tokens=512,
system=f"Summarize the following text in {max_sentences} sentences. Be concise and capture the main point.",
messages=[{"role": "user", "content": text}]
)
return response.content[0].text
article = """
Anthropic released Claude 3.5 Sonnet in June 2024, followed by Claude 3.5 Haiku in November.
The Claude 4 family launched in early 2026 with Sonnet 4.6 and Opus 4.7 offering 200K context windows.
Anthropic's models consistently score near the top of LMSYS Chatbot Arena leaderboard benchmarks.
"""
print(summarize(article))
def bullet_summary(text: str, n_points: int = 5) -> list[str]:
response = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=512,
system=f"Extract exactly {n_points} key points from the text. Return them as a JSON array of strings. No other text.",
messages=[{"role": "user", "content": text}]
)
import json
return json.loads(response.content[0].text)
points = bullet_summary(article)
for p in points:
print(f"• {p}")
import json
def structured_summary(text: str) -> dict:
system = """Return a JSON object with these exact keys:
- summary: 2-3 sentence overview
- key_points: list of 5 concise strings
- sentiment: one of "positive", "neutral", "negative"
- topics: list of up to 5 topic tags
No markdown, no explanation — only the raw JSON object."""
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=system,
messages=[{"role": "user", "content": text}]
)
return json.loads(response.content[0].text)
result = structured_summary(article)
print(result["summary"])
print(result["key_points"])
print(result["sentiment"])
def chunk_text(text: str, words_per_chunk: int = 3000) -> list[str]:
words = text.split()
return [
" ".join(words[i:i + words_per_chunk])
for i in range(0, len(words), words_per_chunk)
]
def summarize_long_document(text: str) -> str:
chunks = chunk_text(text)
if len(chunks) == 1:
return summarize(text)
# Map: summarize each chunk
chunk_summaries = [summarize(chunk, max_sentences=5) for chunk in chunks]
# Reduce: synthesize chunk summaries into a final summary
combined = "
".join(f"[Section {i+1}]
{s}" for i, s in enumerate(chunk_summaries))
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system="You have been given summaries of individual sections of a long document. Write a cohesive 3-5 sentence summary of the entire document.",
messages=[{"role": "user", "content": combined}]
)
return response.content[0].text
# pip install requests beautifulsoup4 anthropic
import requests
from bs4 import BeautifulSoup
def summarize_url(url: str) -> str:
html = requests.get(url, timeout=10).text
soup = BeautifulSoup(html, "html.parser")
# Extract main text, skip nav/footer
for tag in soup(["script", "style", "nav", "footer", "header"]):
tag.decompose()
text = " ".join(soup.get_text(separator=" ").split())[:15000] # 15K char safety cap
return summarize(text)
print(summarize_url("https://en.wikipedia.org/wiki/Anthropic"))
def batch_summarize(texts: list[str]) -> list[str]:
"""Summarize many documents at 50% cost via the Batch API."""
requests_list = [
{
"custom_id": f"summary_{i}",
"params": {
"model": "claude-haiku-4-5-20251001",
"max_tokens": 256,
"system": "Summarize in 2 sentences.",
"messages": [{"role": "user", "content": t}]
}
}
for i, t in enumerate(texts)
]
batch = client.beta.messages.batches.create(requests=requests_list)
print(f"Batch ID: {batch.id} — poll until processing_status == 'ended'")
return batch.id # poll batch.id later, or use the Batch API webhook
| Model | Cost per 1K tokens (in/out) | Context | Best for |
|---|---|---|---|
| claude-haiku-4-5-20251001 | $0.00025 / $0.00125 | 200K | High-volume bulk summarization |
| claude-sonnet-4-6 | $0.003 / $0.015 | 200K | Nuanced documents, structured output |
| claude-opus-4-7 | $0.015 / $0.075 | 200K | Complex research papers, board reports |
Use the Claude API Cost Calculator to estimate the cost of your summarization pipeline before scaling. For document Q&A (not just summarization), see the RAG with Claude guide. For PDF-specific summarization, see Claude PDF Analysis.