Skip to content

Commit 6f991cb

Browse files
KludexWh1isper
andauthored
Add support for AWS Bedrock Converse API (#994)
Co-authored-by: Wh1isper <[email protected]>
1 parent 306abbc commit 6f991cb

28 files changed

+1946
-15
lines changed

docs/api/models/bedrock.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# `pydantic_ai.models.bedrock`
2+
3+
## Setup
4+
5+
For details on how to set up authentication with this model, see [model configuration for Bedrock](../../models.md#bedrock).
6+
7+
::: pydantic_ai.models.bedrock

docs/api/providers.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
::: pydantic_ai.providers.openai
88

99
::: pydantic_ai.providers.deepseek
10+
11+
::: pydantic_ai.providers.bedrock

docs/models.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ PydanticAI is Model-agnostic and has built in support for the following model pr
77
* [Groq](#groq)
88
* [Mistral](#mistral)
99
* [Cohere](#cohere)
10+
* [Bedrock](#bedrock)
1011

1112
See [OpenAI-compatible models](#openai-compatible-models) for more examples on how to use models such as [OpenRouter](#openrouter), and [Grok (xAI)](#grok-xai) that support the OpenAI SDK.
1213

@@ -540,6 +541,93 @@ agent = Agent(model)
540541
...
541542
```
542543

544+
## Bedrock
545+
546+
### Install
547+
548+
To use [`BedrockConverseModel`][pydantic_ai.models.bedrock.BedrockConverseModel], you need to either install [`pydantic-ai`](install.md), or install [`pydantic-ai-slim`](install.md#slim-install) with the `bedrock` optional group:
549+
550+
```bash
551+
pip/uv-add 'pydantic-ai-slim[bedrock]'
552+
```
553+
554+
### Configuration
555+
556+
To use [AWS Bedrock](https://aws.amazon.com/bedrock/), you'll need an AWS account with Bedrock enabled and appropriate credentials. You can use either AWS credentials directly or a pre-configured boto3 client.
557+
558+
[`BedrockModelName`][pydantic_ai.models.bedrock.BedrockModelName] contains a list of available Bedrock models, including models from Anthropic, Amazon, Cohere, Meta, and Mistral.
559+
560+
### Environment variables
561+
562+
You can set your AWS credentials as environment variables:
563+
564+
```bash
565+
export AWS_ACCESS_KEY_ID='your-access-key'
566+
export AWS_SECRET_ACCESS_KEY='your-secret-key'
567+
export AWS_REGION='us-east-1' # or your preferred region
568+
```
569+
570+
You can then use [`BedrockConverseModel`][pydantic_ai.models.bedrock.BedrockConverseModel] by name:
571+
572+
```python {title="bedrock_model_by_name.py", test="skip"}
573+
from pydantic_ai import Agent
574+
575+
agent = Agent('bedrock:anthropic.claude-3-sonnet-20240229-v1:0')
576+
...
577+
```
578+
579+
Or initialize the model directly with just the model name:
580+
581+
```python {title="bedrock_model_init.py" test="skip"}
582+
from pydantic_ai import Agent
583+
from pydantic_ai.models.bedrock import BedrockConverseModel
584+
585+
model = BedrockConverseModel('anthropic.claude-3-sonnet-20240229-v1:0')
586+
agent = Agent(model)
587+
...
588+
```
589+
590+
### `provider` argument
591+
592+
You can provide a custom [`BedrockProvider`][pydantic_ai.providers.bedrock.BedrockProvider] via the [`provider` argument][pydantic_ai.models.bedrock.BedrockConverseModel.__init__]. This is useful when you want to specify credentials directly or use a custom boto3 client:
593+
594+
```python {title="bedrock_model_provider.py"}
595+
from pydantic_ai import Agent
596+
from pydantic_ai.models.bedrock import BedrockConverseModel
597+
from pydantic_ai.providers.bedrock import BedrockProvider
598+
599+
# Using AWS credentials directly
600+
model = BedrockConverseModel(
601+
'anthropic.claude-3-sonnet-20240229-v1:0',
602+
provider=BedrockProvider(
603+
region_name='us-east-1',
604+
aws_access_key_id='your-access-key',
605+
aws_secret_access_key='your-secret-key',
606+
),
607+
)
608+
agent = Agent(model)
609+
...
610+
```
611+
612+
You can also pass a pre-configured boto3 client:
613+
614+
```python {title="bedrock_model_boto3.py"}
615+
import boto3
616+
617+
from pydantic_ai import Agent
618+
from pydantic_ai.models.bedrock import BedrockConverseModel
619+
from pydantic_ai.providers.bedrock import BedrockProvider
620+
621+
# Using a pre-configured boto3 client
622+
bedrock_client = boto3.client('bedrock-runtime', region_name='us-east-1')
623+
model = BedrockConverseModel(
624+
'anthropic.claude-3-sonnet-20240229-v1:0',
625+
provider=BedrockProvider(bedrock_client=bedrock_client),
626+
)
627+
agent = Agent(model)
628+
...
629+
```
630+
543631
## OpenAI-compatible Models
544632

545633
Many of the models are compatible with OpenAI API, and thus can be used with [`OpenAIModel`][pydantic_ai.models.openai.OpenAIModel] in PydanticAI.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ nav:
5454
- api/models/base.md
5555
- api/models/openai.md
5656
- api/models/anthropic.md
57+
- api/models/bedrock.md
5758
- api/models/cohere.md
5859
- api/models/gemini.md
5960
- api/models/vertexai.md

pydantic_ai_slim/pydantic_ai/_pydantic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from __future__ import annotations as _annotations
77

88
from inspect import Parameter, signature
9-
from typing import TYPE_CHECKING, Any, Callable, TypedDict, cast
9+
from typing import TYPE_CHECKING, Any, Callable, cast
1010

1111
from pydantic import ConfigDict
1212
from pydantic._internal import _decorators, _generate_schema, _typing_extra
@@ -15,7 +15,7 @@
1515
from pydantic.json_schema import GenerateJsonSchema
1616
from pydantic.plugin._schema_validator import create_schema_validator
1717
from pydantic_core import SchemaValidator, core_schema
18-
from typing_extensions import get_origin
18+
from typing_extensions import TypedDict, get_origin
1919

2020
from ._griffe import doc_descriptions
2121
from ._utils import check_object_json_schema, is_model_like

pydantic_ai_slim/pydantic_ai/common_tools/duckduckgo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import functools
22
from dataclasses import dataclass
3-
from typing import TypedDict
43

54
import anyio
65
import anyio.to_thread
76
from pydantic import TypeAdapter
7+
from typing_extensions import TypedDict
88

99
from pydantic_ai.tools import Tool
1010

pydantic_ai_slim/pydantic_ai/common_tools/tavily.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from dataclasses import dataclass
2-
from typing import Literal, TypedDict
2+
from typing import Literal
33

44
from pydantic import TypeAdapter
5+
from typing_extensions import TypedDict
56

67
from pydantic_ai.tools import Tool
78

pydantic_ai_slim/pydantic_ai/models/__init__.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,49 @@
3434
'anthropic:claude-3-opus-latest',
3535
'claude-3-7-sonnet-latest',
3636
'claude-3-5-haiku-latest',
37+
'bedrock:amazon.titan-tg1-large',
38+
'bedrock:amazon.titan-text-lite-v1',
39+
'bedrock:amazon.titan-text-express-v1',
40+
'bedrock:us.amazon.nova-pro-v1:0',
41+
'bedrock:us.amazon.nova-lite-v1:0',
42+
'bedrock:us.amazon.nova-micro-v1:0',
43+
'bedrock:anthropic.claude-3-5-sonnet-20241022-v2:0',
44+
'bedrock:us.anthropic.claude-3-5-sonnet-20241022-v2:0',
45+
'bedrock:anthropic.claude-3-5-haiku-20241022-v1:0',
46+
'bedrock:us.anthropic.claude-3-5-haiku-20241022-v1:0',
47+
'bedrock:anthropic.claude-instant-v1',
48+
'bedrock:anthropic.claude-v2:1',
49+
'bedrock:anthropic.claude-v2',
50+
'bedrock:anthropic.claude-3-sonnet-20240229-v1:0',
51+
'bedrock:us.anthropic.claude-3-sonnet-20240229-v1:0',
52+
'bedrock:anthropic.claude-3-haiku-20240307-v1:0',
53+
'bedrock:us.anthropic.claude-3-haiku-20240307-v1:0',
54+
'bedrock:anthropic.claude-3-opus-20240229-v1:0',
55+
'bedrock:us.anthropic.claude-3-opus-20240229-v1:0',
56+
'bedrock:anthropic.claude-3-5-sonnet-20240620-v1:0',
57+
'bedrock:us.anthropic.claude-3-5-sonnet-20240620-v1:0',
58+
'bedrock:anthropic.claude-3-7-sonnet-20250219-v1:0',
59+
'bedrock:us.anthropic.claude-3-7-sonnet-20250219-v1:0',
60+
'bedrock:cohere.command-text-v14',
61+
'bedrock:cohere.command-r-v1:0',
62+
'bedrock:cohere.command-r-plus-v1:0',
63+
'bedrock:cohere.command-light-text-v14',
64+
'bedrock:meta.llama3-8b-instruct-v1:0',
65+
'bedrock:meta.llama3-70b-instruct-v1:0',
66+
'bedrock:meta.llama3-1-8b-instruct-v1:0',
67+
'bedrock:us.meta.llama3-1-8b-instruct-v1:0',
68+
'bedrock:meta.llama3-1-70b-instruct-v1:0',
69+
'bedrock:us.meta.llama3-1-70b-instruct-v1:0',
70+
'bedrock:meta.llama3-1-405b-instruct-v1:0',
71+
'bedrock:us.meta.llama3-2-11b-instruct-v1:0',
72+
'bedrock:us.meta.llama3-2-90b-instruct-v1:0',
73+
'bedrock:us.meta.llama3-2-1b-instruct-v1:0',
74+
'bedrock:us.meta.llama3-2-3b-instruct-v1:0',
75+
'bedrock:us.meta.llama3-3-70b-instruct-v1:0',
76+
'bedrock:mistral.mistral-7b-instruct-v0:2',
77+
'bedrock:mistral.mixtral-8x7b-instruct-v0:1',
78+
'bedrock:mistral.mistral-large-2402-v1:0',
79+
'bedrock:mistral.mistral-large-2407-v1:0',
3780
'claude-3-5-sonnet-latest',
3881
'claude-3-opus-latest',
3982
'cohere:c4ai-aya-expanse-32b',
@@ -324,7 +367,7 @@ def infer_model(model: Model | KnownModelName) -> Model:
324367
return TestModel()
325368

326369
try:
327-
provider, model_name = model.split(':')
370+
provider, model_name = model.split(':', maxsplit=1)
328371
except ValueError:
329372
model_name = model
330373
# TODO(Marcelo): We should deprecate this way.
@@ -368,6 +411,10 @@ def infer_model(model: Model | KnownModelName) -> Model:
368411

369412
# TODO(Marcelo): Missing provider API.
370413
return AnthropicModel(model_name)
414+
elif provider == 'bedrock':
415+
from .bedrock import BedrockConverseModel
416+
417+
return BedrockConverseModel(model_name)
371418
else:
372419
raise UserError(f'Unknown model: {model}')
373420

0 commit comments

Comments
 (0)