Skip to content

OpenAI Python SDK: Complete Guide โ€‹

๐Ÿš€ ย  Launch interactive mode!

Ready to play? Fire up the playground and test it live!

๐Ÿ‘จโ€๐Ÿ’ป Author: Mohankumar Ramachandran

Welcome to your all-in-one, hands-on OpenAI Python SDK tutorial!
Whether youโ€™re just starting out or want to master the latest features, this notebook has you covered.

Youโ€™ll learn, with easy-to-run code:

  • ๐Ÿ”‘ Setup & Install โ€“ Get your API key, install the SDK
  • ๐Ÿ“ Text Generation โ€“ Write stories & answers
  • ๐Ÿ—ฃ๏ธ Chat Roles & Memory โ€“ Custom assistants, multi-turn chat
  • ๐Ÿ–ผ๏ธ Vision โ€“ Analyze images (URLs & files)
  • โšก Streaming โ€“ Real-time responses
  • ๐Ÿ› ๏ธ Function Calling โ€“ Let AI use your Python tools
  • ๐Ÿ“ฆ Structured Output โ€“ Get responses as Python objects
  • ๐Ÿ”ข Embeddings โ€“ Turn text into vectors

Ready to build smarter, richer AI apps? Letโ€™s dive in! ๐ŸŽ‰

Setup Model API key โ€‹

Run the next cell to setup a free OpenAI API key using your GitHub account, or use your own OpenAI API key.

Note: May not work for enterprise GitHub accounts due to company-specific policies.

py
# NOTE: Set support_with_star to False if you do not want to support our work yet.
from foreverpython import init_github_models

# Run below if you already have your own OpenAI API key
# import os
# os.environ["OPENAI_API_KEY"] = "sk-..."

# else, run below to setup a free GitHub Models API key using your GitHub account.
await init_github_models(use_browser_cache=True, support_with_star=True)

Install OpenAI SDK โ€‹

First, let's install the official OpenAI Python package so you can access all the latest features and models! ๐Ÿ“ฆโœจ

py
# Install the OpenAI Python SDK
%pip install openai==1.93.0

Text Generation โ€‹

Generating text with OpenAI is super easy! ๐Ÿ“โœจ You can use the API to write stories, answer questions, or just have fun. Below is a simple example that sends a prompt and gets a creative response.

py
# Generate a one-sentence bedtime story using OpenAI
from openai import OpenAI
from openai.types.chat import ChatCompletionUserMessageParam

# Create an OpenAI client to interact with the API
openai_client = OpenAI()

# Create a chat completion (text generation) request
bedtime_story_response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",  # Pick a small, fast model
    messages=[
        ChatCompletionUserMessageParam(
            role="user", content="Write a one-sentence bedtime story about a unicorn."
        )
    ],
)

# Print the generated story ๐Ÿฆ„โœจ
print(bedtime_story_response.choices[0].message.content)

Chat Roles โ€‹

With OpenAI chat models, you can set different roles to control your assistant's behavior! ๐Ÿ—ฃ๏ธ For example, you can make it act like a pirate, a helpful friend, or a professional developer. Roles like system, user, or even developer help guide the conversation.

py
# Example: Setting custom roles in conversation
from openai import OpenAI
from openai.types.chat import ChatCompletionDeveloperMessageParam
from openai.types.chat import ChatCompletionUserMessageParam

# Create OpenAI client
openai_client = OpenAI()

# Define a conversation where the assistant talks like a pirate!
pirate_chat_response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=[
        # Set behavior of the assistant to talk like a pirate
        ChatCompletionDeveloperMessageParam(
            role="developer", content="Talk like a pirate."
        ),
        # Add question from the user to the conversation
        ChatCompletionUserMessageParam(
            role="user", content="Are semicolons optional in JavaScript?"
        ),
    ],
)

# Print the pirate-themed answer โ˜ ๏ธ
print(pirate_chat_response.choices[0].message.content)

Conversation Context โ€‹

Want your chatbot to remember what was said earlier? Since OpenAI chat models can handle multiple messages, you can pass a list of messages to keep the conversation flowing naturally! ๐Ÿ—จ๏ธ๐Ÿ”

py
# Keep track of chat history for multi-turn conversations
from openai import OpenAI
from typing import List, cast
from openai.types.chat import ChatCompletionUserMessageParam
from openai.types.chat import ChatCompletionMessageParam
from openai.types.chat import ChatCompletionAssistantMessageParam

# Create OpenAI client
openai_client = OpenAI()

# Start conversation history with the user's first message
conversation_history: List[ChatCompletionMessageParam] = [
    ChatCompletionUserMessageParam(role="user", content="tell me a joke")
]

# First response from the assistant
first_joke_response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=conversation_history,
)

# Extract the assistant's message from the response
first_joke_response_message = first_joke_response.choices[0].message

print("=" * 50 + "\n## First Response:\n")
print(first_joke_response_message.content)
print("=" * 50, "\n")

# Add the assistant's reply and a new user prompt to the history
conversation_history.append(
    cast(ChatCompletionAssistantMessageParam, first_joke_response_message.model_dump())
)
conversation_history.append(
    ChatCompletionUserMessageParam(role="user", content="tell me another")
)

# Second response (model remembers the context!)
second_joke_response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=conversation_history,
)

print("=" * 50 + "\n## Second Response:\n")
print(second_joke_response.choices[0].message.content)
print("=" * 50)

Image Analysis โ€‹

You can ask OpenAI models about images by sending them a URL! ๐Ÿ–ผ๏ธ๐Ÿค– This is perfect for describing photos, recognizing objects, or even reading text from images (OCR).

py
# Analyze an image from a URL with OpenAI Vision
from openai import OpenAI
from openai.types.chat import ChatCompletionContentPartImageParam
from openai.types.chat import ChatCompletionUserMessageParam
from openai.types.chat import ChatCompletionContentPartTextParam

# Create OpenAI client
openai_client = OpenAI()

# Send an image URL and ask "What's in this image?"
vision_response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=[
        ChatCompletionUserMessageParam(
            role="user",
            content=[
                ChatCompletionContentPartTextParam(
                    type="text", text="What's in this image?"
                ),
                ChatCompletionContentPartImageParam(
                    type="image_url",
                    image_url={
                        "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg",
                    },
                ),
            ],
        ),
    ],
)

# Print the AI's description ๐ŸŒณ๐Ÿฆ†
print(vision_response.choices[0].message.content)

File Image Input โ€‹

You can also upload images (or even PDFs!) directly from your computer. ๐Ÿ“ Just encode your image as Base64 and send it to the API. This is handy if your image isn't available online.

py
# Analyze a local image by encoding it as Base64
import base64
from openai import OpenAI
from openai.types.chat import ChatCompletionContentPartImageParam
from openai.types.chat import ChatCompletionUserMessageParam
from openai.types.chat import ChatCompletionContentPartTextParam

# Create OpenAI client
openai_client = OpenAI()

# Specify your local image file path here
local_image_path = "./sample_data/green_pathway.jpg"

# Encode the image as Base64
with open(local_image_path, "rb") as image_file:
    base64_image_str = base64.b64encode(image_file.read()).decode("utf-8")

# Send the image to the model for analysis
image_analysis_response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=[
        ChatCompletionUserMessageParam(
            role="user",
            content=[
                ChatCompletionContentPartTextParam(
                    type="text", text="What's in this image?"
                ),
                ChatCompletionContentPartImageParam(
                    type="image_url",
                    image_url={
                        "url": f"data:image/jpeg;base64,{base64_image_str}",
                    },
                ),
            ],
        ),
    ],
)

# Print the AI's answer! ๐Ÿ–ผ๏ธ๐Ÿ”
print(image_analysis_response.choices[0].message.content)

Streaming Output โ€‹

Want your app to feel lightning fast? โšก Try streaming responses! With streaming, you can see the output as it's being generatedโ€”perfect for chatbots and dynamic UIs.

py
# Stream a long OpenAI chunk by chunk
from openai import OpenAI
from openai.types.chat import ChatCompletionUserMessageParam

# Create OpenAI client
openai_client = OpenAI()

# Start a streaming chat completion for a longer prompt
streamed_story = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=[
        ChatCompletionUserMessageParam(
            role="user",
            content="Write me a big story about `Attention Is All You Need` research paper",
        ),
    ],
    stream=True,  # Enable streaming!
)

# Print each chunk as it arrives, for a real-time feel ๐Ÿ’จ
for response_chunk in streamed_story:
    if len(response_chunk.choices) and response_chunk.choices[0].delta.content:
        print(response_chunk.choices[0].delta.content, end="", flush=True)

Tool / Function Calling โ€‹

Tool calling lets your AI assistant use your own Python functions as tools! ๐Ÿ› ๏ธ This means you can dramatically increase what your model can do.

  • Fetch real data, like the current weather or stock prices
  • Perform live calculations
  • Connect to APIs or extend your assistant with any Python logic you need

๐Ÿฅ‡ Method 1: Define a Tool using JSON Schema โ€‹

You can define a tool for the model directly using a JSON schema. This is great when you want to specify the parameters and their types in a standard way.

When to use: If you want a quick and flexible way to define tool inputs and outputs.

py
# Import required libraries for tool calling
from openai import OpenAI
from openai.types.chat import ChatCompletionUserMessageParam, ChatCompletionToolParam

# Create an OpenAI client
openai_client = OpenAI()

# Define a tool using JSON schema for a weather function
weather_tool_schema = ChatCompletionToolParam(
    type="function",
    function={
        "name": "get_weather",
        "description": "Get current temperature for provided coordinates in celsius.",
        "parameters": {
            "type": "object",
            "properties": {
                "latitude": {
                    "type": "number",
                    "description": "Latitude of the location to get weather for.",
                },
                "longitude": {
                    "type": "number",
                    "description": "Longitude of the location to get weather for.",
                },
            },
            "required": ["latitude", "longitude"],
            "additionalProperties": False,
        },
        "strict": True,
    },
)

# Use the tool with the model
response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=[
        ChatCompletionUserMessageParam(
            role="user",
            content="What's the weather like in Bangalore today and its air quality?",
        )
    ],
    tools=[weather_tool_schema],
)

# Print the model's tool call response
response.choices[0].message.tool_calls

๐Ÿฅˆ Method 2: Define a Tool using Pydantic Models โ€‹

You can also define tools using Pydantic models, which gives you automatic input validation and clear documentation for your tool's inputs.

When to use: If your tool requires strong type safety or you want to leverage Pydantic's validation features.

py
# Import required libraries for tool calling with Pydantic
from openai import OpenAI, pydantic_function_tool
from pydantic import BaseModel, Field
from openai.types.chat import ChatCompletionUserMessageParam

# Create an OpenAI client
openai_client = OpenAI()


# Define a Pydantic schema for the weather tool
class WeatherToolSchema(BaseModel):
    """Get current temperature for provided coordinates in celsius."""

    latitude: float = Field(
        ..., description="Latitude of the location to get weather for."
    )
    longitude: float = Field(
        ..., description="Longitude of the location to get weather for."
    )


# Register this Pydantic model as a tool
weather_tool_schema = pydantic_function_tool(WeatherToolSchema, name="get_weather")

# Use the tool with the model
response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=[
        ChatCompletionUserMessageParam(
            role="user",
            content="What's the weather like in Bangalore today and its air quality?",
        )
    ],
    tools=[weather_tool_schema],
)

# Print the model's tool call response
response.choices[0].message.tool_calls

Tool Invocation โ€‹

Let's put it all together! We'll define a tool, let the model decide when to call it, and show how you can execute the tool call and return the result to the model.

This is how you enable your AI assistant to fetch real data in a live, multi-step conversation.

py
# Import necessary libraries
import httpx
import json
from openai import OpenAI, pydantic_function_tool
from pydantic import BaseModel, Field
from typing import List, cast
from openai.types.chat import (
    ChatCompletionUserMessageParam,
    ChatCompletionAssistantMessageParam,
    ChatCompletionMessageParam,
    ChatCompletionToolMessageParam,
)

# Create the OpenAI client
openai_client = OpenAI()

# Maintain the conversation history
message_history: List[ChatCompletionMessageParam] = [
    ChatCompletionUserMessageParam(
        role="user",
        content="What's the weather like in Bangalore today and its air quality?",
    )
]


# Define a function to call the Open-Meteo weather API
def get_weather(latitude, longitude):
    """
    Calls Open-Meteo weather API to fetch the current temperature for given coordinates.
    """
    with httpx.Client() as client:
        response = client.get(
            "https://api.open-meteo.com/v1/forecast",
            params={
                "longitude": longitude,
                "latitude": latitude,
                "current": "temperature_2m,wind_speed_10m",
                "hourly": "temperature_2m,relative_humidity_2m,wind_speed_10m",
            },
        )
    return response.json()["current"]["temperature_2m"]


# Define the Pydantic tool schema
class WeatherToolSchema(BaseModel):
    """Get current temperature for provided coordinates in celsius."""

    latitude: float = Field(
        ..., description="Latitude of the location to get weather for."
    )
    longitude: float = Field(
        ..., description="Longitude of the location to get weather for."
    )


# Register the tool with OpenAI
weather_tool_schema = pydantic_function_tool(WeatherToolSchema, name="get_weather")

# Step 1: Ask the model to select and call the right tool
tool_call_response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=message_history,
    tools=[weather_tool_schema],
)

# Step 2: Add the assistant's tool call to the conversation history
message_history.append(
    cast(
        ChatCompletionAssistantMessageParam,
        tool_call_response.choices[0].message.model_dump(),
    ),
)

# Step 3: Execute the tool function and add the result as a tool message
for tool_call in tool_call_response.choices[0].message.tool_calls or []:
    params = json.loads(tool_call.function.arguments)
    tool_result = get_weather(params["latitude"], params["longitude"])
    message_history.append(
        ChatCompletionToolMessageParam(
            role="tool",
            tool_call_id=tool_call.id,
            content=str(tool_result),
        ),
    )

# Step 4: Let the model summarize and use the tool result in its final answer
final_response = openai_client.chat.completions.create(
    model="openai/gpt-4.1-mini",
    messages=message_history,
    tools=[weather_tool_schema],
)

# Print the assistant's final answer using real API data โ˜€๏ธ๐ŸŒก๏ธ
print(final_response.choices[0].message.content)

Structured Output โ€‹

Did you know you can get responses as structured Python objects, not just plain text? ๐Ÿ˜ This is extremely useful for extracting data, facts, or step-by-step answers! OpenAI uses Pydantic for easy data validation.

py
# Get step-by-step math reasoning as structured output
from pydantic import BaseModel
from openai import OpenAI
from openai.types.chat import ChatCompletionSystemMessageParam
from openai.types.chat import ChatCompletionUserMessageParam

# Create OpenAI client
openai_client = OpenAI()


# Define Pydantic classes for the expected output
class SolutionStep(BaseModel):
    output: str
    explanation: str


class MathProblemSolution(BaseModel):
    steps: list[SolutionStep]
    final_answer: str


# Send a message and specify the response format
structured_response = openai_client.chat.completions.parse(
    model="openai/gpt-4.1-mini",
    messages=[
        ChatCompletionSystemMessageParam(
            role="system",
            content="You are a helpful math tutor. Guide the user through the solution step by step.",
        ),
        ChatCompletionUserMessageParam(
            role="user", content="how can I solve 8x + 7 = -23"
        ),
    ],
    response_format=MathProblemSolution,
)

# Access the parsed structured response
solution = structured_response.choices[0].message.parsed

# Check if we got a valid solution and print the steps
if solution:
    # Print each step
    for step_number, step in enumerate(solution.steps, 1):
        print(f"Step {step_number}")
        print(f"Explanation: {step.explanation}")
        print(f"Output: {step.output}\n")

    # Show the final answer ๐Ÿงฎ
    print("Final Answer:\n" + solution.final_answer)
else:
    print("No solution found. Please try a different problem.")

Embeddings Generation โ€‹

Want to turn text into numerical vectors? ๐Ÿงฎ OpenAI's embeddings let you do just that! This is great for tasks like semantic search, clustering, and more. Embeddings are like fingerprints for your text, making it easier to find similar content or group related ideas.

py
from openai import OpenAI

# Create OpenAI client
openai_client = OpenAI()

# Generate embeddings for a list of text inputs
inputs = [
    "The weather is sunny and warm today.",
    "Python is a popular programming language for data science.",
    "How do I bake a chocolate cake from scratch?",
    "Artificial intelligence will change the future of work.",
    "The capital of France is Paris.",
    "Can you recommend a good book to read?",
    "I love hiking in the mountains during autumn.",
    "The quick brown fox jumps over the lazy dog.",
    "Customer support response time is critical for satisfaction.",
    "She solved the math problem in just a few seconds.",
]

# Send in inputs as batch to the embeddings API
response = openai_client.embeddings.create(input=inputs, model="text-embedding-3-small")

# Print the embeddings for each input and show the first few values
for idx, embedding in enumerate(response.data):
    print(f"Input {idx+1}: {inputs[idx]}")
    print(f"Embedding: {embedding.embedding[:3]}...\n")

Acknowledgements โ€‹

๐Ÿ’ก If you found this guide helpful, consider exploring the official docs and community resources below for deeper learning and up-to-date best practices!

Content and inspiration for this guide were drawn from the following resources: