Skip to content

Commit ccef143

Browse files
authored
Merge pull request openai#3326 from openai/codex/bedrock-responses-review
feat(api): Add Amazon Bedrock Responses support
2 parents fdf4901 + a50ff0a commit ccef143

6 files changed

Lines changed: 1081 additions & 3 deletions

File tree

‎README.md‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,37 @@ In addition to the options provided in the base `OpenAI` client, the following o
926926

927927
An example of using the client with Microsoft Entra ID (formerly known as Azure Active Directory) can be found [here](https://github.com/openai/openai-python/blob/main/examples/azure_ad.py).
928928

929+
## Amazon Bedrock
930+
931+
To use this library with [Amazon Bedrock's OpenAI-compatible API](https://docs.aws.amazon.com/bedrock/latest/userguide/models-api-compatibility.html), use the `BedrockOpenAI` class instead of the `OpenAI` class.
932+
933+
```py
934+
from openai import BedrockOpenAI
935+
936+
# gets the bearer token from AWS_BEARER_TOKEN_BEDROCK and the region from AWS_REGION/AWS_DEFAULT_REGION
937+
client = BedrockOpenAI()
938+
939+
response = client.responses.create(
940+
model="openai.gpt-5.4",
941+
input="Say hello!",
942+
)
943+
944+
print(response.output_text)
945+
```
946+
947+
`BedrockOpenAI` configures AWS bearer auth and the Bedrock Mantle endpoint, then uses the normal SDK resources. AWS controls which endpoints and features are supported; unsupported calls surface the provider's normal HTTP errors through the SDK.
948+
949+
Pass `base_url` or set `AWS_BEDROCK_BASE_URL` to override the derived `https://bedrock-mantle.<region>.api.aws/openai/v1` endpoint. The legacy module client supports `openai.api_type = "amazon-bedrock"` or `OPENAI_API_TYPE=amazon-bedrock`.
950+
951+
Set `AWS_BEARER_TOKEN_BEDROCK` to an [Amazon Bedrock API key](https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html). To refresh tokens yourself, pass a provider instead of `api_key`:
952+
953+
```py
954+
client = BedrockOpenAI(
955+
aws_region="us-west-2",
956+
bedrock_token_provider=lambda: refresh_bedrock_token(),
957+
)
958+
```
959+
929960
## Versioning
930961

931962
This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:

‎examples/bedrock.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from openai import BedrockOpenAI
2+
3+
client = BedrockOpenAI()
4+
5+
# For refreshed Bedrock bearer tokens:
6+
# client = BedrockOpenAI(aws_region="us-west-2", bedrock_token_provider=get_bedrock_token)
7+
8+
response = client.responses.create(
9+
model="openai.gpt-5.4",
10+
input="Say hello!",
11+
)
12+
13+
print(response.output_text)

‎src/openai/__init__.py‎

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@
7979
"AsyncStream",
8080
"OpenAI",
8181
"AsyncOpenAI",
82+
"BedrockOpenAI",
83+
"AsyncBedrockOpenAI",
8284
"file_from_path",
8385
"BaseModel",
8486
"DEFAULT_TIMEOUT",
@@ -96,9 +98,10 @@
9698
if not _t.TYPE_CHECKING:
9799
from ._utils._resources_proxy import resources as resources
98100

99-
from .lib import azure as _azure, pydantic_function_tool as pydantic_function_tool
101+
from .lib import azure as _azure, bedrock as _bedrock, pydantic_function_tool as pydantic_function_tool
100102
from .version import VERSION as VERSION
101103
from .lib.azure import AzureOpenAI as AzureOpenAI, AsyncAzureOpenAI as AsyncAzureOpenAI
104+
from .lib.bedrock import BedrockOpenAI as BedrockOpenAI, AsyncBedrockOpenAI as AsyncBedrockOpenAI
102105
from .lib._old_api import *
103106
from .lib.streaming import (
104107
AssistantEventHandler as AssistantEventHandler,
@@ -150,7 +153,7 @@
150153

151154
http_client: _httpx.Client | None = None
152155

153-
_ApiType = _te.Literal["openai", "azure"]
156+
_ApiType = _te.Literal["openai", "azure", "amazon-bedrock"]
154157

155158
api_type: _ApiType | None = _t.cast(_ApiType, _os.environ.get("OPENAI_API_TYPE"))
156159

@@ -162,6 +165,10 @@
162165

163166
azure_ad_token_provider: _azure.AzureADTokenProvider | None = None
164167

168+
_bedrock_api_key: str | None = None
169+
170+
bedrock_token_provider: _bedrock.BedrockTokenProvider | None = None
171+
165172

166173
class _ModuleClient(OpenAI):
167174
# Note: we have to use type: ignores here as overriding class members
@@ -294,10 +301,23 @@ class _AzureModuleClient(_ModuleClient, AzureOpenAI): # type: ignore
294301
...
295302

296303

304+
class _BedrockModuleClient(_ModuleClient, BedrockOpenAI): # type: ignore
305+
@property # type: ignore
306+
@override
307+
def api_key(self) -> str | None:
308+
return _bedrock_api_key if _bedrock_api_key is not None else api_key
309+
310+
@api_key.setter # type: ignore
311+
def api_key(self, value: str | None) -> None: # type: ignore
312+
global _bedrock_api_key
313+
314+
_bedrock_api_key = value
315+
316+
297317
class _AmbiguousModuleClientUsageError(OpenAIError):
298318
def __init__(self) -> None:
299319
super().__init__(
300-
"Ambiguous use of module client; please set `openai.api_type` or the `OPENAI_API_TYPE` environment variable to `openai` or `azure`"
320+
"Ambiguous use of module client; please set `openai.api_type` or the `OPENAI_API_TYPE` environment variable to `openai`, `azure`, or `amazon-bedrock`"
301321
)
302322

303323

@@ -370,6 +390,22 @@ def _load_client() -> OpenAI: # type: ignore[reportUnusedFunction]
370390
)
371391
return _client
372392

393+
if api_type == "amazon-bedrock":
394+
_client = _BedrockModuleClient( # type: ignore
395+
api_key=api_key,
396+
bedrock_token_provider=bedrock_token_provider,
397+
organization=organization,
398+
project=project,
399+
webhook_secret=webhook_secret,
400+
base_url=base_url,
401+
timeout=timeout,
402+
max_retries=max_retries,
403+
default_headers=default_headers,
404+
default_query=default_query,
405+
http_client=http_client,
406+
)
407+
return _client
408+
373409
_client = _ModuleClient(
374410
api_key=api_key,
375411
admin_api_key=admin_api_key,

0 commit comments

Comments
 (0)