---
name: "OpenAI API"
description: "Skill for OpenAI API — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "dev"
agents: ["claude-code", "codex", "gemini"]
tags: ["openai-api", "dev", "auto-generated"]
---

# OpenAI API

---
name: OpenAI API
description: Use when working with OpenAI's API for chat completions, embeddings, image generation, audio processing, and fine-tuning. Essential for AI-powered applications and automation.
category: dev
metadata:
  author: skynet
  version: 1.0.0
---

# OpenAI API

## Quick Setup

```bash
# Install OpenAI Python client
pip install openai

# Set API key (get from https://platform.openai.com/account/api-keys)
export OPENAI_API_KEY="sk-proj-..."

# Verify installation
python -c "import openai; print(openai.__version__)"
```

## Authentication Patterns

```python
# Method 1: Environment variable (recommended)
import openai
client = openai.OpenAI()  # Uses OPENAI_API_KEY automatically

# Method 2: Direct initialization
client = openai.OpenAI(api_key="sk-proj-...")

# Method 3: Azure OpenAI
client = openai.AzureOpenAI(
    api_key="your-key",
    api_version="2024-02-01",
    azure_endpoint="https://your-resource.openai.azure.com"
)
```

## Chat Completions

### Basic Chat
```python
response = client.chat.completions.create(
    model="gpt-4",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain quantum computing"}
    ],
    max_tokens=150,
    temperature=0.7
)
print(response.choices[0].message.content)
```

### Streaming Response
```python
stream = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Write a 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
```python
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get weather for a location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
                },
                "required": ["location"]
            }
        }
    }
]

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

# Handle function call
if response.choices[0].message.tool_calls:
    tool_call = response.choices[0].message.tool_calls[0]
    function_name = tool_call.function.name
    arguments = json.loads(tool_call.function.arguments)
```

## Embeddings

```python
# Generate embeddings
response = client.embeddings.create(
    model="text-embedding-3-small",
    input=["Text to embed", "Another text"],
    encoding_format="float"
)

embeddings = [data.embedding for data in response.data]

# Calculate similarity
import numpy as np
similarity = np.dot(embeddings[0], embeddings[1])
```

## Image Generation (DALL-E)

```python
# Generate image
response = client.images.generate(
    model="dall-e-3",
    prompt="A futuristic city with flying cars",
    size="1024x1024",
    quality="standard",
    n=1
)

image_url = response.data[0].url

# Edit image (DALL-E 2 only)
response = client.images.edit(
    model="dall-e-2",
    image=open("original.png", "rb"),
    mask=open("mask.png", "rb"),
    prompt="Add a sunset background",
    n=1,
    size="1024x1024"
)
```

## Audio Processing

### Text-to-Speech
```python
response = client.audio.speech.create(
    model="tts-1",
    voice="alloy",
    input="Hello! This is a test of text to speech."
)

with open("output.mp3", "wb") as f:
    f.write(response.content)
```

### Speech-to-Text
```python
with open("audio.mp3", "rb") as audio_file:
    transcript = client.audio.transcriptions.create(
        model="whisper-1",
        file=audio_file,
        response_format="text"
    )
    print(transcript)

# With timestamps
transcript = client.audio.transcriptions.create(
    model="whisper-1",
    file=audio_file,
    response_format="verbose_json",
    timestamp_granularities=["word"]
)
```

## Decision Tree: Model Selection

```
Need AI assistance?
├── Text generation/chat?
│   ├── Complex reasoning → gpt-4
│   ├── Fast/cheap → gpt-3.5-turbo
│   └── Latest features → gpt-4-turbo
├── Text embeddings?
│   ├── High quality → text-embedding-3-large
│   └── Cost-effective → text-embedding-3-small
├── Image generation?
│   ├── High quality → dall-e-3
│   └── Editing/variations → dall-e-2
└── Audio?
    ├── Speech-to-text → whisper-1
    └── Text-to-speech → tts-1 or tts-1-hd
```

## Batch Processing

```python
# Create batch job
batch_input = []
for i, prompt in enumerate(prompts):
    batch_input.append({
        "custom_id": f"request-{i}",
        "method": "POST",
        "url": "/v1/chat/completions",
        "body": {
            "model": "gpt-3.5-turbo",
            "messages": [{"role": "user", "content": prompt}],
            "max_tokens": 100
        }
    })

# Save to JSONL file
with open("batch_input.jsonl", "w") as f:
    for item in batch_input:
        f.write(json.dumps(item) + "\n")

# Upload and create batch
file_response = client.files.create(
    file=open("batch_input.jsonl", "rb"),
    purpose="batch"
)

batch = client.batches.create(
    input_file_id=file_response.id,
    endpoint="/v1/chat/completions",
    completion_window="24h"
)

# Check status
batch_status = client.batches.retrieve(batch.id)
print(f"Status: {batch_status.status}")
```

## Usage Tracking

```bash
# Check usage with curl
curl https://api.openai.com/v1/usage \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -G \
  -d "date=2024-01-01"
```

```python
# Monitor token usage
def count_tokens(text, model="gpt-4"):
    import tiktoken
    encoding = tiktoken.encoding_for_model(model)
    return len(encoding.encode(text))

# Calculate costs
def estimate_cost(prompt_tokens, completion_tokens, model="gpt-4"):
    pricing = {
        "gpt-4": {"input": 0.03, "output": 0.06},  # per 1K tokens
        "gpt-3.5-turbo": {"input": 0.0015, "output": 0.002}
    }
    cost = (prompt_tokens * pricing[model]["input"] + 
            completion_tokens * pricing[model]["output"]) / 1000
    return cost
```

## Error Handling

```python
import openai
from openai import OpenAI

client = OpenAI()

try:
    response = client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": "Hello"}]
    )
except openai.RateLimitError as e:
    print(f"Rate limit exceeded: {e}")
    # Implement exponential backoff
    time.sleep(2 ** attempt)
except openai.APIError as e:
    print(f"API error: {e}")
except openai.AuthenticationError as e:
    print(f"Authentication failed: {e}")
    # Check API key
except openai.APIConnectionError as e:
    print(f"Connection error: {e}")
    # Check internet connection
```

## Common Troubleshooting

**Error: "Invalid API key"**
```bash
# Verify key format (should start with sk-proj- for new keys)
echo $OPENAI_API_KEY | head -c 20

# Test key validity
curl https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY"
```

**Error: "Rate limit exceeded"**
```python
import time
import random

def retry_with_backoff(func, max_retries=5):
    for attempt in range(max_retries):
        try:
            return func()
        except openai.RateLimitError:
            if attempt == max_retries - 1:
                raise
            wait_time = (2 ** attempt) + random.uniform(0, 1)
            time.sleep(wait_time)
```

**Error: "Model not found"**
```python
# List available models
models = client.models.list()
for model in models.data:
    print(model.id)
```

**Token limit exceeded**
```python
def truncate_conversation(messages, max_tokens=3000, model="gpt-4"):
    import tiktoken
    encoding = tiktoken.encoding_for_model(model)
    
    total_tokens = 0
    truncated = []
    
    # Keep system message, truncate from oldest user messages
    for msg in reversed(messages):
        msg_tokens = len(encoding.encode(msg["content"]))
        if total_tokens + msg_tokens > max_tokens:
            break
        truncated.insert(0, msg)
        total_tokens += msg_tokens
    
    return truncated
```
