Follow AiTechWorlds on LinkedIn for professional AI content!Follow Now →
20 minLesson 28 of 34
Python for AI

Using the OpenAI API

Using the OpenAI API in Python

The OpenAI API gives you access to GPT-4o, DALL-E, and Whisper — building intelligence directly into your Python applications. This lesson covers everything from your first API call to building production-ready AI features.

Setup

# pip install openai python-dotenv
from openai import OpenAI
from dotenv import load_dotenv
import os

load_dotenv()  # Load API key from .env file

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# NEVER hardcode API keys in your code

Basic Text Generation

# Simple completion
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "You are a helpful Python tutor."},
        {"role": "user", "content": "Explain list comprehensions in 3 sentences."}
    ],
    temperature=0.7,     # 0 = deterministic, 1 = creative
    max_tokens=300
)

answer = response.choices[0].message.content
print(answer)

# Cost tracking
print(f"Input tokens: {response.usage.prompt_tokens}")
print(f"Output tokens: {response.usage.completion_tokens}")
print(f"Total: {response.usage.total_tokens}")

Multi-Turn Conversations

class Conversation:
    def __init__(self, system_prompt, model="gpt-4o"):
        self.model = model
        self.messages = [{"role": "system", "content": system_prompt}]
    
    def chat(self, user_message, temperature=0.7):
        self.messages.append({"role": "user", "content": user_message})
        
        response = client.chat.completions.create(
            model=self.model,
            messages=self.messages,
            temperature=temperature
        )
        
        assistant_message = response.choices[0].message.content
        self.messages.append({"role": "assistant", "content": assistant_message})
        
        return assistant_message
    
    def reset(self, keep_system=True):
        if keep_system:
            self.messages = [self.messages[0]]
        else:
            self.messages = []

# Interactive chatbot
conv = Conversation("You are an expert Python developer. Be concise.")
print(conv.chat("What's the difference between a list and a tuple?"))
print(conv.chat("When would I use a tuple instead?"))
print(conv.chat("Give me a quick example."))

Structured Outputs: JSON Mode

import json

def extract_product_info(description: str) -> dict:
    """Extract structured product data from free text."""
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {
                "role": "system",
                "content": """Extract product information and return ONLY valid JSON with these fields:
                {
                    "name": "product name",
                    "price": number or null,
                    "category": "category string",
                    "features": ["list", "of", "features"],
                    "available": true/false
                }"""
            },
            {"role": "user", "content": description}
        ],
        response_format={"type": "json_object"},  # Forces JSON output
        temperature=0
    )
    
    return json.loads(response.choices[0].message.content)

result = extract_product_info("""
    The MacBook Pro 14-inch features Apple M3 chip, 16GB RAM, 
    and 512GB storage. Currently available for $1,599.
""")
print(result)
# {'name': 'MacBook Pro 14-inch', 'price': 1599, 'category': 'Laptop',
#  'features': ['Apple M3 chip', '16GB RAM', '512GB storage'], 'available': True}

Function Calling / Tool Use

import json

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_stock_price",
            "description": "Get the current stock price for a company ticker symbol",
            "parameters": {
                "type": "object",
                "properties": {
                    "ticker": {
                        "type": "string",
                        "description": "Stock ticker symbol e.g. AAPL, MSFT"
                    }
                },
                "required": ["ticker"]
            }
        }
    }
]

def get_stock_price(ticker: str) -> dict:
    """Mock stock price lookup."""
    mock_prices = {"AAPL": 185.50, "MSFT": 420.30, "GOOGL": 150.25}
    price = mock_prices.get(ticker.upper())
    if price:
        return {"ticker": ticker, "price": price, "currency": "USD"}
    return {"error": f"Unknown ticker: {ticker}"}

def run_with_tools(user_message: str) -> str:
    messages = [{"role": "user", "content": user_message}]
    
    while True:
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools,
            tool_choice="auto"
        )
        
        choice = response.choices[0]
        messages.append(choice.message)
        
        if choice.finish_reason == "stop":
            return choice.message.content
        
        # Process tool calls
        for tool_call in choice.message.tool_calls:
            args = json.loads(tool_call.function.arguments)
            result = get_stock_price(**args)
            
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result)
            })

print(run_with_tools("What's the current price of Apple and Microsoft stock?"))

Streaming Responses

def stream_response(prompt: str):
    """Stream tokens as they're generated — better UX for long responses."""
    stream = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}],
        stream=True
    )
    
    full_response = ""
    for chunk in stream:
        if chunk.choices[0].delta.content is not None:
            content = chunk.choices[0].delta.content
            print(content, end='', flush=True)  # Print as it arrives
            full_response += content
    
    print()  # New line at end
    return full_response

stream_response("Write a haiku about Python programming.")

Image Generation with DALL-E

def generate_image(prompt: str, size="1024x1024", quality="standard") -> str:
    """Generate an image and return the URL."""
    response = client.images.generate(
        model="dall-e-3",
        prompt=prompt,
        size=size,
        quality=quality,
        n=1
    )
    return response.data[0].url

url = generate_image("A Python snake writing code on a laptop, digital art style")
print(f"Image URL: {url}")

Audio Transcription with Whisper

def transcribe_audio(audio_path: str, language="en") -> str:
    """Transcribe audio file to text."""
    with open(audio_path, 'rb') as audio_file:
        transcript = client.audio.transcriptions.create(
            model="whisper-1",
            file=audio_file,
            language=language
        )
    return transcript.text

text = transcribe_audio("meeting_recording.mp3")
print(text)

Error Handling and Rate Limits

from openai import RateLimitError, APIError, APIConnectionError
import time

def resilient_api_call(messages, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.chat.completions.create(
                model="gpt-4o",
                messages=messages
            )
        
        except RateLimitError:
            wait = 2 ** attempt * 5  # Exponential backoff: 5s, 10s, 20s
            print(f"Rate limited. Waiting {wait}s...")
            time.sleep(wait)
        
        except APIConnectionError as e:
            print(f"Connection error: {e}. Retrying...")
            time.sleep(2 ** attempt)
        
        except APIError as e:
            if e.status_code >= 500:  # Server error — retry
                time.sleep(2 ** attempt)
            else:
                raise  # Client error (400-499) — don't retry
    
    raise Exception(f"API call failed after {max_retries} attempts")

Next lesson: Using the Anthropic Claude API — working with Claude's unique capabilities.

📱

Get this course's notes on Telegram!

Free cheat sheets, summaries & practice exercises

Get Notes Free →
!