Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,37 @@ In addition to the options provided in the base `OpenAI` client, the following o

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).

## Amazon Bedrock

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.

```py
from openai import BedrockOpenAI

# gets the bearer token from AWS_BEARER_TOKEN_BEDROCK and the region from AWS_REGION/AWS_DEFAULT_REGION
client = BedrockOpenAI()

response = client.responses.create(
model="openai.gpt-5.4",
input="Say hello!",
)

print(response.output_text)
```

`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.

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`.

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`:

```py
client = BedrockOpenAI(
aws_region="us-west-2",
bedrock_token_provider=lambda: refresh_bedrock_token(),
)
```

## Versioning

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:
Expand Down
13 changes: 13 additions & 0 deletions examples/bedrock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from openai import BedrockOpenAI

client = BedrockOpenAI()

# For refreshed Bedrock bearer tokens:
# client = BedrockOpenAI(aws_region="us-west-2", bedrock_token_provider=get_bedrock_token)

response = client.responses.create(
model="openai.gpt-5.4",
input="Say hello!",
)

print(response.output_text)
42 changes: 39 additions & 3 deletions src/openai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@
"AsyncStream",
"OpenAI",
"AsyncOpenAI",
"BedrockOpenAI",
"AsyncBedrockOpenAI",
"file_from_path",
"BaseModel",
"DEFAULT_TIMEOUT",
Expand All @@ -96,9 +98,10 @@
if not _t.TYPE_CHECKING:
from ._utils._resources_proxy import resources as resources

from .lib import azure as _azure, pydantic_function_tool as pydantic_function_tool
from .lib import azure as _azure, bedrock as _bedrock, pydantic_function_tool as pydantic_function_tool
from .version import VERSION as VERSION
from .lib.azure import AzureOpenAI as AzureOpenAI, AsyncAzureOpenAI as AsyncAzureOpenAI
from .lib.bedrock import BedrockOpenAI as BedrockOpenAI, AsyncBedrockOpenAI as AsyncBedrockOpenAI
from .lib._old_api import *
from .lib.streaming import (
AssistantEventHandler as AssistantEventHandler,
Expand Down Expand Up @@ -150,7 +153,7 @@

http_client: _httpx.Client | None = None

_ApiType = _te.Literal["openai", "azure"]
_ApiType = _te.Literal["openai", "azure", "amazon-bedrock"]

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

Expand All @@ -162,6 +165,10 @@

azure_ad_token_provider: _azure.AzureADTokenProvider | None = None

_bedrock_api_key: str | None = None

bedrock_token_provider: _bedrock.BedrockTokenProvider | None = None


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


class _BedrockModuleClient(_ModuleClient, BedrockOpenAI): # type: ignore
@property # type: ignore
@override
def api_key(self) -> str | None:
return _bedrock_api_key if _bedrock_api_key is not None else api_key

@api_key.setter # type: ignore
def api_key(self, value: str | None) -> None: # type: ignore
global _bedrock_api_key

_bedrock_api_key = value


class _AmbiguousModuleClientUsageError(OpenAIError):
def __init__(self) -> None:
super().__init__(
"Ambiguous use of module client; please set `openai.api_type` or the `OPENAI_API_TYPE` environment variable to `openai` or `azure`"
"Ambiguous use of module client; please set `openai.api_type` or the `OPENAI_API_TYPE` environment variable to `openai`, `azure`, or `amazon-bedrock`"
)


Expand Down Expand Up @@ -370,6 +390,22 @@ def _load_client() -> OpenAI: # type: ignore[reportUnusedFunction]
)
return _client

if api_type == "amazon-bedrock":
_client = _BedrockModuleClient( # type: ignore
api_key=api_key,
bedrock_token_provider=bedrock_token_provider,
organization=organization,
project=project,
webhook_secret=webhook_secret,
base_url=base_url,
timeout=timeout,
max_retries=max_retries,
default_headers=default_headers,
default_query=default_query,
http_client=http_client,
)
return _client

_client = _ModuleClient(
api_key=api_key,
admin_api_key=admin_api_key,
Expand Down
Loading
Loading