featured image

Integrating OpenAI API into Your Applications

Learn how to integrate OpenAI's GPT models into your applications with best practices for prompt engineering, error handling, and cost optimization.

Published

Sun Sep 15 2024

Technologies Used

OpenAI GPT-4 API Integration
Advanced 45 minutes

Introduction

OpenAI’s API provides powerful language models that can enhance your applications with natural language understanding and generation capabilities. This tutorial covers everything you need to know to integrate OpenAI’s API effectively.

Prerequisites

  • Python 3.8 or higher
  • Basic understanding of REST APIs
  • OpenAI API key (get one here)

Setup

First, install the OpenAI Python library:

pip install openai

Set up your API key as an environment variable:

export OPENAI_API_KEY='your-api-key-here'

Basic Usage

Here’s a simple example to get started:

from openai import OpenAI
import os

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

response = client.chat.completions.create(
    model="gpt-4-turbo-preview",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain quantum computing in simple terms."}
    ]
)

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

Prompt Engineering Best Practices

1. Be Specific and Clear

Bad prompt:

"Write code"

Good prompt:

"""Write a Python function that takes a list of integers and returns 
the sum of all even numbers. Include error handling for invalid inputs 
and add docstring documentation."""

2. Use System Messages Effectively

The system message sets the behavior and context:

messages = [
    {
        "role": "system", 
        "content": """You are an expert Python developer who writes clean, 
        well-documented code following PEP 8 standards. Always include 
        type hints and comprehensive docstrings."""
    },
    {
        "role": "user", 
        "content": "Create a function to validate email addresses"
    }
]

3. Provide Examples (Few-Shot Learning)

messages = [
    {"role": "system", "content": "You are a sentiment analyzer."},
    {"role": "user", "content": "I love this product!"},
    {"role": "assistant", "content": "Positive"},
    {"role": "user", "content": "This is terrible."},
    {"role": "assistant", "content": "Negative"},
    {"role": "user", "content": "The weather is nice today."}
]

Advanced Features

Streaming Responses

For long responses, use streaming to improve user experience:

stream = client.chat.completions.create(
    model="gpt-4-turbo-preview",
    messages=[{"role": "user", "content": "Write a long story"}],
    stream=True
)

for chunk in stream:
    if chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end="")

Function Calling

Enable the model to call functions in your code:

functions = [
    {
        "name": "get_weather",
        "description": "Get the current weather for a location",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "City name"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"]
                }
            },
            "required": ["location"]
        }
    }
]

response = client.chat.completions.create(
    model="gpt-4-turbo-preview",
    messages=[{"role": "user", "content": "What's the weather in Paris?"}],
    functions=functions,
    function_call="auto"
)

# Check if the model wants to call a function
if response.choices[0].message.function_call:
    function_name = response.choices[0].message.function_call.name
    arguments = json.loads(response.choices[0].message.function_call.arguments)
    
    # Call your actual function
    result = get_weather(**arguments)
    
    # Send the result back to the model
    second_response = client.chat.completions.create(
        model="gpt-4-turbo-preview",
        messages=[
            {"role": "user", "content": "What's the weather in Paris?"},
            response.choices[0].message,
            {
                "role": "function",
                "name": function_name,
                "content": json.dumps(result)
            }
        ]
    )

JSON Mode

Force the model to return valid JSON:

response = client.chat.completions.create(
    model="gpt-4-turbo-preview",
    messages=[
        {
            "role": "system",
            "content": "You are a helpful assistant that outputs JSON."
        },
        {
            "role": "user",
            "content": "List 3 programming languages with their use cases"
        }
    ],
    response_format={"type": "json_object"}
)

data = json.loads(response.choices[0].message.content)

Error Handling

Always implement robust error handling:

from openai import OpenAI, OpenAIError, RateLimitError, APIError
import time

def call_openai_with_retry(messages, max_retries=3):
    """Call OpenAI API with exponential backoff retry logic"""
    client = OpenAI()
    
    for attempt in range(max_retries):
        try:
            response = client.chat.completions.create(
                model="gpt-4-turbo-preview",
                messages=messages,
                temperature=0.7,
                max_tokens=1000
            )
            return response
            
        except RateLimitError:
            if attempt < max_retries - 1:
                wait_time = (2 ** attempt) * 2  # Exponential backoff
                print(f"Rate limit hit. Waiting {wait_time} seconds...")
                time.sleep(wait_time)
            else:
                raise
                
        except APIError as e:
            print(f"API error: {e}")
            if attempt < max_retries - 1:
                time.sleep(2)
            else:
                raise
                
        except OpenAIError as e:
            print(f"OpenAI error: {e}")
            raise

# Usage
try:
    response = call_openai_with_retry([
        {"role": "user", "content": "Hello!"}
    ])
    print(response.choices[0].message.content)
except OpenAIError as e:
    print(f"Failed after retries: {e}")

Cost Optimization

1. Choose the Right Model

  • GPT-4 Turbo: Most capable, higher cost
  • GPT-3.5 Turbo: Faster, cheaper, good for most tasks
  • GPT-4o mini: Cheapest, best for simple tasks

2. Limit Token Usage

response = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=messages,
    max_tokens=500,  # Limit response length
    temperature=0.3  # Lower temperature = more focused responses
)

# Track token usage
print(f"Tokens used: {response.usage.total_tokens}")
print(f"Cost: ${response.usage.total_tokens * 0.000002:.6f}")

3. Cache Responses

import hashlib
import json
from functools import lru_cache

@lru_cache(maxsize=100)
def cached_openai_call(messages_hash):
    """Cache OpenAI responses to avoid duplicate calls"""
    messages = json.loads(messages_hash)
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages
    )
    return response.choices[0].message.content

# Usage
messages = [{"role": "user", "content": "Hello"}]
messages_hash = json.dumps(messages, sort_keys=True)
result = cached_openai_call(messages_hash)

Security Best Practices

1. Never Expose API Keys

# ❌ Bad - hardcoded key
client = OpenAI(api_key="sk-...")

# ✅ Good - environment variable
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

2. Validate User Input

def sanitize_input(user_input: str) -> str:
    """Sanitize user input to prevent prompt injection"""
    # Remove potential injection attempts
    sanitized = user_input.replace("Ignore previous instructions", "")
    
    # Limit length
    max_length = 1000
    sanitized = sanitized[:max_length]
    
    return sanitized

user_message = sanitize_input(request.form.get("message"))

3. Implement Rate Limiting

from flask_limiter import Limiter
from flask import Flask

app = Flask(__name__)
limiter = Limiter(app, key_func=lambda: request.remote_addr)

@app.route("/api/chat", methods=["POST"])
@limiter.limit("10 per minute")
def chat():
    # Your OpenAI API call here
    pass

Real-World Example: Code Review Bot

Here’s a complete example that reviews code:

def review_code(code: str, language: str) -> dict:
    """Review code and provide feedback"""
    client = OpenAI()
    
    prompt = f"""Review the following {language} code and provide:
1. Potential bugs or errors
2. Performance improvements
3. Best practice suggestions
4. Security concerns

Code:
{code}

Format your response as JSON with keys: bugs, performance, best_practices, security
"""
    
    response = client.chat.completions.create(
        model="gpt-4-turbo-preview",
        messages=[
            {
                "role": "system",
                "content": "You are an expert code reviewer."
            },
            {
                "role": "user",
                "content": prompt
            }
        ],
        response_format={"type": "json_object"},
        temperature=0.3
    )
    
    return json.loads(response.choices[0].message.content)

# Usage
code = """
def calculate_average(numbers):
    return sum(numbers) / len(numbers)
"""

review = review_code(code, "python")
print(json.dumps(review, indent=2))

Conclusion

You now have the knowledge to integrate OpenAI’s API into your applications effectively. Remember to:

  • Write clear, specific prompts
  • Implement proper error handling
  • Optimize for cost
  • Follow security best practices
  • Monitor usage and performance

Next Steps

Resources

We respect your privacy.

← View All Tutorials

Related Projects

    Ask me anything!