Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ jobs:
- name: Run build
run: rye build

- name: Validate Bedrock wheel
run: rye run python scripts/utils/validate-bedrock-wheel.py

- name: Get GitHub OIDC Token
if: |-
github.repository == 'stainless-sdks/openai-python' &&
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "2.43.0"
".": "2.44.0"
}
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 2.44.0 (2026-06-24)

Full Changelog: [v2.43.0...v2.44.0](https://github.com/openai/openai-python/compare/v2.43.0...v2.44.0)

### Bug Fixes

* **auth:** prioritize first auth header ([797e336](https://github.com/openai/openai-python/commit/797e3362e222ae14e587a4543b76a54d8992d66c))

## 2.43.0 (2026-06-17)

Full Changelog: [v2.42.0...v2.43.0](https://github.com/openai/openai-python/compare/v2.42.0...v2.43.0)
Expand Down
61 changes: 53 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -928,13 +928,25 @@ An example of using the client with Microsoft Entra ID (formerly known as Azure

## 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.
To use this library with [Amazon Bedrock's OpenAI-compatible API](https://docs.aws.amazon.com/bedrock/latest/userguide/models-api-compatibility.html), configure the standard `OpenAI` client with the Bedrock provider.

Install the optional Bedrock dependencies to use the standard AWS credential chain and SigV4 authentication:

```sh
pip install 'openai[bedrock]'
```

```py
from openai import BedrockOpenAI
from openai import OpenAI
from openai.providers import bedrock

# gets the bearer token from AWS_BEARER_TOKEN_BEDROCK and the region from AWS_REGION/AWS_DEFAULT_REGION
client = BedrockOpenAI()
# Uses your normal AWS credentials. You can omit region when it is
# configured through AWS_REGION, AWS_DEFAULT_REGION, or your AWS profile.
client = OpenAI(
provider=bedrock(
region="us-west-2",
)
)

response = client.responses.create(
model="openai.gpt-5.4",
Expand All @@ -944,19 +956,52 @@ response = client.responses.create(
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.
The provider configures AWS authentication and the Bedrock Mantle endpoint while retaining the normal SDK resources, retries, streaming, and error handling. AWS controls which endpoints and features are supported; unsupported calls surface the provider's normal HTTP errors through the SDK.

The default AWS credential chain supports environment credentials, shared credentials and config files, named profiles, SSO and assume-role profiles, and workload credentials such as ECS, EKS, and EC2 metadata. To select a named profile:

```py
client = OpenAI(
provider=bedrock(
profile="my-profile",
)
)
```

You can also pass `access_key_id` and `secret_access_key`, with an optional `session_token`, or a refreshable `credential_provider` that returns botocore-compatible credentials. Explicit bearer and AWS credential options are mutually exclusive.

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`.
Pass `base_url` to `bedrock(...)` or set `AWS_BEDROCK_BASE_URL` to override the derived `https://bedrock-mantle.<region>.api.aws/openai/v1` endpoint.

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`:
SigV4 requests require replayable, fully serialized request bodies. Standard JSON requests already meet this requirement, and response streaming is unaffected. Low-level one-shot request streams must be buffered before sending, or sent with bearer authentication and retries disabled.

Bearer tokens remain available as a compatibility or manual authentication mode. Set `AWS_BEARER_TOKEN_BEDROCK` to an [Amazon Bedrock API key](https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html), pass `api_key`, or provide a refresh callback:

```py
client = OpenAI(
provider=bedrock(
region="us-west-2",
token_provider=lambda: refresh_bedrock_token(),
)
)
```

Without explicit authentication, `AWS_BEARER_TOKEN_BEDROCK` takes precedence over the default AWS credential chain for backwards compatibility.

### Legacy `BedrockOpenAI` client

`BedrockOpenAI` and `AsyncBedrockOpenAI` remain available for existing applications and delegate to the same provider implementation. New applications should prefer `OpenAI(provider=bedrock(...))`.

```py
from openai import BedrockOpenAI

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

The legacy module client also continues to support `openai.api_type = "amazon-bedrock"` or `OPENAI_API_TYPE=amazon-bedrock`.

## 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
12 changes: 7 additions & 5 deletions examples/bedrock.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from openai import BedrockOpenAI
from openai import OpenAI
from openai.providers import bedrock

client = BedrockOpenAI()

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

response = client.responses.create(
model="openai.gpt-5.4",
Expand Down
10 changes: 8 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "openai"
version = "2.43.0"
version = "2.44.0"
description = "The official Python library for the openai API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand All @@ -11,7 +11,7 @@ authors = [
dependencies = [
"httpx>=0.23.0, <1",
"pydantic>=1.9.0, <3",
"typing-extensions>=4.11, <5", "typing-extensions>=4.14, <5",
"typing-extensions>=4.14, <5",
"anyio>=3.5.0, <5",
"distro>=1.7.0, <2",
"sniffio",
Expand Down Expand Up @@ -47,6 +47,10 @@ aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.9"]
realtime = ["websockets >= 13, < 16"]
datalib = ["numpy >= 1", "pandas >= 1.2.3", "pandas-stubs >= 1.1.0.11"]
voice_helpers = ["sounddevice>=0.5.1", "numpy>=2.0.2"]
bedrock = [
"botocore>=1.40.0,<1.43; python_version < '3.10'",
"botocore>=1.40.0,<2; python_version >= '3.10'",
]

[tool.rye]
managed = true
Expand All @@ -57,6 +61,7 @@ dev-dependencies = [
"respx",
"pytest",
"pytest-asyncio",
"jsonschema>=4.23.0",
"ruff",
"time-machine",
"nox",
Expand All @@ -65,6 +70,7 @@ dev-dependencies = [
"rich>=13.7.1",
"inline-snapshot>=0.28.0",
"azure-identity >=1.14.1",
"botocore==1.42.97",
"types-tqdm > 4",
"types-pyaudio > 0",
"trio >=0.22.2",
Expand Down
25 changes: 22 additions & 3 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,18 @@ async-timeout==5.0.1
# via aiohttp
attrs==25.4.0
# via aiohttp
# via jsonschema
# via nox
# via outcome
# via referencing
# via trio
azure-core==1.36.0
# via azure-identity
azure-identity==1.25.1
backports-asyncio-runner==1.2.0
# via pytest-asyncio
botocore==1.42.97
# via openai
certifi==2026.1.4
# via httpcore
# via httpx
Expand Down Expand Up @@ -100,6 +104,11 @@ iniconfig==2.1.0
inline-snapshot==0.31.1
jiter==0.12.0
# via openai
jmespath==1.1.0
# via botocore
jsonschema==4.25.1
jsonschema-specifications==2025.9.1
# via jsonschema
markdown-it-py==3.0.0
# via rich
mdurl==0.1.2
Expand Down Expand Up @@ -161,16 +170,23 @@ pytest==8.4.2
pytest-asyncio==1.2.0
pytest-xdist==3.8.0
python-dateutil==2.9.0.post0
# via botocore
# via pandas
# via time-machine
pytz==2025.2
# via pandas
referencing==0.36.2
# via jsonschema
# via jsonschema-specifications
requests==2.32.5
# via azure-core
# via msal
respx==0.22.0
rich==14.2.0
# via inline-snapshot
rpds-py==0.27.1
# via jsonschema
# via referencing
ruff==0.14.7
six==1.17.0
# via python-dateutil
Expand All @@ -194,9 +210,11 @@ trio==0.31.0
types-pyaudio==0.2.16.20250801
types-pytz==2025.2.0.20251108
# via pandas-stubs
types-requests==2.32.4.20250913
types-requests==2.31.0.6
# via types-tqdm
types-tqdm==4.67.0.20250809
types-urllib3==1.26.25.14
# via types-requests
typing-extensions==4.15.0
# via aiosignal
# via anyio
Expand All @@ -211,15 +229,16 @@ typing-extensions==4.15.0
# via pydantic-core
# via pyright
# via pytest-asyncio
# via referencing
# via typing-inspection
# via virtualenv
typing-inspection==0.4.2
# via pydantic
tzdata==2025.2
# via pandas
urllib3==2.5.0
urllib3==1.26.20
# via botocore
# via requests
# via types-requests
virtualenv==20.35.4
# via nox
websockets==15.0.1
Expand Down
7 changes: 7 additions & 0 deletions requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ async-timeout==5.0.1
# via aiohttp
attrs==25.4.0
# via aiohttp
botocore==1.42.97
# via openai
certifi==2026.1.4
# via httpcore
# via httpx
Expand Down Expand Up @@ -53,6 +55,8 @@ idna==3.11
# via yarl
jiter==0.12.0
# via openai
jmespath==1.1.0
# via botocore
multidict==6.7.0
# via aiohttp
# via yarl
Expand All @@ -74,6 +78,7 @@ pydantic==2.12.5
pydantic-core==2.41.5
# via pydantic
python-dateutil==2.9.0.post0
# via botocore
# via pandas
pytz==2025.2
# via pandas
Expand All @@ -100,6 +105,8 @@ typing-inspection==0.4.2
# via pydantic
tzdata==2025.2
# via pandas
urllib3==1.26.20
# via botocore
websockets==15.0.1
# via openai
yarl==1.22.0
Expand Down
Loading
Loading