openai-python: The Official SDK, Its Auth Surface, and Where It Stops
The official Python library for the OpenAI API
At a glance
- What is it?
- The official Python client for the OpenAI REST API is generated from an OpenAPI specification and now carries workload identity authentication for Kubernetes, Azure, and GCP. This covers what it does, how to run it, and which maintenance and licensing questions to settle before adopting it.
- Who is it for?
- Adopt openai-python if your application is Python 3.10 or newer and you want typed request and response definitions for the OpenAI REST API, particularly if you need workload identity authentication on Kubernetes, Azure, or GCP. Do not adopt it if you need a provider-neutral client that talks to several model vendors through one interface, or if you are running Python below 3.10.
- 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 received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What openai-python Is For, and Who It Is Not For
The library provides access to the OpenAI REST API from any Python 3.10 or newer application. That version floor is stated in the README and it is the first thing to check against your environment. The library includes type definitions for all request parameters and response fields, and it offers both synchronous and asynchronous clients powered by HTTPX2. It is generated from the OpenAI OpenAPI specification rather than hand-written, which is the detail that explains most of its behaviour: parameter names, response shapes, and endpoint coverage track the specification, and the generated surface is broad because the specification is broad.
The audience is narrower than the phrase official SDK suggests. This is a client for one vendor's API, not an abstraction layer over several. If your code needs to switch between model providers behind a single interface, this library is the wrong shape for that job, and no configuration flag changes it. If you are on Python 3.9 or earlier, you cannot install and run it as documented. The README also points to api.md as the full API reference, which is where you should look before assuming an endpoint is missing; the README itself only demonstrates a small slice.
Generated From OpenAPI: What That Means in Practice
The README states plainly that the library is generated from the OpenAPI specification hosted at openai/openai-openapi. That single sentence carries a lot of weight. Generated clients tend to have uniform method signatures, consistent error types, and pagination or streaming helpers that follow one pattern across every endpoint, because the generator applies the same template everywhere. The trade-off is that generated code can feel mechanical. Method names mirror the specification rather than any particular developer's taste, and the depth of the response objects means you often index several levels down before reaching the field you want, as the Chat Completions example shows with completion.choices[0].message.content.
The README describes two ways to generate text. The Responses API is presented as the primary API for interacting with OpenAI models. The Chat Completions API is described as the previous standard, supported indefinitely. That word indefinitely matters if you have existing code on chat.completions: the README does not announce a removal, but it does place the two endpoints in different tiers of recommendation. New code written against the examples will use client.responses.create and read response.output_text, which is a flatter access path than the choices array.
Installation and the Two Client Entry Points
Installation is a single command from PyPI: pip install openai. There is no separate extras step documented for the core client.
The README's first example constructs OpenAI with api_key=os.environ.get("OPENAI_API_KEY") and notes that this is the default and can be omitted, meaning the client will read the environment variable on its own. The README recommends python-dotenv so that OPENAI_API_KEY="My API Key" lives in a .env file rather than in source control. That is a documentation-level recommendation, not a library feature: the library reads the environment variable, and dotenv is what populates it during local development.
For concurrent workloads, AsyncOpenAI is the asynchronous counterpart. The README names DefaultAsyncHttpx2Client as the asynchronous HTTP client, and DefaultHttpx2Client as the synchronous one, and the X.509 example shows the synchronous client being passed explicitly through the http_client argument. If you need custom transport behaviour, that argument is where it goes.
Workload Identity: Replacing Long-Lived API Keys
The most substantial piece of the README beyond basic usage is workload identity authentication, aimed at what it calls secure, automated environments such as cloud-managed Kubernetes, Azure, and Google Cloud Platform. The mechanism is short-lived tokens from cloud identity providers instead of long-lived API keys.
The shape of the configuration is consistent across providers. You pass a workload_identity dictionary containing identity_provider_id, service_account_id, and a provider. The provider comes from openai.auth: k8s_service_account_token_provider takes a path to a service account token, azure_managed_identity_token_provider takes a resource URL, and gcp_id_token_provider takes an audience. A custom provider is also supported through a plain dictionary with token_type set to "jwt" and a get_token callable that returns a string.
Token lifetime is managed for you. The README states that refresh_buffer_seconds defaults to 1200 seconds, that is 20 minutes before expiration, and the examples show it being overridden to 120.0. Tokens are exchanged lazily, cached, and refreshed automatically. One constraint is easy to miss: identity settings are captured when the client is constructed, so changing identity means creating a new client. In a long-running process that rotates identities, that detail determines your object lifecycle.
X.509 mTLS and Its Documented Boundaries
X.509 workload identity federation is the most constrained mode, and the README is explicit about the constraints. You configure a client certificate and server trust on an HTTPX2 client, then pass only the identity-provider and service-account IDs to the SDK through x509_workload_identity. The example builds an ssl context with ssl.create_default_context(cafile=...), loads the certificate chain and key, and passes that context as verify to DefaultHttpx2Client with follow_redirects=False.
The boundary list is worth reading twice. X.509 mode defaults to https://mtls.api.openai.com/v1 when neither base_url nor OPENAI_BASE_URL is set. Requests require HTTPS and must stay on the configured API origin, and the effective HTTP Host authority must match that origin. Provider API-key and proxy-only headers cannot be sent to the API alongside X.509 authentication. Token exchanges do not inherit API request hooks, authentication, or cookies. Azure clients do not support X.509 workload identity at all.
The division of responsibility is stated directly: certificate files, private keys, passwords, server trust, proxies, and rotation remain application and transport concerns. The SDK does not manage your certificate lifecycle. If your team expected the library to handle rotation end to end, this is the paragraph that corrects that expectation, and it is the strongest argument for reading the two linked examples, examples/x509_workload_identity.py and examples/x509_workload_identity_async.py, before writing your own setup.
Maintenance Cost and the Apache-2.0 Licence
Release cadence is the maintenance signal visible in the repository metadata. Three releases landed within roughly two days in September 2026: v3.10.0, v3.11.0, and v3.12.0. A fast cadence on a generated client usually means the specification moved rather than that the hand-written surface churned, but either way it sets an expectation: if you pin the version, you will be pinning against a moving target, and if you do not pin, you accept that a minor bump can arrive mid-sprint. The major version is 3.x, so the library has already been through at least two breaking major transitions, which is context for how you treat upgrade notes.
The licence is Apache-2.0. That is a permissive licence that generally allows commercial and closed-source use, modification, and redistribution, and it includes an explicit patent grant. It also carries notice and attribution conditions that apply to redistributed copies. This is a description of the licence text, not legal advice; if you redistribute the library or a modified version of it, have your own counsel confirm what notices you must carry.
One maintenance cost is specific to this library's design. Because it is generated from the OpenAPI specification and covers the full REST surface, the type definitions for request parameters and response fields are extensive. That is the feature. It is also the upgrade cost, since a specification change can ripple through types your code depends on.
Choosing Between openai-python and a Provider-Neutral Client
The real alternative for many teams is not another OpenAI client but a provider-neutral library that presents one interface over several vendors' APIs. The difference in approach is structural, not cosmetic. openai-python is generated from a single vendor's OpenAPI specification, so its method signatures, response objects, and authentication modes map one to one onto that vendor's REST surface. The workload identity section is the clearest illustration: k8s_service_account_token_provider, azure_managed_identity_token_provider, and gcp_id_token_provider exist because the OpenAI API accepts federated cloud identities, and the X.509 mode defaults to a specific OpenAI mTLS host.
A provider-neutral client would abstract those away behind a common authentication parameter, and in doing so it would have to flatten the parts of the API that do not have equivalents elsewhere. You would gain portability and lose the direct mapping to the specification, including the typed request and response definitions that this library is built around. The decision is therefore about whether provider portability is a requirement or a preference. If it is a preference and you are committed to the OpenAI API, the generated client gives you closer alignment with the specification and with each release. If it is a requirement, this library will not satisfy it, and no amount of configuration changes that.
Editorial conclusion
Adopt openai-python if your application is Python 3.10 or newer and you want typed request and response definitions for the OpenAI REST API, particularly if you need workload identity authentication on Kubernetes, Azure, or GCP. Do not adopt it if you need a provider-neutral client that talks to several model vendors through one interface, or if you are running Python below 3.10. Before committing, verify your installed Python version, confirm that your deployment can supply short-lived tokens through one of the supported providers, and read the X.509 section of the README if you plan to use mutual TLS, because Azure clients do not support that mode and identity settings are captured at client construction time.
Community notes