The OpenAI Python SDK (openai on PyPI) is the official Python client for OpenAI’s API. It handles authentication, request formatting, response parsing, streaming, and retries — so you don’t have to implement those yourself. This guide covers installation, the core OpenAI class, chat completions, streaming, function calling, async usage, the JavaScript SDK equivalent, Azure OpenAI integration, and how to point the same SDK at Novita AI’s OpenAI-compatible endpoint to use open-weight models without rewriting your code.
Install the OpenAI Python Package
Python 3.8 or later is required:
pip install openai
For development, add it to your requirements.txt or pyproject.toml:
pip install openai>=1.0.0
The 1.x release (shipped in late 2023) changed the interface significantly from the 0.x API. If you are migrating older code, note that openai.ChatCompletion.create() is gone; use client.chat.completions.create() instead.
Set your API key as an environment variable. Do not put it in source code:
export OPENAI_API_KEY="sk-..."
The OpenAI Client Class
The OpenAI class is the main entry point. It reads the API key from the OPENAI_API_KEY environment variable by default, or you can pass it explicitly:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["OPENAI_API_KEY"],
)
The client manages connection pooling, retries, and timeouts. You should create one instance and reuse it across your application, not instantiate it per request.
Configurable options at initialization:
| Parameter | Default | Description |
|---|---|---|
api_key | OPENAI_API_KEY env var | Authentication credential |
base_url | https://api.openai.com/v1 | Override for proxy or compatible API |
timeout | 600s | Per-request timeout |
max_retries | 2 | Automatic retries on rate limit errors |
http_client | None | Custom httpx client for proxy or cert configuration |
Chat Completions: Basic Request
Chat completions are the most common use case. The messages list follows the same format as the API: a list of role/content dicts representing the conversation:
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "You are a helpful coding assistant."},
{"role": "user", "content": "What is the difference between a list and a tuple in Python?"},
],
temperature=0.3,
max_tokens=512,
)
print(response.choices[0].message.content)
The response is a ChatCompletion object. Key fields:
response.choices[0].message.content— the text responseresponse.usage.prompt_tokens— tokens consumed by the inputresponse.usage.completion_tokens— tokens consumed by the outputresponse.model— the model version that served the request
For production use, pass max_tokens to avoid runaway generation costs and temperature=0 or low values when you need deterministic outputs.
Streaming Responses
For interactive interfaces where users see tokens as they arrive, use stream=True:
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
with client.chat.completions.stream(
model="gpt-4o",
messages=[
{"role": "user", "content": "Explain Python generators in plain language."},
],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Using the context manager (with statement) ensures the connection is properly closed after iteration. The .text_stream attribute yields plain strings; .stream yields raw event objects if you need metadata like usage stats per chunk.
If you need streaming without a context manager:
stream = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "List 5 Python best practices."}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta
if delta.content:
print(delta.content, end="", flush=True)
Function Calling
Function calling lets the model decide when to call a function and return a JSON argument object. Your application executes the function, then sends the result back for the model to incorporate into its response:
import os
import json
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Returns current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name, e.g. 'San Francisco'",
}
},
"required": ["city"],
},
},
}
]
messages = [{"role": "user", "content": "What's the weather in Tokyo?"}]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto",
)
choice = response.choices[0]
if choice.finish_reason == "tool_calls":
tool_call = choice.message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
# Execute your actual function here
result = {"city": args["city"], "temperature": "18°C", "condition": "cloudy"}
messages.append(choice.message)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result),
})
final = client.chat.completions.create(
model="gpt-4o",
messages=messages,
)
print(final.choices[0].message.content)
The model returns finish_reason="tool_calls" when it wants to invoke a function. You run the function, add the result to the messages list, and make a second request. This two-step loop is the standard pattern.
Async Usage with AsyncOpenAI
For FastAPI, asyncio-based services, or any code that benefits from non-blocking I/O, use AsyncOpenAI:
import os
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI(api_key=os.environ["OPENAI_API_KEY"])
async def get_response(prompt: str) -> str:
response = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
max_tokens=256,
)
return response.choices[0].message.content
async def main():
result = await get_response("What is asyncio in Python?")
print(result)
asyncio.run(main())
AsyncOpenAI is a drop-in async counterpart; all methods are awaitable. This is preferable to using asyncio.to_thread to wrap the sync client.
OpenAI JavaScript SDK
The OpenAI JavaScript SDK (openai on npm) mirrors the Python interface closely. Install it:
npm install openai
Basic chat completion in Node.js:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const response = await client.chat.completions.create({
model: "gpt-4o",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Explain promises vs async/await in JavaScript." },
],
max_tokens: 512,
});
console.log(response.choices[0].message.content);
Streaming in JavaScript:
import OpenAI from "openai";
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const stream = await client.chat.completions.stream({
model: "gpt-4o",
messages: [{ role: "user", content: "Summarize the fetch API in 3 sentences." }],
});
for await (const chunk of stream) {
const text = chunk.choices[0]?.delta?.content ?? "";
process.stdout.write(text);
}
The JavaScript SDK supports Node.js 18+, Deno, and browser environments (though exposing your API key in the browser is unsafe — use a server-side proxy instead). The base_url option for pointing to compatible APIs works exactly as in Python.
Azure OpenAI Python Integration
If you are using the Azure OpenAI service rather than the direct OpenAI API, use the AzureOpenAI client from the same package:
import os
from openai import AzureOpenAI
client = AzureOpenAI(
api_key=os.environ["AZURE_OPENAI_API_KEY"],
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_version="2024-02-01",
)
response = client.chat.completions.create(
model="gpt-4o", # Your deployment name in Azure
messages=[
{"role": "user", "content": "How do I use Azure OpenAI with Python?"},
],
)
print(response.choices[0].message.content)
Required environment variables for Azure:
AZURE_OPENAI_API_KEY: Your Azure resource API keyAZURE_OPENAI_ENDPOINT: Your endpoint URL, e.g.https://your-resource.openai.azure.com/
The model parameter in Azure OpenAI refers to your deployment name, not the underlying model name. Set api_version to match the Azure API version your deployment uses (check the Azure OpenAI documentation for current supported versions).
For authentication via Microsoft Entra ID (formerly Azure AD) instead of an API key:
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from openai import AzureOpenAI
token_provider = get_bearer_token_provider(
DefaultAzureCredential(),
"https://cognitiveservices.azure.com/.default",
)
client = AzureOpenAI(
azure_ad_token_provider=token_provider,
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_version="2024-02-01",
)
Switch to Novita AI’s OpenAI-Compatible API
Novita AI exposes an OpenAI-compatible endpoint at https://api.novita.ai/openai. You can use the same openai Python or JavaScript SDK, changing only the base_url and api_key. No other code changes are required:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["NOVITA_API_KEY"],
base_url="https://api.novita.ai/openai",
)
response = client.chat.completions.create(
model="deepseek/deepseek-v4-pro",
messages=[
{"role": "system", "content": "You are a helpful coding assistant."},
{"role": "user", "content": "Explain how Python's GIL affects multithreading."},
],
temperature=0.3,
max_tokens=512,
)
print(response.choices[0].message.content)
Get a Novita AI API key from novita.ai/settings/key-management. The same key works across all Novita AI APIs including the OpenAI-compatible endpoint.
JavaScript with Novita AI:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.NOVITA_API_KEY,
baseURL: "https://api.novita.ai/openai",
});
const response = await client.chat.completions.create({
model: "qwen/qwen3-coder-30b-a3b-instruct",
messages: [{ role: "user", content: "Write a Python type annotation cheatsheet." }],
max_tokens: 600,
});
console.log(response.choices[0].message.content);
Everything downstream — streaming, function calling, async usage, response_format, temperature, max_tokens — works identically. The Novita AI endpoint follows the OpenAI Chat Completions API spec.
Open-Source Models via Novita AI
Swapping base_url gives you access to a catalog of open-weight models that are now competitive with closed-source frontiers on specific tasks. For coding workflows, function calling, and long-context reasoning, the practical gap has narrowed substantially.
Models available through Novita AI’s OpenAI-compatible endpoint that are worth evaluating:
DeepSeek V4 Pro (deepseek/deepseek-v4-pro): A large MoE model (MIT-adjacent license) that ranks near the top of SWE-Bench and function-calling benchmarks. Strong for coding agents, code review, and multi-step tool-use tasks where you’d otherwise reach for GPT-4o or Claude Opus.
Qwen3 Coder 30B A3B Instruct (qwen/qwen3-coder-30b-a3b-instruct): A 30B sparse MoE model from the Qwen Coder family, optimized for code generation, bug triage, and pull-request review. At $0.07 per 1M input tokens and $0.27 per 1M output tokens on Novita AI, it is substantially cheaper than most closed APIs for routine coding assistance.
Qwen3 235B A22B Instruct (qwen/qwen3-235b-a22b-instruct-2507): A large MoE model (Apache 2.0) with strong reasoning and multilingual coding performance. Good for tasks where you currently use GPT-4o for creative or complex responses but want to reduce per-token cost at volume.
The model ID format on Novita AI is provider/model-name. You pass it directly to the model parameter in the SDK.
A straightforward routing pattern for teams that want to mix open and closed models:
def get_client(use_novita: bool = False) -> OpenAI:
if use_novita:
return OpenAI(
api_key=os.environ["NOVITA_API_KEY"],
base_url="https://api.novita.ai/openai",
)
return OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# Use open-weight for cost-sensitive, high-volume coding tasks
coding_client = get_client(use_novita=True)
# Use OpenAI for tasks where the closed model is genuinely better
openai_client = get_client(use_novita=False)
This lets you A/B test output quality, benchmark per-task performance, and shift volume to cheaper models without touching request logic.
FAQ
What is the OpenAI Python package name?
The package name on PyPI is openai. Install with pip install openai.
What is the OpenAI client Python class called?
The main class is OpenAI for synchronous usage and AsyncOpenAI for async usage. Both are in the openai module: from openai import OpenAI, AsyncOpenAI.
Does the OpenAI Python SDK support streaming?
Yes. Use client.chat.completions.stream() as a context manager, or pass stream=True to client.chat.completions.create() and iterate over the chunks.
What is the OpenAI JavaScript SDK package name?
The npm package is openai. Install with npm install openai. The class and method signatures are nearly identical to the Python SDK.
How do I use Azure OpenAI with Python?
Use the AzureOpenAI class from the openai package. Pass azure_endpoint, api_key, and api_version. The model parameter refers to your Azure deployment name, not the underlying model.
Can I use the OpenAI Python SDK with other providers?
Yes. Any provider that implements the OpenAI Chat Completions API format can be used by setting base_url on the client. Novita AI’s endpoint at https://api.novita.ai/openai is one example; the full SDK feature set — streaming, function calling, async — works without changes.
How do I keep my OpenAI API key secure?
Store the key in an environment variable (OPENAI_API_KEY) and read it with os.environ["OPENAI_API_KEY"]. Never put it in source code, public repositories, build logs, or client-side JavaScript.
Recommended Articles
- Novita AI Now Supports OpenAI Agents SDK! — Connect Novita AI models to the OpenAI Agents SDK for multi-agent orchestration, guardrails, and tracing.
- Qwen3 Coder 30B A3B Instruct Quick Start — Model ID, pricing, context window, and API examples for this cost-effective coding model on Novita AI.
- Vercel AI SDK: Complete Developer Guide for Building AI Applications — Use the Vercel AI SDK with Novita AI’s OpenAI-compatible endpoint for streaming, tool calls, and agent loops in TypeScript.
