Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d202327
chore(internal): clean up code comments (#578)
claude[bot] Sep 1, 2026
6673bdb
codegen metadata
stainless-app[bot] Sep 2, 2026
d1d2c01
feat(api): add support for sending a workspace ID on more endpoints
stainless-app[bot] Sep 2, 2026
aa90b81
codegen metadata
stainless-app[bot] Sep 2, 2026
85454ca
fix: repair custom-code merge in messages resources (#580)
dtmeadows-ant Sep 2, 2026
daca8f1
chore(internal): narrower codeowners scope
stainless-app[bot] Sep 2, 2026
26c509d
docs(api): update a few doc strings
stainless-app[bot] Sep 2, 2026
41aa767
chore(internal): revert codeowners change
stainless-app[bot] Sep 2, 2026
9447099
fix(client): raise a clear error when an httpx object is passed inste…
stainless-app[bot] Sep 3, 2026
f9b0cf2
chore(internal): bundle the mock server spec and update dev tooling
anthropic-sdks-writer[bot] Sep 3, 2026
ea8a347
Build SDK
anthropic-sdks-writer[bot] Sep 3, 2026
9fce1e4
feat(api): add Claude Tag category and user breakdowns to usage reports
anthropic-sdks-writer[bot] Sep 3, 2026
ba9bf35
chore(tests): remove stale warning filters
claude[bot] Sep 3, 2026
07834f6
chore(internal): fix mypy unreachable error in detect-breaking-change…
anthropic-sdks-writer[bot] Sep 3, 2026
182abb5
chore(examples): refresh platform model IDs (#499)
claude[bot] Sep 4, 2026
6b5046a
chore(tests): reword the skip reason on the path-level query param tests
anthropic-sdks-writer[bot] Sep 4, 2026
1de1957
feat(api): add named types for organization compliance settings state
anthropic-sdks-writer[bot] Sep 4, 2026
3be44ac
release: 1.4.0
stainless-app[bot] Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,17 @@ jobs:
- name: Run tests
run: ./scripts/test

detect_breaking_changes_vs_main:
detect_breaking_changes:
timeout-minutes: 10
name: detect-breaking-changes-vs-main
name: detect-breaking-changes
runs-on: 'ubuntu-latest'
if: |-
(github.event_name == 'push' &&
!startsWith(github.ref, 'refs/heads/release-please--')) ||
github.event.pull_request.head.repo.fork
steps:
# fetch-depth: 0 fetches full commit history (all branches, so
# origin/main is available) so `git merge-base HEAD origin/main`
# fetch-depth: 0 fetches full commit history (all branches and
# tags, so the base ref is available) so `git merge-base`
# below can resolve the fork point. filter: blob:none keeps the
# fetch cheap: commit metadata is downloaded eagerly, file blobs
# only when a later `git checkout` asks for them.
Expand All @@ -127,15 +127,28 @@ jobs:

- name: Determine base SHA
run: |
BASE_SHA=$(git merge-base HEAD origin/main 2>/dev/null || echo "")
echo "BASE_SHA=$BASE_SHA" >> $GITHUB_ENV
# A breaking-change-baseline tag, when the repo keeps one, marks the API
# surface to compare against; it is moved by force, so refetch it.
git fetch --quiet --force origin '+refs/tags/breaking-change-baseline:refs/tags/breaking-change-baseline' 2>/dev/null || true
if git rev-parse --quiet --verify 'refs/tags/breaking-change-baseline^{commit}' >/dev/null; then
BASE_REF='refs/tags/breaking-change-baseline'
elif git rev-parse --quiet --verify 'origin/main^{commit}' >/dev/null; then
BASE_REF='origin/main'
else
echo 'No breaking-change-baseline tag or origin/main to compare against; skipping.'
echo "BASE_SHA=" >> "$GITHUB_ENV"
exit 0
fi
echo "Comparing against $BASE_REF"
BASE_SHA=$(git merge-base HEAD "$BASE_REF" 2>/dev/null || echo "")
echo "BASE_SHA=$BASE_SHA" >> "$GITHUB_ENV"

- name: Detect removed symbols
if: env.BASE_SHA != ''
run: |
uv run python scripts/detect-breaking-changes.py "$BASE_SHA"

- name: Detect breaking changes vs. main
- name: Detect breaking changes
if: env.BASE_SHA != ''
run: |
# Try to check out previous versions of the breaking change detection script. This ensures that
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.3.0"
".": "1.4.0"
}
3 changes: 0 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
configured_endpoints: 201
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic/anthropic-e50cf35b74cc0471a2b5af7ea03765aa81c035f82588e9a1ba1b29aeaa17d064.yml
openapi_spec_hash: e4ae88bdd84c7e293dd46037a6769b8d
config_hash: e7cae7a85b1d1ebf25c2bfdff6b8fc4c
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# Changelog

## 1.4.0 (2026-09-04)

Full Changelog: [v1.3.0...v1.4.0](https://github.com/anthropics/anthropic-sdk-python/compare/v1.3.0...v1.4.0)

### Features

* **api:** add Claude Tag category and user breakdowns to usage reports ([9fce1e4](https://github.com/anthropics/anthropic-sdk-python/commit/9fce1e4994e113c35f4a7116d0c5eb90367b9c66))
* **api:** add named types for organization compliance settings state ([1de1957](https://github.com/anthropics/anthropic-sdk-python/commit/1de1957334e7491979ddb21a1d673fa4e56d5459))
* **api:** add support for sending a workspace ID on more endpoints ([d1d2c01](https://github.com/anthropics/anthropic-sdk-python/commit/d1d2c01d8aa128080dea3d711e12cb3df95a2149))


### Bug Fixes

* **client:** raise a clear error when an httpx object is passed instead of an httpx2 one ([9447099](https://github.com/anthropics/anthropic-sdk-python/commit/94470992f0f00ed331f2faa585cfda2cb8412a08))
* repair custom-code merge in messages resources ([#580](https://github.com/anthropics/anthropic-sdk-python/issues/580)) ([85454ca](https://github.com/anthropics/anthropic-sdk-python/commit/85454cab9a323801b76500707b84c1992c1c0ee4))


### Chores

* **examples:** refresh platform model IDs ([#499](https://github.com/anthropics/anthropic-sdk-python/issues/499)) ([182abb5](https://github.com/anthropics/anthropic-sdk-python/commit/182abb51cdb5dda815b0b2498dc4adaab6dde469))
* **internal:** bundle the mock server spec and update dev tooling ([f9b0cf2](https://github.com/anthropics/anthropic-sdk-python/commit/f9b0cf281932512e6b40cd1a887a44542c883468))
* **internal:** clean up code comments ([#578](https://github.com/anthropics/anthropic-sdk-python/issues/578)) ([d202327](https://github.com/anthropics/anthropic-sdk-python/commit/d2023274f69dd0609ddabbf8f6af08041f868d8b))
* **internal:** fix mypy unreachable error in detect-breaking-changes script ([07834f6](https://github.com/anthropics/anthropic-sdk-python/commit/07834f601fb4a81958f15e2129ca091cb9d1c646))
* **internal:** narrower codeowners scope ([daca8f1](https://github.com/anthropics/anthropic-sdk-python/commit/daca8f13032311676ed30a6e0527ee304e1419c9))
* **internal:** revert codeowners change ([41aa767](https://github.com/anthropics/anthropic-sdk-python/commit/41aa767464881bb51937f42fe9c426ae3081fd9f))
* **tests:** remove stale warning filters ([ba9bf35](https://github.com/anthropics/anthropic-sdk-python/commit/ba9bf356ed60fa2eb206e266c86c0202dd005616))
* **tests:** reword the skip reason on the path-level query param tests ([6b5046a](https://github.com/anthropics/anthropic-sdk-python/commit/6b5046ad29999ec887226aecff67db9feb2d1972))


### Documentation

* **api:** update a few doc strings ([26c509d](https://github.com/anthropics/anthropic-sdk-python/commit/26c509d66192f2b40150b481fa89da97e532612c))

## 1.3.0 (2026-09-01)

Full Changelog: [v1.2.0...v1.3.0](https://github.com/anthropics/anthropic-sdk-python/compare/v1.2.0...v1.3.0)
Expand Down
2 changes: 2 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1770,10 +1770,12 @@ Types:
```python
from anthropic.types.beta.organization import (
BetaComplianceSettings,
BetaComplianceSettingsState,
BetaComplianceSettingsStateDisabled,
BetaComplianceSettingsStateDisabledParam,
BetaComplianceSettingsStateEnabled,
BetaComplianceSettingsStateEnabledParam,
BetaComplianceSettingsStateParam,
)
```

Expand Down
2 changes: 1 addition & 1 deletion examples/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
)

response = cl.messages.create(
model="claude-haiku-4-5",
model="claude-sonnet-5",
messages=[
{"role": "user", "content": "Hello!"},
],
Expand Down
4 changes: 2 additions & 2 deletions examples/bedrock.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"content": "Hello!",
}
],
model="anthropic.claude-sonnet-4-5-20250929-v1:0",
model="global.anthropic.claude-sonnet-5",
)
print(message.model_dump_json(indent=2))

Expand All @@ -33,7 +33,7 @@
"content": "Say hello there!",
}
],
model="anthropic.claude-sonnet-4-5-20250929-v1:0",
model="global.anthropic.claude-sonnet-5",
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Expand Down
12 changes: 0 additions & 12 deletions examples/memory/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ def conversation_loop():

messages: list[BetaMessageParam] = []

# Initialize tracking for debug
last_response_id: Optional[str] = None
last_usage = None

Expand All @@ -85,7 +84,6 @@ def conversation_loop():
print(" /memory_clear - Delete all memory")
print(" /debug - View conversation history and token usage")

# Display context management settings
print(f"\n🧹 Context Management")
print("=" * 60)

Expand Down Expand Up @@ -115,11 +113,9 @@ def conversation_loop():
elif user_input.lower() == "/debug":
print("\n🔍 Conversation history:")

# Show last response ID if available
if last_response_id:
print(f"📌 Last response ID: {last_response_id}")

# Show token usage if available
if last_usage:
usage = last_usage
input_tokens = usage.get("input_tokens", 0)
Expand Down Expand Up @@ -170,7 +166,6 @@ def conversation_loop():
spinner = Spinner("Thinking")
spinner.start()

# Use tool_runner with memory tool
try:
runner = client.beta.messages.tool_runner(
betas=["context-management-2025-06-27"],
Expand All @@ -185,22 +180,18 @@ def conversation_loop():
spinner.stop()
raise

# Process all messages from the runner
for message in runner:
spinner.stop()

# Store response ID and usage for debug display
last_response_id = message.id

if hasattr(message, "usage") and message.usage:
last_usage = message.usage.model_dump() if hasattr(message.usage, "model_dump") else dict(message.usage)

# Check for context management actions
if message.context_management:
for edit in message.context_management.applied_edits:
print(f"\n🧹 [Context Management: {edit.type} applied]")

# Process content blocks
assistant_content: list[BetaContentBlockParam] = []
for content in message.content:
if content.type == "text":
Expand All @@ -222,14 +213,11 @@ def conversation_loop():
}
)

# Store assistant message
if assistant_content:
messages.append({"role": "assistant", "content": assistant_content})

# Generate tool response automatically
tool_response = runner.generate_tool_call_response()
if tool_response and tool_response["content"]:
# Add tool results to messages
messages.append({"role": "user", "content": tool_response["content"]})

for result in tool_response["content"]:
Expand Down
1 change: 0 additions & 1 deletion examples/structured_outputs_streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,5 @@ class Order(pydantic.BaseModel):
if event.type == "text":
print(event.parsed_snapshot())

# Get the final parsed output
final_message = stream.get_final_message()
print(f"\nFinal parsed order: {final_message.parsed_output}")
9 changes: 7 additions & 2 deletions examples/vertex.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#!/usr/bin/env -S uv run python

# Note: you must have installed `anthropic` with the `vertex` extra
# e.g. `pip install -U anthropic[vertex]`

import asyncio

from anthropic import AnthropicVertex, AsyncAnthropicVertex
Expand All @@ -9,7 +14,7 @@ def sync_client() -> None:
client = AnthropicVertex()

message = client.messages.create(
model="claude-sonnet-4@20250514",
model="claude-sonnet-5",
max_tokens=100,
messages=[
{
Expand All @@ -27,7 +32,7 @@ async def async_client() -> None:
client = AsyncAnthropicVertex()

message = await client.messages.create(
model="claude-sonnet-4@20250514",
model="claude-sonnet-5",
max_tokens=1024,
messages=[
{
Expand Down
3 changes: 0 additions & 3 deletions examples/web_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@
],
)

# Print the full response
print("\nFull response:")
print(message.model_dump_json(indent=2))

# Extract and print the content
print("\nResponse content:")
for content_block in message.content:
if content_block.type == "text":
print(content_block.text)

# Print usage information
print("\nUsage statistics:")
print(f"Input tokens: {message.usage.input_tokens}")
print(f"Output tokens: {message.usage.output_tokens}")
Expand Down
4 changes: 0 additions & 4 deletions examples/web_search_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ async def main() -> None:
}
],
) as stream:
# Process streaming events
async for chunk in stream:
# Print text deltas as they arrive
if chunk.type == "content_block_delta" and chunk.delta.type == "text_delta":
print(chunk.delta.text, end="", flush=True)

Expand All @@ -34,7 +32,6 @@ async def main() -> None:
elif chunk.type == "content_block_stop" and chunk.content_block.type == "web_search_tool_result":
print("[Web search completed]", end="\n\n", flush=True)

# Get the final complete message
message = await stream.get_final_message()

print("\n\nFinal usage statistics:")
Expand All @@ -52,7 +49,6 @@ async def main() -> None:
for i, block in enumerate(message.content):
print(f"Content Block {i + 1}: Type = {block.type}")

# Show the entire message structure as JSON for debugging
print("\nComplete message structure (JSON):")
print(message.model_dump_json(indent=2))

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "anthropic"
version = "1.3.0"
version = "1.4.0"
description = "The official Python library for the anthropic API"
dynamic = ["readme"]
license = "MIT"
Expand Down Expand Up @@ -82,6 +82,7 @@ dev = [
"boto3-stubs >= 1",
"rich>=13.7.1",
"pytest-xdist>=3.6.1",
"hypothesis",
"inline-snapshot>=0.28.0",
"griffe>=1",
"http-snapshot[httpx]==0.1.9",
Expand Down
4 changes: 4 additions & 0 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ docstring-parser==0.17.0
exceptiongroup==1.3.1 ; python_full_version < '3.11'
# via
# anyio
# hypothesis
# pytest
execnet==2.1.2
# via pytest-xdist
Expand Down Expand Up @@ -56,6 +57,7 @@ httpx==0.28.1
# respx
httpx2==2.9.1
# via anthropic
hypothesis==6.165.10
idna==3.18
# via
# anyio
Expand Down Expand Up @@ -105,6 +107,8 @@ rich==14.3.3
ruff==0.15.6
sniffio==1.3.1
# via anthropic
sortedcontainers==2.4.0
# via hypothesis
time-machine==3.2.0
tomli==2.4.0 ; python_full_version < '3.11'
# via
Expand Down
2 changes: 1 addition & 1 deletion scripts/lint
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ echo "==> Checking dependency version caps"
uv run python scripts/utils/check-dependency-caps.py

echo "==> Running pyright"
uv run pyright
uv run pyright --project .

echo "==> Running mypy"
uv run mypy .
Expand Down
15 changes: 8 additions & 7 deletions scripts/mock
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ cd "$(dirname "$0")/.."
if [[ -n "$1" && "$1" != '--'* ]]; then
URL="$1"
shift
elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then
URL="$STAINLESS_OPENAPI_SPEC_URL"
else
URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)"
fi

# Check if the URL is empty
if [ -z "$URL" ]; then
echo "Error: No OpenAPI spec path/url provided or found in .stats.yml"
exit 1
# The generator writes the gzip'd spec next to this script; the
# cd at the top of scripts/mock puts CWD at the SDK root.
SPEC_TMPFILE="$(mktemp)"
trap 'rm -f "$SPEC_TMPFILE"' EXIT
gunzip -c scripts/mock-spec.json.gz > "$SPEC_TMPFILE"
URL="$SPEC_TMPFILE"
fi

echo "==> Starting mock server with URL ${URL}"
Expand Down
Binary file added scripts/mock-spec.json.gz
Binary file not shown.
Loading
Loading