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
4 changes: 2 additions & 2 deletions .castiron.stats.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
schema_version: 1
generation_id: e1943695-9da0-4ac1-ae5a-cc763f5d90be
generation_id: 6f16b5a1-6b31-43ea-a1dd-a1a9fc37821e
openapi_spec_hash: 1faf0319c407c6534ef7c381614afbb6
openapi_transformed_spec_hash: 53eff50caa9d18046e4ff0615bc7512d
config_hash: 4617b0962f16d328804312ac81aac630
codegen_sha: b97c76f867d26f99d0de01d6283fa6d511044141
codegen_sha: 20f59b5cced5772bda4c6d6e3e19726d3805e4a1
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.54.0"
".": "3.0.0"
}
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## [3.0.0](https://github.com/openai/openai-python/compare/v2.54.0...v3.0.0) (2026-08-12)


### ⚠ BREAKING CHANGES

* **api:** HTTPX2 is now the default HTTP client, and `httpx` is no longer installed automatically. Applications using custom HTTPX clients, transports, or configuration objects must migrate to their HTTPX2 equivalents or use the temporary, runtime-only legacy HTTPX escape hatch. See the [HTTPX2 migration guide](https://github.com/openai/openai-python/blob/main/httpx2.md).

### Features

* **api:** migrate to HTTPX2 ([#3594](https://github.com/openai/openai-python/pull/3594))

## [2.54.0](https://github.com/openai/openai-python/compare/v2.53.0...v2.54.0) (2026-08-11)


Expand Down
90 changes: 21 additions & 69 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

The OpenAI Python library provides convenient access to the OpenAI REST API from any Python 3.10+
application. The library includes type definitions for all request params and response fields,
and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
and offers both synchronous and asynchronous clients powered by [HTTPX2](https://httpx2.pydantic.dev/).

It is generated from our [OpenAPI specification](https://github.com/openai/openai-openapi) with [Stainless](https://stainlessapi.com/).

Expand Down Expand Up @@ -244,9 +244,7 @@ Functionality between the synchronous and asynchronous clients is otherwise iden

### With aiohttp

By default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend.

The `aiohttp` backend requires Python 3.10 or later.
By default, the async client uses HTTPX2. For improved concurrency performance, you may also use `aiohttp` as the HTTPX2 transport.

You can enable this by installing `aiohttp`:

Expand Down Expand Up @@ -283,32 +281,9 @@ async def main() -> None:
asyncio.run(main())
```

### Experimental HTTPX2 support

To opt in to experimental HTTPX2 support, install the optional extra on Python 3.10 or later:

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

```python
from openai import OpenAI, AsyncOpenAI, DefaultHttpx2Client, DefaultAsyncHttpx2Client

client = OpenAI(http_client=DefaultHttpx2Client())
async_client = AsyncOpenAI(http_client=DefaultAsyncHttpx2Client())
```

See [`examples/httpx2_client.py`](examples/httpx2_client.py) for a minimal runnable example.
### HTTPX2 migration

The module-level client can be configured in the same way:

```python
import openai

openai.http_client = openai.DefaultHttpx2Client()
```

Parsed API models are unchanged, but requests, raw and streaming responses, and transport-level exceptions may be HTTPX2 objects at runtime. Code that catches HTTPX exceptions or relies on HTTPX-specific mocks, transports, authentication, hooks, or instrumentation may need to be updated. Transport-facing type annotations may still describe HTTPX.
HTTPX2 is the default HTTP client. If you configure a custom HTTP client, transport, timeout, authentication handler, event hook, or request mock, see the [HTTPX2 migration guide](httpx2.md).

## Streaming responses

Expand Down Expand Up @@ -636,7 +611,7 @@ try:
)
except openai.APIConnectionError as e:
print("The server could not be reached")
print(e.__cause__) # an underlying Exception, likely raised within httpx.
print(e.__cause__) # an underlying Exception, likely raised within HTTPX2.
except openai.RateLimitError as e:
print("A 429 status code was received; we should back off a bit.")
except openai.APIStatusError as e:
Expand Down Expand Up @@ -723,9 +698,10 @@ client.with_options(max_retries=5).chat.completions.create(
## Timeouts

By default requests time out after 10 minutes. You can configure this with a `timeout` option,
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
which accepts a float or an [`httpx2.Timeout`](https://httpx2.pydantic.dev/) object:

```python
import httpx2
from openai import OpenAI

# Configure the default for all requests:
Expand All @@ -736,7 +712,7 @@ client = OpenAI(

# More granular control:
client = OpenAI(
timeout=httpx.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
timeout=httpx2.Timeout(60.0, read=5.0, write=10.0, connect=2.0),
)

# Override per-request:
Expand Down Expand Up @@ -849,11 +825,11 @@ To make requests to undocumented endpoints, you can make requests using `client.
http verbs. Options on the client will be respected (such as retries) when making this request.

```py
import httpx
import httpx2

response = client.post(
"/foo",
cast_to=httpx.Response,
cast_to=httpx2.Response,
body={"my_param": True},
)

Expand All @@ -873,30 +849,26 @@ can also get all the extra fields on the Pydantic model as a dict with

### Configuring the HTTP client

You can directly override the [httpx client](https://www.python-httpx.org/api/#client) to customize it for your use case, including:

- Support for [proxies](https://www.python-httpx.org/advanced/proxies/)
- Custom [transports](https://www.python-httpx.org/advanced/transports/)
- Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality
You can override the [HTTPX2 client](https://httpx2.pydantic.dev/) to customize proxies, transports, authentication, event hooks, and other advanced HTTP behavior. See the [HTTPX2 migration guide](httpx2.md) when updating an existing custom client.

```python
import httpx
from openai import OpenAI, DefaultHttpxClient
import httpx2
from openai import OpenAI, DefaultHttpx2Client

client = OpenAI(
# Or use the `OPENAI_BASE_URL` env var
base_url="http://my.test.server.example.com:8083/v1",
http_client=DefaultHttpxClient(
http_client=DefaultHttpx2Client(
proxy="http://my.test.proxy.example.com",
transport=httpx.HTTPTransport(local_address="0.0.0.0"),
transport=httpx2.HTTPTransport(local_address="0.0.0.0"),
),
)
```

You can also customize the client on a per-request basis by using `with_options()`:

```python
client.with_options(http_client=DefaultHttpxClient(...))
client.with_options(http_client=DefaultHttpx2Client(...))
```

#### Mutual TLS
Expand All @@ -913,7 +885,7 @@ and pass it through the custom HTTP client:
import os
import ssl

from openai import OpenAI, DefaultHttpxClient
from openai import OpenAI, DefaultHttpx2Client

# Server trust is configured independently. Without `cafile`, this uses the
# operating system's normal trusted certificate authorities.
Expand All @@ -938,7 +910,7 @@ client = OpenAI(
),
# A client certificate belongs to the HTTP client, not the base URL.
# Disable redirects so it cannot follow a response to another origin.
http_client=DefaultHttpxClient(
http_client=DefaultHttpx2Client(
verify=ssl_context,
follow_redirects=False,
),
Expand All @@ -951,7 +923,7 @@ The async configuration is equivalent:
import os
import ssl

from openai import AsyncOpenAI, DefaultAsyncHttpxClient
from openai import AsyncOpenAI, DefaultAsyncHttpx2Client

ssl_context = ssl.create_default_context(
cafile=os.environ.get("OPENAI_MTLS_CA_BUNDLE"),
Expand All @@ -968,27 +940,7 @@ client = AsyncOpenAI(
"OPENAI_BASE_URL",
"https://mtls.api.openai.com/v1",
),
http_client=DefaultAsyncHttpxClient(
verify=ssl_context,
follow_redirects=False,
),
)
```

Experimental HTTPX2 uses the same native `SSLContext`. Install the optional
extra with `pip install 'openai[httpx2]'`, then use `DefaultHttpx2Client` or
`DefaultAsyncHttpx2Client` in place of the corresponding HTTPX client above:

```python
from openai import OpenAI, DefaultHttpx2Client

client = OpenAI(
api_key=os.environ["OPENAI_API_KEY"],
base_url=os.environ.get(
"OPENAI_BASE_URL",
"https://mtls.api.openai.com/v1",
),
http_client=DefaultHttpx2Client(
http_client=DefaultAsyncHttpx2Client(
verify=ssl_context,
follow_redirects=False,
),
Expand All @@ -1001,7 +953,7 @@ See the complete [sync HTTPX2](examples/mtls_httpx2.py) and
The certificate-bearing HTTP client is transport-wide. Dedicate it to the
selected mTLS origin; do not reuse it for other services or pass it through
`with_options()` with a different `base_url`. If redirects are required, add an
HTTPX request hook that rejects requests whose scheme, host, or port differs
HTTPX2 request hook that rejects requests whose scheme, host, or port differs
from the configured mTLS origin before enabling `follow_redirects`.

`SSLContext.load_cert_chain()` raises during setup for unreadable or malformed
Expand Down
Loading
Loading