Skip to content

Anthropic Python SDK ​

The official anthropic package, on plugboard's Messages API.

Connect ​

Use the base URL without /v1. The SDK adds /v1/messages itself.

py
client = Anthropic(base_url=os.environ["PLUGBOARD_BASE_URL"].removesuffix("/v1"), api_key=os.environ["PLUGBOARD_KEY"], max_retries=0)

Chat ​

py
message = client.messages.create(model=model, max_tokens=1024, messages=[{"role": "user", "content": "Reply with exactly: pong"}])

Tool calls ​

The answer has a tool_use block. Your code runs the tool and sends a tool_result back.

py
first = client.messages.create(model=model, max_tokens=1024, tools=TOOLS, messages=messages)
call = next(block for block in first.content if block.type == "tool_use")
second = client.messages.create(
    model=model,
    max_tokens=1024,
    tools=TOOLS,
    messages=[
        *messages,
        {"role": "assistant", "content": first.content},
        {"role": "user", "content": [{"type": "tool_result", "tool_use_id": call.id, "content": json.dumps(WEATHER)}]},
    ],
)

Streaming ​

py
text = ""
with client.messages.stream(model=model, max_tokens=1024, messages=[{"role": "user", "content": PROMPT}]) as stream:
    for piece in stream.text_stream:
        text += piece
    message = stream.get_final_message()

Structured output ​

Pass output_config={"format": {"type": "json_schema", "schema": ...}}; the answer is one text block holding the JSON. See Structured outputs. A forced tool also works: a tool whose input_schema is the schema, with tool_choice set to that tool, and the call's input is the answer.

py
message = client.messages.create(
    model=model,
    max_tokens=1024,
    tools=[
        {
            "name": "record_meal",
            "description": "Record the estimated nutrition for a meal",
            "input_schema": {
                "type": "object",
                "properties": {"calories": {"type": "number"}, "protein_g": {"type": "number"}},
                "required": KEYS,
                "additionalProperties": False,
            },
        }
    ],
    tool_choice={"type": "tool", "name": "record_meal"},
    messages=[{"role": "user", "content": PROMPT}],
)

Files ​

client.beta.files.upload(file=...) returns an id you can use in an image or document block with source: {"type": "file", "file_id": ...}. See Files.

Limits ​

  • Errors carry error.type (authentication_error, not_found_error) and no error.code.
  • The schema in structured output is not enforced by the provider. Validate the answer.