mirror of
https://github.com/anthropics/skills.git
synced 2026-08-02 13:05:28 +08:00
Update claude-api skill: auth, cloud providers, Managed Agents fixes, token counting (#1276)
* Sync claude-api skill with latest upstream updates - Add token-counting.md and SKILL.md trigger description update - Add auth guidance: env credential resolution, ant auth login, OAuth/WIF doc links, 401 causes - Add mid-conversation system messages (beta) to prompt-caching, agent-design, SKILL.md, Python/TS READMEs - Add cache pre-warming (max_tokens: 0) section to prompt-caching - Add Managed Agents pre-flight viability check to onboarding and overview - Add Bedrock model-ID section to model-migration; add Bedrock row to live-sources - Add /claude-api migrate subcommand row and migrate-entry callout - Fix MA networking config: limited type with allow_package_managers/allow_mcp_servers - Bump MA create-operations rate limit to 300 RPM - Fix MA SDK drift: sessions.events.stream(), event.name, typed event arrays - Add SDK coverage: stop_details, error .type, C# tool runner + MA support, Go model constants, Java 2.34.0, client config, response helpers, auto-pagination, advisor tool - Move Sonnet 4 / Opus 4 to deprecated in models.md * Add Anthropic CLI and Claude Platform on AWS docs to claude-api skill - Add shared/anthropic-cli.md: install, auth profiles, OAuth scopes, command structure, version-controlled Managed Agents resources, credential traps - Add shared/claude-platform-on-aws.md: AnthropicAWS clients, SigV4 auth, workspace_id, regions, feature availability - Restore cross-references to both files throughout SKILL.md and the managed-agents docs (previously rewritten to live-sources.md pointers) - Restore Claude Platform on AWS provider taxonomy in SKILL.md, the migration-guide section, and live-sources rows
This commit is contained in:
@@ -11,10 +11,12 @@ pip install anthropic
|
||||
```python
|
||||
import anthropic
|
||||
|
||||
# Default (uses ANTHROPIC_API_KEY env var)
|
||||
# Default — resolves credentials from the environment:
|
||||
# ANTHROPIC_API_KEY, or ANTHROPIC_AUTH_TOKEN, or an `ant auth login` profile.
|
||||
# Prefer this for local dev; don't hardcode a key.
|
||||
client = anthropic.Anthropic()
|
||||
|
||||
# Explicit API key
|
||||
# Explicit API key (only when you must inject a specific key)
|
||||
client = anthropic.Anthropic(api_key="your-api-key")
|
||||
|
||||
# Async client
|
||||
@@ -23,6 +25,67 @@ async_client = anthropic.AsyncAnthropic()
|
||||
|
||||
---
|
||||
|
||||
## Client Configuration
|
||||
|
||||
### Per-request overrides
|
||||
|
||||
Use `with_options()` to override client settings for a single call without mutating the client:
|
||||
|
||||
```python
|
||||
client.with_options(timeout=5.0, max_retries=5).messages.create(
|
||||
model="claude-opus-4-8",
|
||||
max_tokens=1024,
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
)
|
||||
```
|
||||
|
||||
### Timeouts
|
||||
|
||||
Default request timeout is 10 minutes. Pass a float (seconds) or an `httpx.Timeout` for granular control. On timeout the SDK raises `anthropic.APITimeoutError` (and retries per `max_retries`).
|
||||
|
||||
```python
|
||||
import httpx
|
||||
|
||||
client = anthropic.Anthropic(timeout=20.0)
|
||||
client = anthropic.Anthropic(
|
||||
timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
|
||||
)
|
||||
```
|
||||
|
||||
### Retries
|
||||
|
||||
The SDK auto-retries connection errors, 408, 409, 429, and ≥500 with exponential backoff (default 2 retries). Set `max_retries` on the client or via `with_options()`; `max_retries=0` disables.
|
||||
|
||||
### Async performance (aiohttp backend)
|
||||
|
||||
For high-concurrency async workloads, install `anthropic[aiohttp]` and pass `DefaultAioHttpClient` instead of the default httpx backend:
|
||||
|
||||
```python
|
||||
from anthropic import AsyncAnthropic, DefaultAioHttpClient
|
||||
|
||||
async with AsyncAnthropic(http_client=DefaultAioHttpClient()) as client:
|
||||
...
|
||||
```
|
||||
|
||||
### Custom HTTP client (proxy, base URL)
|
||||
|
||||
Use `DefaultHttpxClient` / `DefaultAsyncHttpxClient` — not raw `httpx.Client` — so the SDK's default timeouts and connection limits are preserved:
|
||||
|
||||
```python
|
||||
from anthropic import Anthropic, DefaultHttpxClient
|
||||
|
||||
client = Anthropic(
|
||||
base_url="http://my.test.server.example.com:8083", # or ANTHROPIC_BASE_URL env var
|
||||
http_client=DefaultHttpxClient(proxy="http://my.test.proxy.example.com"),
|
||||
)
|
||||
```
|
||||
|
||||
### Logging
|
||||
|
||||
Set `ANTHROPIC_LOG=debug` (or `info`) to enable SDK logging via the standard `logging` module.
|
||||
|
||||
---
|
||||
|
||||
## Basic Message Request
|
||||
|
||||
```python
|
||||
@@ -53,6 +116,23 @@ response = client.messages.create(
|
||||
)
|
||||
```
|
||||
|
||||
### Mid-conversation system messages (beta, model-gated)
|
||||
|
||||
For operator instructions that arrive mid-conversation (mode switches, injected state), append `{"role": "system", ...}` to `messages` instead of editing top-level `system` — this preserves the cached prefix and carries operator authority. Must follow a user message; cannot be `messages[0]`. Unsupported models return a 400 (`role 'system' is not supported on this model`). See `shared/prompt-caching.md` for when to use this vs. top-level `system`.
|
||||
|
||||
```python
|
||||
response = client.messages.create(
|
||||
model=MODEL_ID, # must support mid-conversation system messages
|
||||
max_tokens=16000,
|
||||
system=[{"type": "text", "text": STABLE_SYSTEM, "cache_control": {"type": "ephemeral"}}],
|
||||
messages=history + [
|
||||
{"role": "user", "content": user_message},
|
||||
{"role": "system", "content": "Terse mode enabled — keep responses under 40 words."},
|
||||
],
|
||||
extra_headers={"anthropic-beta": "mid-conversation-system-2026-04-07"},
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vision (Images)
|
||||
@@ -222,6 +302,31 @@ except anthropic.APIConnectionError:
|
||||
|
||||
---
|
||||
|
||||
## Response Helpers
|
||||
|
||||
Every response object exposes `_request_id` (populated from the `request-id` header) — log it when reporting failures to Anthropic. Despite the underscore prefix, this property is public.
|
||||
|
||||
```python
|
||||
message = client.messages.create(...)
|
||||
print(message._request_id) # req_018EeWyXxfu5pfWkrYcMdjWG
|
||||
print(message.to_json()) # serialize the Pydantic model
|
||||
print(message.to_dict()) # plain dict
|
||||
```
|
||||
|
||||
To access raw headers or other response metadata, use `.with_raw_response`:
|
||||
|
||||
```python
|
||||
raw = client.messages.with_raw_response.create(
|
||||
model="claude-opus-4-8",
|
||||
max_tokens=1024,
|
||||
messages=[{"role": "user", "content": "Hello"}],
|
||||
)
|
||||
print(raw.headers.get("request-id"))
|
||||
message = raw.parse() # the Message object messages.create() would have returned
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Multi-Turn Conversations
|
||||
|
||||
The API is stateless — send the full conversation history each time.
|
||||
@@ -268,8 +373,9 @@ response2 = conversation.send("What's my name?") # Claude remembers "Alice"
|
||||
|
||||
**Rules:**
|
||||
|
||||
- Messages must alternate between `user` and `assistant`
|
||||
- Consecutive same-role messages are allowed — the API combines them into a single turn
|
||||
- First message must be `user`
|
||||
- `role: "system"` messages are allowed mid-conversation under the `mid-conversation-system-2026-04-07` beta on supporting models — see § Mid-conversation system messages above
|
||||
|
||||
---
|
||||
|
||||
@@ -320,7 +426,17 @@ The `stop_reason` field in the response indicates why the model stopped generati
|
||||
| `stop_sequence` | Hit a custom stop sequence |
|
||||
| `tool_use` | Claude wants to call a tool — execute it and continue |
|
||||
| `pause_turn` | Model paused and can be resumed (agentic flows) |
|
||||
| `refusal` | Claude refused for safety reasons — output may not match your schema |
|
||||
| `refusal` | Claude refused for safety reasons — check `stop_details` |
|
||||
|
||||
### Structured Stop Details
|
||||
|
||||
When `stop_reason` is `"refusal"`, the response includes a `stop_details` object with structured information about the refusal:
|
||||
|
||||
```python
|
||||
if response.stop_reason == "refusal" and response.stop_details:
|
||||
print(f"Category: {response.stop_details.category}") # "cyber" | "bio" | None
|
||||
print(f"Explanation: {response.stop_details.explanation}")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -100,6 +100,19 @@ print(f"Status: {cancelled.processing_status}") # "canceling"
|
||||
|
||||
---
|
||||
|
||||
## List Batches (auto-pagination)
|
||||
|
||||
Iterating the return value of any `list()` call auto-paginates across all pages — do not index into `.data` if you want the full set:
|
||||
|
||||
```python
|
||||
for batch in client.messages.batches.list(limit=20):
|
||||
print(batch.id, batch.processing_status)
|
||||
```
|
||||
|
||||
For manual control, use `first_page.has_next_page()` / `first_page.get_next_page()` / `first_page.next_page_info()`; `first_page.data` holds the current page's items and `first_page.last_id` is the cursor.
|
||||
|
||||
---
|
||||
|
||||
## Batch with Prompt Caching
|
||||
|
||||
```python
|
||||
|
||||
@@ -16,14 +16,18 @@ The Files API uploads files for use in Messages API requests. Reference files vi
|
||||
|
||||
## Upload a File
|
||||
|
||||
The `file` argument accepts a `(filename, content, content_type)` tuple, a `pathlib.Path` (or any `PathLike` — read for you, async-safe with `AsyncAnthropic`), or an open binary file object.
|
||||
|
||||
```python
|
||||
import anthropic
|
||||
from pathlib import Path
|
||||
|
||||
client = anthropic.Anthropic()
|
||||
|
||||
uploaded = client.beta.files.upload(
|
||||
file=("report.pdf", open("report.pdf", "rb"), "application/pdf"),
|
||||
)
|
||||
# or: client.beta.files.upload(file=Path("report.pdf"))
|
||||
print(f"File ID: {uploaded.id}")
|
||||
print(f"Size: {uploaded.size_bytes} bytes")
|
||||
```
|
||||
@@ -87,9 +91,10 @@ response = client.beta.messages.create(
|
||||
|
||||
### List Files
|
||||
|
||||
Iterate the list result directly — the SDK auto-paginates across all pages. Only use `.data` if you want the first page only.
|
||||
|
||||
```python
|
||||
files = client.beta.files.list()
|
||||
for f in files.data:
|
||||
for f in client.beta.files.list():
|
||||
print(f"{f.id}: {f.filename} ({f.size_bytes} bytes)")
|
||||
```
|
||||
|
||||
|
||||
@@ -24,6 +24,22 @@ async with async_client.messages.stream(
|
||||
print(text, end="", flush=True)
|
||||
```
|
||||
|
||||
### Low-level: `stream=True`
|
||||
|
||||
`messages.stream()` (above) is the recommended helper — it accumulates state and exposes `text_stream` / `get_final_message()`. If you only need the raw event iterator and want lower memory use, pass `stream=True` to `messages.create()` instead:
|
||||
|
||||
```python
|
||||
for event in client.messages.create(
|
||||
model="claude-opus-4-8",
|
||||
max_tokens=64000,
|
||||
messages=[{"role": "user", "content": "Write a story"}],
|
||||
stream=True,
|
||||
):
|
||||
print(event.type)
|
||||
```
|
||||
|
||||
No final-message accumulation is done for you in this form.
|
||||
|
||||
---
|
||||
|
||||
## Handling Different Content Types
|
||||
@@ -160,3 +176,4 @@ except anthropic.APIStatusError as e:
|
||||
3. **Track token usage** — The `message_delta` event contains usage information
|
||||
4. **Use timeouts** — Set appropriate timeouts for your application
|
||||
5. **Default to streaming** — Use `.get_final_message()` to get the complete response even when streaming, giving you timeout protection without needing to handle individual events
|
||||
6. **Large `max_tokens` without streaming raises `ValueError`** — The SDK refuses non-streaming requests it estimates will exceed ~10 minutes (idle connections drop). Pass `stream=True` / use `messages.stream()`, or explicitly override `timeout`, to suppress the guard.
|
||||
|
||||
@@ -15,10 +15,12 @@ pip install anthropic
|
||||
```python
|
||||
import anthropic
|
||||
|
||||
# Default (uses ANTHROPIC_API_KEY env var)
|
||||
# Default — resolves credentials from the environment:
|
||||
# ANTHROPIC_API_KEY, or ANTHROPIC_AUTH_TOKEN, or an `ant auth login` profile.
|
||||
# Prefer this for local dev; don't hardcode a key.
|
||||
client = anthropic.Anthropic()
|
||||
|
||||
# Explicit API key
|
||||
# Explicit API key (only when you must inject a specific key)
|
||||
client = anthropic.Anthropic(api_key="your-api-key")
|
||||
```
|
||||
|
||||
@@ -129,7 +131,7 @@ client.beta.sessions.events.send(
|
||||
import json
|
||||
|
||||
# Stream-first: open stream, then send while stream is live
|
||||
with client.beta.sessions.stream(
|
||||
with client.beta.sessions.events.stream(
|
||||
session_id=session.id,
|
||||
) as stream:
|
||||
client.beta.sessions.events.send(
|
||||
@@ -140,7 +142,7 @@ with client.beta.sessions.stream(
|
||||
... # process events
|
||||
|
||||
# Standalone stream iteration:
|
||||
with client.beta.sessions.stream(
|
||||
with client.beta.sessions.events.stream(
|
||||
session_id=session.id,
|
||||
) as stream:
|
||||
for event in stream:
|
||||
@@ -150,7 +152,7 @@ with client.beta.sessions.stream(
|
||||
print(block.text, end="", flush=True)
|
||||
elif event.type == "agent.custom_tool_use":
|
||||
# Custom tool invocation — session is now idle
|
||||
print(f"\nCustom tool call: {event.tool_name}")
|
||||
print(f"\nCustom tool call: {event.name}")
|
||||
print(f"Input: {json.dumps(event.input)}")
|
||||
# Send result back (see below)
|
||||
elif event.type == "session.status_idle":
|
||||
@@ -210,7 +212,7 @@ def run_custom_tool(tool_name: str, tool_input: dict) -> str:
|
||||
def run_session(client, session_id: str):
|
||||
"""Stream events and handle custom tool calls."""
|
||||
while True:
|
||||
with client.beta.sessions.stream(
|
||||
with client.beta.sessions.events.stream(
|
||||
session_id=session_id,
|
||||
) as stream:
|
||||
tool_calls = []
|
||||
@@ -232,7 +234,7 @@ def run_session(client, session_id: str):
|
||||
# Process custom tool calls
|
||||
results = []
|
||||
for call in tool_calls:
|
||||
result = run_custom_tool(call.tool_name, call.input)
|
||||
result = run_custom_tool(call.name, call.input)
|
||||
results.append({
|
||||
"type": "user.custom_tool_result",
|
||||
"custom_tool_use_id": call.id,
|
||||
|
||||
Reference in New Issue
Block a user