"""Shared fixtures for Anthropic model tests."""
from __future__ import annotations as _annotations
from collections.abc import Callable
from functools import cache
import pytest
from ...conftest import try_import
from ..test_anthropic import MockAnthropic, completion_message
with try_import() as imports_successful:
from anthropic import AsyncAnthropic
from anthropic.types.beta import BetaMessage, BetaTextBlock, BetaToolUseBlock, BetaUsage
from pydantic import BaseModel
from pydantic_ai.models.anthropic import AnthropicModel
from pydantic_ai.providers.anthropic import AnthropicProvider
AnthropicModelFactory = Callable[..., AnthropicModel]
# Model factory fixture for live API tests
@pytest.fixture
def anthropic_model(anthropic_api_key: str) -> AnthropicModelFactory:
"""Factory to create Anthropic models with custom configuration."""
@cache
def _create_model(
model_name: str,
api_key: str | None = None,
) -> AnthropicModel:
"""Create an AnthropicModel with the specified configuration.
Args:
model_name: Model name like 'claude-sonnet-4-5'
api_key: Optional API key, defaults to the fixture's anthropic_api_key
"""
return AnthropicModel(
model_name,
provider=AnthropicProvider(api_key=api_key or anthropic_api_key),
)
return _create_model
# Mock model fixtures for unit tests
@pytest.fixture
def mock_sonnet_4_5(allow_model_requests: None) -> tuple[AnthropicModel, AsyncAnthropic]:
"""Mock claude-sonnet-4-5 model for unit tests."""
c = completion_message(
[BetaTextBlock(text='{"city": "Mexico City", "country": "Mexico"}', type='text')],
BetaUsage(input_tokens=5, output_tokens=10),
)
mock_client = MockAnthropic.create_mock(c)
model = AnthropicModel('claude-sonnet-4-5', provider=AnthropicProvider(anthropic_client=mock_client))
return model, mock_client
# Schema fixtures
@pytest.fixture
def city_location_schema() -> type[BaseModel]:
"""Standard CityLocation schema for testing."""
class CityLocation(BaseModel):
"""A city and its country."""
city: str
country: str
return CityLocation
# Mock response fixtures
@pytest.fixture
def weather_tool_responses() -> list[BetaMessage]:
"""Standard mock responses for weather tool tests."""
return [
completion_message(
[
BetaToolUseBlock(
id='tool_123',
name='get_weather',
input={'location': 'Paris'},
type='tool_use',
)
],
BetaUsage(input_tokens=5, output_tokens=10),
),
completion_message(
[BetaTextBlock(text='The weather in Paris is sunny.', type='text')],
BetaUsage(input_tokens=3, output_tokens=5),
),
]