The openai Python package ships two text APIs, an HTTPX2 transport and a fixed mTLS origin
The official Python library for the OpenAI API
At a glance
- What is it?
- openai-python is the official typed client for the OpenAI REST API, generated from an OpenAPI spec and running on Python 3.10 through 3.14. Responses is the primary API with Chat Completions kept alongside it indefinitely, and authentication has grown from an API key into four workload identity providers plus an X.509 mode with hard origin and header restrictions.
- Who is it for?
- Adopt openai-python when you want typed request and response models on Python 3.10 to 3.14 rather than hand-rolled HTTP calls, and pick it over writing your own client because the library is generated from the OpenAPI specification and updates alongside it. Do not pick it if your platform needs Azure with X.509 federation, because that combination is documented as unsupported, or if you need to send provider API-key headers alongside a certificate, which X.509 mode forbids.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.
Star history
- openai/openai-python32,142 ★ · +522
| Repository | 2026-09-11 | 2026-11-13 |
|---|---|---|
| openai/openai-python | 31.6k | 32.1k |
522 Stars in the last 63 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Responses is primary, and Chat Completions is kept with no announced end
Two text-generation APIs sit side by side in this library, and the older one is not scheduled for removal. The Responses API is named as the primary API, and a first call looks like this:
import os
from openai import OpenAI
client = OpenAI(
# This is the default and can be omitted
api_key=os.environ.get("OPENAI_API_KEY"),
)
response = client.responses.create(
model="gpt-5.5",
instructions="You are a coding assistant that talks like a pirate.",
input="How do I check if a Python object is an instance of a class?",
)
print(response.output_text)The shape difference is worth noticing before you port anything. Responses takes `instructions` and `input` as separate arguments, and the reply comes back through the `output_text` property. Chat Completions takes a list of role-tagged `messages` and returns a choice you have to walk into:
from openai import OpenAI
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-5.5",
messages=[
{"role": "developer", "content": "Talk like a pirate."},
{
"role": "user",
"content": "How do I check if a Python object is an instance of a class?",
},
],
)
print(completion.choices[0].message.content)Both snippets pass `model="gpt-5.5"`. The chat path is called the previous standard and marked as supported indefinitely, so an existing codebase has no reason to move, while new code starts on Responses.
The transport is httpx2, and four pydantic releases are excluded by name
The dependency list in `pyproject.toml` is short and specific. It pins `httpx2>=2.12.0, <3` rather than httpx, `typing-extensions>=4.14, <5`, `anyio>=4.10.0, <5`, `sniffio`, `jiter>=0.16.0, <1`, and pydantic as `>=1.10.13, <3` with four exclusions written out: `!=2.0.*`, `!=2.1.*`, `!=2.2.*`, `!=2.3.*`.
That exclusion list is the interesting part, because it means the resolver will refuse those pydantic releases outright rather than fall back to an older one. The lower bound of `>=1.10.13` means pydantic 1.x is still allowed. If your environment is pinned to pydantic 2.1 or 2.2 for another library, the install fails at resolution and the fix is on your side, not in this package.
The synchronous and asynchronous clients are both built on that same HTTP layer, and the examples directory carries separate files for each transport combination: `httpx2_client.py`, `mtls_httpx2.py`, `mtls_httpx2_async.py` and `mtls_httpx_async.py`.
Any provider that returns a token string can stand in for the built-in ones
Workload identity replaces the long-lived API key with short-lived tokens, and the provider slot accepts four shapes. Three are built in: `k8s_service_account_token_provider`, reading a mounted service account token; `azure_managed_identity_token_provider`, taking a `resource`; and `gcp_id_token_provider`, taking an `audience` such as `https://api.openai.com/v1`. The fourth is yours, and it is nothing more than a token type and a callable:
from openai import OpenAI
def get_custom_token() -> str:
return "your-jwt-token"
client = OpenAI(
workload_identity={
"identity_provider_id": "idp-123",
"service_account_id": "sa-456",
"provider": {
"token_type": "jwt",
"get_token": get_custom_token,
},
}
)Every shape shares the same two identifiers alongside it, `identity_provider_id` and `service_account_id`, so the provider is the only part that varies. Timing is adjustable too. `refresh_buffer_seconds` defaults to 1200 seconds, twenty minutes before expiry, and the same key can shorten that:
client = OpenAI(
workload_identity={
"identity_provider_id": "idp-123",
"service_account_id": "sa-456",
"provider": k8s_service_account_token_provider("/var/token"),
"refresh_buffer_seconds": 120.0,
}
)X.509 mode pins the origin and forbids API-key headers on the same client
Certificate-based federation is the strictest mode here, and its limits are stated as constraints rather than options. When neither `base_url` nor `OPENAI_BASE_URL` is set, X.509 defaults to `https://mtls.api.openai.com/v1`. Requests must use HTTPS and stay on that configured origin, and the effective HTTP Host authority has to match it. Provider API-key headers and proxy-only headers cannot be sent to the API alongside X.509 authentication, so a client cannot fall back to a key on the same object.
Two more constraints shape application code. Token exchanges do not inherit API request hooks, authentication, or cookies, which means anything your hooks normally attach is absent from the exchange itself. And identity settings are captured when the client is constructed, so changing identity means building a new client rather than mutating the existing one. Azure clients do not support X.509 workload identity at all.
The scope is HTTP APIs only. Realtime and WebSockets are not covered, and the two rollout-toggle examples, `examples/x509_workload_identity.py` and `examples/x509_workload_identity_async.py`, select between API-key and X.509 through an application-owned `OPENAI_AUTH_MODE` environment variable. Asynchronous work uses `AsyncOpenAI` with `DefaultAsyncHttpx2Client`. Everything about certificates, keys, passwords, server trust, proxies and rotation stays with the application and the transport layer.
One install command, and the extras decide what you are allowed to call
The base install is a single line:
pip install openaiWhat it gives you is the core client. Anything else is an optional dependency group with its own name and its own constraints. `aiohttp` pulls `aiohttp>=3.14.3`. `realtime` pulls `websockets >= 13, < 16`. `datalib` pulls `numpy >= 1` and `pandas >= 1.2.3`. `voice_helpers` pulls `sounddevice>=0.5.1` with `numpy>=2.0.2`, a higher numpy floor than the datalib group asks for. `bedrock` pulls `botocore>=1.40.0,<2` and `urllib3>=2.7.0,<3`.
The consequence is that a bare `pip install openai` gives you no WebSocket support and no AWS SDK, so calling those paths requires knowing which extra to name before you install. Note also that the extras ask for different numpy floors, so a project taking both `datalib` and `voice_helpers` resolves to the stricter floor of 2.0.2. The examples directory reflects that split: `bedrock.py` and `bedrock_runtime.py` for the AWS path, `azure.py` and `azure_ad.py` for Azure, and a `live/` directory for realtime work.
Supported on Python 3.10 to 3.14, but the repo tooling pins Node 22.22.3
Runtime support is wide and the classifiers are explicit. `requires-python` is set to `>= 3.10`, and the classifier list names Python 3.10, 3.11, 3.12, 3.13 and 3.14, with `Operating System :: OS Independent` plus POSIX, MacOS, Linux and Windows. A `PYTHON_VERSION_POLICY.md` sits at the root.
Contributing to the library is where the toolchain gets narrower. The same repository ships a private pnpm workspace in `package.json` named `openai-python-tooling`, with `packageManager` set to `[email protected]` and `engines` demanding node `22.22.3`, an exact patch version. Its single devDependency is `pyright` at `1.1.414`. Alongside it sit `pnpm-lock.yaml`, `pnpm-workspace.yaml`, a `Brewfile`, `.node-version` and `.python-version`, so both runtimes are version-pinned for contributors.
The Python side of that same dev group pins `ty==0.0.87`, `pytest>=9.0.3`, `pytest-asyncio>=1.4.0` and `trio>=0.22.2`.
Generated from an OpenAPI spec, released by release-please, and dated ahead of the branch
The library is not hand-written, and that shapes what a maintainer edits. It is generated from the project's OpenAPI specification, with the complete API surface in `api.md` and an `api_reference/` directory at the root. Generated code means a change to the specification, not to the SDK, is what surfaces as a new library version.
The release machinery is visible in the repository root: `.release-please-manifest.json` and `release-please-config.json` alongside `CHANGELOG.md`. The three most recent tags are v3.42.1 on 2026-11-01, v3.42.0 on 2026-10-31 and v3.41.0 on 2026-10-28, and `pyproject.toml` carries `version = "3.42.1"`, matching the newest tag. The repository is not archived.
Metadata around all of this is deliberately plain. The package is `openai`, licensed Apache-2.0, authored by OpenAI at [email protected], with the homepage pointing at the PyPI project page rather than a marketing site. Auxiliary documents include `SECURITY.md`, `CONTRIBUTING.md`, `AGENTS.md`, `helpers.md`, `httpx2.md` and `bedrock.md`, the last two matching the HTTPX2 transport and the AWS extra named in the dependency groups.
Editorial conclusion
Adopt openai-python when you want typed request and response models on Python 3.10 to 3.14 rather than hand-rolled HTTP calls, and pick it over writing your own client because the library is generated from the OpenAPI specification and updates alongside it. Do not pick it if your platform needs Azure with X.509 federation, because that combination is documented as unsupported, or if you need to send provider API-key headers alongside a certificate, which X.509 mode forbids. Verify three things in your own environment before writing the integration: that `pip install openai` resolves `httpx2` and a pydantic version outside the excluded 2.0 to 2.3 range, which extras you need (`realtime` pulls `websockets`, `bedrock` pulls `botocore`), and whether the identity you plan to use needs a client rebuilt rather than reconfigured, since identity settings are captured when the client is constructed.
Frequently asked questions
What is the OpenAI Python library?
It is the official Python client for the OpenAI REST API, generated from the project's OpenAPI specification, with type definitions for all request params and response fields. It offers both synchronous and asynchronous clients powered by HTTPX2 and requires Python 3.10 or newer.
How do I install OpenAI in Python?
From PyPI with pip install openai. The base package brings the core client; realtime, Bedrock, aiohttp, datalib and voice helpers are separate optional dependency groups that have to be named at install time.
How do I use the OpenAI Python API to generate text?
Construct an OpenAI client and call client.responses.create with a model, an instructions string and an input string, then read response.output_text. The Chat Completions equivalent takes a list of role-tagged messages and returns the text at completion.choices[0].message.content.
How do I use Azure OpenAI with the Python library?
The examples directory includes azure.py and azure_ad.py, and the library ships azure_managed_identity_token_provider, which takes a resource argument and fits into the workload_identity block alongside identity_provider_id and service_account_id. Azure clients do not support X.509 workload identity.
Is Python OpenAI free?
The library itself carries the Apache-2.0 licence and installs from PyPI at no cost.
Official sources
Where developers are discussing it
Posts on Hacker News, dev.to and Lobsters that link to this repository, found by our scan of those communities. 1 in the last 30 days; newest first.
- State of AI Instruction Quality: Coding Agent Comparisondev.to · Oct 21, 2026 · 6 points · 0 comments
- Contextual Retrieval in 80 Lines: Anthropic's Chunk-Prefix Trick, Measured on Your Docsdev.to · Oct 15, 2026 · 3 points · 3 comments
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/openai-openai-python)Star history chart for your README
[](https://hysenlabs.com/projects/openai-openai-python)Was this useful?