Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Anthropics Anthropic sdk python JSON Output Format

From Leeroopedia
Knowledge Sources
Domains Structured_Output, LLM, Data_Extraction
Last Updated 2026-02-15 00:00 GMT

Overview

The JSON Output Format implementation provides the data structures and schema transformation logic that enable type-safe structured output in the Anthropic Python SDK. It consists of two core components: the JSONOutputFormatParam TypedDict that represents the API's output format parameter, and the transform_schema() function that normalizes Pydantic-generated JSON Schemas into an API-compatible form.

API Surface

JSONOutputFormatParam

from anthropic.types import JSONOutputFormatParam

Source: src/anthropic/types/json_output_format_param.py:L11-16

class JSONOutputFormatParam(TypedDict, total=False):
    schema: Required[Dict[str, object]]
    """The JSON schema of the format"""

    type: Required[Literal["json_schema"]]

A TypedDict with two required fields:

  • schema (Dict[str, object]): The JSON Schema dictionary that defines the expected output structure.
  • type (Literal["json_schema"]): The discriminator literal, always set to "json_schema".

transform_schema

from anthropic.lib._parse._transform import transform_schema

Source: src/anthropic/lib/_parse/_transform.py:L54-167

def transform_schema(
    json_schema: type[pydantic.BaseModel] | dict[str, Any],
) -> dict[str, Any]:

Accepts either a Pydantic BaseModel subclass (which is converted to a JSON Schema dict via model_json_schema()) or a raw JSON Schema dictionary. Returns a normalized schema dictionary suitable for the Anthropic API.

Detailed Behavior

Schema Input Handling

When passed a Pydantic BaseModel subclass, transform_schema() first calls json_schema.model_json_schema() to produce the raw JSON Schema dict. When passed a dict directly, it operates on that dict.

if inspect.isclass(json_schema) and issubclass(json_schema, pydantic.BaseModel):
    json_schema = json_schema.model_json_schema()

Recursive Normalization

The function processes the schema recursively, handling each JSON Schema construct:

$ref pointers: Preserved as-is and returned immediately.

ref = json_schema.pop("$ref", None)
if ref is not None:
    strict_schema["$ref"] = ref
    return strict_schema

$defs blocks: Each definition is recursively transformed.

defs = json_schema.pop("$defs", None)
if defs is not None:
    strict_defs: dict[str, Any] = {}
    strict_schema["$defs"] = strict_defs
    for name, schema in defs.items():
        strict_defs[name] = transform_schema(schema)

Union types: anyOf, oneOf, and allOf are handled. Notably, oneOf is converted to anyOf:

if is_list(any_of):
    strict_schema["anyOf"] = [transform_schema(variant) for variant in any_of]
elif is_list(one_of):
    strict_schema["anyOf"] = [transform_schema(variant) for variant in one_of]
elif is_list(all_of):
    strict_schema["allOf"] = [transform_schema(variant) for variant in all_of]

Object Type Handling

For object types, properties are recursively transformed, additionalProperties is forcibly set to false, and required is preserved:

if type_ == "object":
    strict_schema["properties"] = {
        key: transform_schema(prop_schema)
        for key, prop_schema in json_schema.pop("properties", {}).items()
    }
    json_schema.pop("additionalProperties", None)
    strict_schema["additionalProperties"] = False

    required = json_schema.pop("required", None)
    if required is not None:
        strict_schema["required"] = required

String Format Handling

Supported string formats (date-time, email, uri, uuid, hostname, ipv4, ipv6, date, time, duration) are preserved. Unsupported formats are moved to the description as extra properties:

SupportedStringFormats = {
    "date-time", "time", "date", "duration", "email",
    "hostname", "uri", "ipv4", "ipv6", "uuid",
}

Unsupported Property Fallback

Any remaining properties not explicitly handled are appended to the description field as a formatted string, preserving developer intent for the model to follow:

if json_schema:
    description = strict_schema.get("description")
    strict_schema["description"] = (
        (description + "\n\n" if description is not None else "")
        + "{"
        + ", ".join(f"{key}: {value}" for key, value in json_schema.items())
        + "}"
    )

Usage Example

from pydantic import BaseModel
from anthropic.lib._parse._transform import transform_schema
from anthropic.types import JSONOutputFormatParam

class MovieReview(BaseModel):
    title: str
    rating: float
    summary: str
    pros: list[str]
    cons: list[str]

# Generate and transform the schema
schema = transform_schema(MovieReview)

# Wrap in the API parameter format
output_format = JSONOutputFormatParam(schema=schema, type="json_schema")

Dependencies

  • pydantic (BaseModel, TypeAdapter, model_json_schema): For schema generation from Python types.
  • typing_extensions (Literal, Required, TypedDict): For the JSONOutputFormatParam type definition.

Key Source Files

  • src/anthropic/types/json_output_format_param.py -- JSONOutputFormatParam TypedDict definition.
  • src/anthropic/lib/_parse/_transform.py -- transform_schema() and get_transformed_string() functions, SupportedTypes, SupportedStringFormats.

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment