Implementation:Anthropics Anthropic sdk python ParsedMessage Output
| Knowledge Sources | |
|---|---|
| Domains | Structured_Output, LLM, Data_Extraction |
| Last Updated | 2026-02-15 00:00 GMT |
Overview
The ParsedMessage Output implementation provides the generic typed container classes that hold validated structured output from the Anthropic API. It consists of ParsedTextBlock, ParsedContentBlock, and ParsedMessage, which extend the standard API response types to carry deserialized Pydantic model instances. The companion parse_text() and parse_response() functions handle the actual JSON validation and container construction.
API Surface
ParsedMessage
from anthropic.types import ParsedMessage
Source: src/anthropic/types/parsed_message.py:L45-56
class ParsedMessage(Message, Generic[ResponseFormatT]):
content: List[ParsedContentBlock[ResponseFormatT]]
@property
def parsed_output(self) -> Optional[ResponseFormatT]:
for content in self.content:
if content.type == "text" and content.parsed_output:
return content.parsed_output
return None
ParsedTextBlock
Source: src/anthropic/types/parsed_message.py:L25-28
class ParsedTextBlock(TextBlock, Generic[ResponseFormatT]):
parsed_output: Optional[ResponseFormatT] = None
__api_exclude__ = {"parsed_output"}
ParsedContentBlock
Source: src/anthropic/types/parsed_message.py:L32-42
ParsedContentBlock: TypeAlias = Annotated[
Union[
ParsedTextBlock[ResponseFormatT],
ThinkingBlock,
RedactedThinkingBlock,
ToolUseBlock,
ServerToolUseBlock,
WebSearchToolResultBlock,
],
PropertyInfo(discriminator="type"),
]
A discriminated union of content block types. The type field is used as the discriminator so that Pydantic can dispatch to the correct block class. Only ParsedTextBlock carries the generic type parameter; other block types are passed through unchanged.
Parsing Functions
parse_text
Source: src/anthropic/lib/_parse/_response.py:L16-20
def parse_text(text: str, output_format: ResponseFormatT | NotGiven) -> ResponseFormatT | None:
if is_given(output_format):
adapted_type: TypeAdapter[ResponseFormatT] = TypeAdapter(output_format)
return adapted_type.validate_json(text)
return None
This function performs the core JSON-to-Pydantic deserialization:
- Checks if
output_formatis actually given (not the sentinelNOT_GIVEN). - Creates a
TypeAdapterfor the target type. - Calls
validate_json(text), which parses the JSON string and validates it against the Pydantic model in a single step. - Returns the validated model instance, or
Noneif no output format was specified.
parse_response
Source: src/anthropic/lib/_parse/_response.py:L49-72
def parse_response(
*,
output_format: ResponseFormatT | NotGiven,
response: Message,
) -> ParsedMessage[ResponseFormatT]:
content_list: list[ParsedContentBlock[ResponseFormatT]] = []
for content in response.content:
if content.type == "text":
content_list.append(
construct_type_unchecked(
type_=ParsedTextBlock[ResponseFormatT],
value={
**content.to_dict(),
"parsed_output": parse_text(content.text, output_format),
},
)
)
else:
content_list.append(content)
return construct_type_unchecked(
type_=ParsedMessage[ResponseFormatT],
value={
**response.to_dict(),
"content": content_list,
},
)
This function transforms a standard Message into a ParsedMessage:
- Iterates through the message's content blocks.
- For each
TextBlock, constructs aParsedTextBlockwith the original data plus the validatedparsed_output. - Non-text blocks (ThinkingBlock, ToolUseBlock, etc.) are passed through unchanged.
- Constructs the final
ParsedMessagewith the rebuilt content list.
Uses construct_type_unchecked() to build instances without re-running validation on the already-validated data, for performance.
Detailed Behavior
parsed_output Property Lookup
The ParsedMessage.parsed_output property performs a linear scan through self.content:
@property
def parsed_output(self) -> Optional[ResponseFormatT]:
for content in self.content:
if content.type == "text" and content.parsed_output:
return content.parsed_output
return None
It returns the parsed_output from the first text block that has a truthy value. This handles the common case where there is a single text content block. If no text block has a parsed output (e.g., the model only produced tool use blocks, or the JSON was invalid), it returns None.
__api_exclude__ on ParsedTextBlock
The __api_exclude__ = {"parsed_output"} class variable ensures that the parsed_output field is excluded from serialization when the block is converted back to a dict for API communication. This prevents the SDK's internal augmentation from leaking into wire-format data.
TYPE_CHECKING Guard on Content
The content field on ParsedMessage uses a TYPE_CHECKING guard:
class ParsedMessage(Message, Generic[ResponseFormatT]):
if TYPE_CHECKING:
content: List[ParsedContentBlock[ResponseFormatT]]
else:
content: List[ParsedContentBlock]
At runtime, Pydantic sees the non-generic ParsedContentBlock (since generic unions are not fully supported by Pydantic at runtime). At type-check time, IDEs and type checkers see the fully parameterized ParsedContentBlock[ResponseFormatT], providing correct type inference for parsed_output.
Usage Example
import anthropic
from pydantic import BaseModel
class MovieReview(BaseModel):
title: str
rating: float
summary: str
pros: list[str]
cons: list[str]
client = anthropic.Anthropic()
message = client.messages.parse(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Review the movie Inception"}],
output_format=MovieReview,
)
# Type-safe access to the parsed output
review = message.parsed_output # Optional[MovieReview]
if review is not None:
print(f"{review.title}: {review.rating}/10")
print(f"Summary: {review.summary}")
for pro in review.pros:
print(f" + {pro}")
for con in review.cons:
print(f" - {con}")
# Raw text is still accessible
for block in message.content:
if block.type == "text":
print(f"Raw JSON: {block.text}")
Dependencies
- pydantic (
BaseModel,TypeAdapter,validate_json): For JSON deserialization and validation. - typing_extensions (
TypeVar,Generic,Annotated): For generic type parameterization. - anthropic._models (
construct_type_unchecked): For constructing Pydantic models without re-validation. - anthropic._utils (
PropertyInfo): For discriminated union support.
Key Source Files
src/anthropic/types/parsed_message.py--ParsedTextBlock(L25-28),ParsedContentBlock(L32-42),ParsedMessage(L45-56).src/anthropic/lib/_parse/_response.py--parse_text()(L16-20),parse_response()(L49-72).