When I first started working with AI APIs three years ago, I made the same mistake that almost every developer makes: I hardcoded the latest model version into my production application. Six months later, when the provider updated their model and deprecated the old version, I spent an entire weekend emergency-patching my code while users experienced service interruptions. That painful experience taught me why AI model versioning and API compatibility management are critical skills that every developer needs to master from day one.
In this comprehensive guide, I'll walk you through everything you need to know about managing AI model versions, maintaining API compatibility, and building resilient applications that can adapt when providers release new models or change their APIs. By the end of this tutorial, you'll have a complete system for tracking, testing, and migrating between AI model versions without breaking your applications.
Understanding AI Model Versioning: Why It Matters
When you use an AI API like those available through HolySheheep AI, you're connecting to a service that's constantly evolving. Providers regularly release new model versions with improved capabilities, better accuracy, lower costs, or faster response times. However, these improvements sometimes come with changes to the API interface, response formats, or behavior.
AI model versioning is the practice of explicitly specifying which version of a model your application should use. Instead of just requesting "GPT-4" or "Claude," you specify "GPT-4.1" or "Claude Sonnet 4.5" to ensure consistent behavior across requests. This approach gives you control over when and how you upgrade to new versions.
Why Do Providers Version Their Models?
- Performance improvements: New versions often deliver better results for the same cost
- Cost optimization: Providers like HolySheep AI offer models like DeepSeek V3.2 at just $0.42 per million tokens, significantly reducing your operational expenses
- Capability expansion: New versions may support longer contexts, additional features, or better reasoning
- Bug fixes: Version updates often address limitations or errors in previous releases
- Infrastructure improvements: Newer versions may leverage improved hardware for faster responses
Your First AI API Call: A Step-by-Step Walkthrough
Before diving into versioning strategies, let's establish a solid foundation with your first API call. If you're completely new to AI APIs, don't worryβwe'll start from absolute scratch.
Understanding the Basic Request Structure
Every AI API call follows a similar pattern: you send a request containing your message, and the API returns a response. The request includes several key components:
- Endpoint: The URL that identifies the specific service you're calling
- Headers: Authentication and content type information
- Body: Your actual request data, including the model version, messages, and parameters
The HolySheep AI platform offers <50ms latency and supports multiple leading models including GPT-4.1 at $8 per million tokens, Claude Sonnet 4.5 at $15 per million tokens, Gemini 2.5 Flash at $2.50 per million tokens, and DeepSeek V3.2 at $0.42 per million tokensβproviding flexibility for both high-performance and cost-sensitive applications.
Making Your First API Call with Python
Let's write your first complete API call. This example uses Python, one of the most popular languages for AI integration work:
# Install the required library first:
pip install requests
import requests
import json
Your API configuration
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY" # Replace with your actual key
def send_message_to_ai(user_message):
"""
Send a message to an AI model and get a response.
This is your first step into AI API integration!
"""
# Define the endpoint for chat completions
endpoint = f"{BASE_URL}/chat/completions"
# Set up headers with your authentication
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Construct your request body
# Notice we specify a specific model version for consistency
payload = {
"model": "gpt-4.1", # Always specify the exact version!
"messages": [
{
"role": "system",
"content": "You are a helpful assistant that explains things clearly to beginners."
},
{
"role": "user",
"content": user_message
}
],
"temperature": 0.7, # Controls randomness (0 = deterministic, 1 = creative)
"max_tokens": 500 # Limits response length
}
try:
# Make the API call
response = requests.post(endpoint, headers=headers, json=payload)
# Check if the request was successful
if response.status_code == 200:
data = response.json()
assistant_message = data["choices"][0]["message"]["content"]
return assistant_message
else:
print(f"Error: {response.status_code}")
print(response.text)
return None
except requests.exceptions.RequestException as e:
print(f"Connection error: {e}")
return None
Test your first API call
if __name__ == "__main__":
print("π€ AI API Tutorial - First Call")
print("=" * 40)
response = send_message_to_ai("What is model versioning and why should I care?")
if response:
print("\nπ AI Response:")
print(response)
What you see in this code:
- Line by line explanation: We construct a request with proper authentication headers
- Model specification: Notice "gpt-4.1" instead of just "gpt-4"βthis is the versioning practice in action
- Error handling: We check the response status and handle potential connection issues
- Clean structure: The function is reusable and can be called multiple times
Building a Version-Aware AI Client
Now that you understand the basics, let's build something more robust: a version-aware client that can automatically handle different model versions and gracefully handle API changes.
import requests import json import time from typing import Dict, List, Optional, Any from dataclasses import dataclass from enum import Enum class ModelVersion(Enum): """Supported AI model versions with their configurations""" GPT_4_1 = "gpt-4.1" CLAUDE_SONNET_4_5 = "claude-sonnet-4.5" GEMINI_2_5_FLASH = "gemini-2.5-flash" DEEPSEEK_V3_2 = "deepseek-v3.2" @dataclass class ModelConfig: """Configuration for each model version""" name: str cost_per_million_tokens: float max_context_tokens: int supports_streaming: bool avg_latency_ms: float class VersionAwareAIClient: """ A robust AI client that handles model versioning automatically. This is production-ready code you can use in real applications! """ # Model configurations with real pricing data MODEL_CONFIGS: Dict[str, ModelConfig] = { "gpt-4.1": ModelConfig( name="GPT-4.1", cost_per_million_tokens=8.00, max_context_tokens=128000, supports_streaming=True, avg_latency_ms=45 ), "claude-sonnet-4.5": ModelConfig( name="Claude Sonnet 4.5", cost_per_million_tokens=15.00, max_context_tokens=200000, supports_streaming=True, avg_latency_ms=38 ), "gemini-2.5-flash": ModelConfig( name="Gemini 2.5 Flash", cost_per_million_tokens=2.50, max_context_tokens=1000000, supports_streaming=True, avg_latency_ms=25 ), "deepseek-v3.2": ModelConfig( name="DeepSeek V3.2", cost_per_million_tokens=0.42, max_context_tokens=64000, supports_streaming=True, avg_latency_ms=30 ), } def __init__(self, api_key: str, base_url: str = "https://api.holysheep.ai/v1"): self.api_key = api_key self.base_url = base_url self.current_model = "gpt-4.1" self.request_count = 0 def set_model(self, model_name: str) -> bool: """ Safely switch to a different model version. Returns True if successful, False if model not supported. """ if model_name in self.MODEL_CONFIGS: self.current_model = model_name print(f"β Model switched to: {model_name}") return True else: print(f"β Unsupported model: {model_name}") print(f"Available models: {list(self.MODEL_CONFIGS.keys())}") return False def estimate_cost(self, input_tokens: int, output_tokens: int) -> float: """ Estimate the cost of a request based on token counts. Uses the current model's pricing configuration. """ config = self.MODEL_CONFIGS.get(self.current_model) if not config: return 0.0 total_tokens = input_tokens + output_tokens cost = (total_tokens / 1_000_000) * config.cost_per_million_tokens return round(cost, 4) def send_request(self, messages: List[Dict], **kwargs) -> Optional[Dict]: """ Send a request to the AI model with automatic version handling. Includes comprehensive error handling for API compatibility issues. """ endpoint = f"{self.base_url}/chat/completions" headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" } payload = { "model": self.current_model, "messages": messages, **{k: v for k, v in kwargs.items() if v is not None} } start_time = time.time() try: response = requests.post(endpoint, headers=headers, json=payload, timeout=30) elapsed_ms = (time.time() - start_time) * 1000 self.request_count += 1 if response.status_code == 200: return { "success": True, "data": response.json(), "latency_ms": round(elapsed_ms, 2), "model_used": self.current_model } else: return self._handle_error_response(response) except requests.exceptions.Timeout: return { "success": False, "error": "Request timed out", "model_used": self.current_model, "suggestion": "Try a faster model like Gemini 2.5 Flash for better latency" } except Exception as e: return { "success": False, "error": str(e), "model_used": self.current_model } def _handle_error_response(self, response: requests.Response) -> Dict: """Handle various API error responses with helpful suggestions""" status_code = response.status_code error_data = response.json() if response.content else {} error_handlers = { 401: ("Authentication failed", "Check your API key is correct"), 403: ("Access forbidden", "Your account may have restrictions"), 404: ("Model not found", "Verify the model name is correct"), 429: ("Rate limit exceeded", "Wait before making more requests"), 500: ("Server error", "The provider is experiencing issues"), 503: ("Service unavailable", "Try again in a few moments"), } error_msg, suggestion = error_handlers.get( status_code, ("Unknown error", "Check API documentation") ) return { "success": False, "error": error_msg, "details": error_data, "suggestion": suggestion, "status_code": status_code } def get_model_info(self) -> Dict: """Get information about the currently selected model""" config = self.MODEL_CONFIGS.get(self.current_model) if config: return { "model": self.current_model, "name": config.name, "cost_per_million": f"${config.cost_per_million_tokens:.2f}", "max_tokens": config.max_context_tokens, "supports_streaming": config.supports_streaming, "avg_latency": f"{config.avg_latency_ms}ms" } return {} Usage example
if __name__ == "__main__": # Initialize your client client = VersionAwareAIClient(api_key="YOUR_HOLYSHEEP_API_KEY") print("π€ HolySheep AI Version-Aware Client Demo") print("=" * 50) # Show available models print("\nπ¦ Available Models:") for model_id, config in client.MODEL_CONFIGS.items(): print(f" β’ {model_id}: ${config.cost_per_million_tokens}/1M tokens") # Test with different models test_messages = [ {"role": "user", "content": "Explain AI model versioning in one sentence."} ] # Try each model for model in ["deepseek-v3.2", "gemini-2.5-flash", "gpt-4.1"]: if client.set_model(model): result = client.send_request(test_messages, max_tokens=100) if result["success"]: print(f"\nβ {model} response received in {result['latency_ms']}ms") else: print(f"\nβ {model} failed: {result.get('error')}")
This code introduces several critical concepts for production AI applications:
- Configuration management: All model versions and their parameters are stored in a central location
- Automatic error handling: The client catches common errors and provides actionable suggestions
- Cost estimation: Before making expensive calls, you can estimate the cost
- Model switching: The client can switch between models based on your needs
API Compatibility Strategies for Production Applications
When you're building applications that depend on AI APIs, you need strategies to ensure your code remains compatible even when providers make changes. Here are the key approaches used by professional development teams.
Strategy 1: Pin to Specific Versions
The most conservative approach is to explicitly pin your application to a specific model version and maintain that version until you've thoroughly tested newer options. This minimizes unexpected behavior changes but may prevent you from benefiting from improvements.
# Configuration file approach (config.py)
"""
Production Configuration - Pin to specific versions
This ensures consistency across all deployments
"""
Never change these without thorough testing!
PRODUCTION_MODELS = {
"primary": {
"chat": "gpt-4.1",
"embedding": "text-embedding-3-small",
"vision": "gpt-4o"
},
"fallback": {
"chat": "deepseek-v3.2",
"embedding": "text-embedding-3-small",
"vision": "gemini-2.5-flash"
}
}
Environment-based configuration
import os
ENVIRONMENT = os.getenv("APP_ENV", "production")
if ENVIRONMENT == "development":
# Use cheaper models for testing
DEFAULT_MODEL = "deepseek-v3.2"
DEBUG_MODE = True
elif ENVIRONMENT == "staging":
# Test with production-equivalent models
DEFAULT_MODEL = "gpt-4.1"
DEBUG_MODE = True
else:
# Production uses pinned, tested versions
DEFAULT_MODEL = PRODUCTION_MODELS["primary"]["chat"]
DEBUG_MODE = False
Strategy 2: Implement Fallback Chains
For critical applications, implement a fallback chain where if your preferred model is unavailable or fails, the system automatically tries the next model in order of preference:
class FallbackChain:
"""
Automatically falls back to alternative models if primary fails.
Essential for production applications that cannot tolerate downtime.
"""
def __init__(self, api_key: str):
self.client = VersionAwareAIClient(api_key)
# Define your fallback priority
# Order matters: try most capable first, fall back to most reliable
self.fallback_order = [
"gpt-4.1", # Most capable, highest cost
"claude-sonnet-4.5", # Strong alternative
"gemini-2.5-flash", # Fast and reliable
"deepseek-v3.2" # Most cost-effective
]
def send_with_fallback(self, messages: List[Dict],
preferred_model: str = None) -> Dict:
"""
Try models in order until one succeeds.
Returns the successful response plus which model was used.
"""
models_to_try = []
if preferred_model:
# Put preferred model first
models_to_try = [preferred_model] + [
m for m in self.fallback_order if m != preferred_model
]
else:
models_to_try = self.fallback_order
last_error = None
for model in models_to_try:
self.client.set_model(model)
result = self.client.send_request(messages)
if result["success"]:
result["fallback_used"] = model != preferred_model
result["models_attempted"] = models_to_try.index(model) + 1
return result
else:
last_error = result
print(f"β οΈ {model} failed, trying next option...")
# All models failed
return {
"success": False,
"error": "All models in fallback chain failed",
"last_error": last_error,
"models_attempted": len(models_to_try),
"suggestion": "Check your API key and account status"
}
Real-world usage
def get_ai_response(user_input: str, max_cost: float = 0.01) -> str:
"""
Get an AI response while respecting cost constraints.
Useful for high-volume applications.
"""
chain = FallbackChain(api_key="YOUR_HOLYSHEEP_API_KEY")
messages = [{"role": "user", "content": user_input}]
# Try cheapest models first for cost-sensitive applications
result = chain.send_with_fallback(messages)
if result["success"]:
cost = chain.client.estimate_cost(
input_tokens=100, # Approximate
output_tokens=200
)
if cost <= max_cost:
return result["data"]["choices"][0]["message"]["content"]
else:
return f"Response would cost ${cost:.4f}, exceeds limit of ${max_cost}"
else:
return f"Failed to get response: {result['error']}"
Monitoring and Tracking Model Changes
The key to successful API compatibility management is continuous monitoring. You need to know when providers release new models, when they deprecate old ones, and how your application's behavior changes with updates.
Building a Simple Monitoring Dashboard
Here's a monitoring system that tracks your API usage, response times, and alerts you to potential issues:
import sqlite3
from datetime import datetime
from typing import List, Dict
import statistics
class APIMonitor:
"""
Monitor your AI API usage and track model performance over time.
Essential for understanding cost trends and identifying issues.
"""
def __init__(self, db_path: str = "ai_api_monitor.db"):
self.db_path = db_path
self._init_database()
def _init_database(self):
"""Create the monitoring database if it doesn't exist"""
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS api_requests (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT NOT NULL,
model TEXT NOT NULL,
input_tokens INTEGER,
output_tokens INTEGER,
latency_ms REAL,
success BOOLEAN,
error_message TEXT,
cost_usd REAL
)
""")
conn.commit()
def log_request(self, model: str, input_tokens: int,
output_tokens: int, latency_ms: float,
success: bool, error_message: str = None,
cost_per_million: float = 0.0):
"""Log a single API request to the database"""
total_cost = ((input_tokens + output_tokens) / 1_000_000) * cost_per_million
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute("""
INSERT INTO api_requests
(timestamp, model, input_tokens, output_tokens,
latency_ms, success, error_message, cost_usd)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", (
datetime.now().isoformat(),
model,
input_tokens,
output_tokens,
latency_ms,
success,
error_message,
total_cost
))
conn.commit()
def get_model_statistics(self, days: int = 7) -> List[Dict]:
"""Get performance statistics for each model over the specified period"""
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute("""
SELECT
model,
COUNT(*) as total_requests,
SUM(success) as successful_requests,
AVG(latency_ms) as avg_latency,
SUM(cost_usd) as total_cost,
AVG(input_tokens + output_tokens) as avg_tokens
FROM api_requests
WHERE timestamp >= datetime('now', '-' || ? || ' days')
GROUP BY model
ORDER BY total_requests DESC
""", (days,))
columns = [desc[0] for desc in cursor.description]
results = [dict(zip(columns, row)) for row in cursor.fetchall()]
for r in results:
r['success_rate'] = (r['successful_requests'] / r['total_requests'] * 100)
r['total_cost'] = round(r['total_cost'], 4)
r['avg_latency'] = round(r['avg_latency'], 2)
return results
def check_model_deprecation(self, supported_models: List[str]) -> Dict:
"""
Check if you're using any deprecated models.
Call this periodically to catch deprecated model usage.
"""
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute("""
SELECT DISTINCT model FROM api_requests
WHERE model NOT IN (SELECT value FROM json_each(?))
""", (json.dumps(supported_models),))
deprecated = [row[0] for row in cursor.fetchall()]
return {
"has_deprecated": len(deprecated) > 0,
"deprecated_models": deprecated,
"action_required": bool(deprecated)
}
def generate_cost_report(self, days: int = 30) -> str:
"""Generate a human-readable cost report"""
stats = self.get_model_statistics(days)
report = f"""
π AI API Cost Report ({days} days)
{'=' * 40}
"""
total_cost = 0
total_requests = 0
for s in stats:
report += f"""
{s['model']}
Requests: {s['total_requests']:,}
Success Rate: {s['success_rate']:.1f}%
Avg Latency: {s['avg_latency']:.1f}ms
Total Cost: ${s['total_cost']:.4f}
"""
total_cost += s['total_cost']
total_requests += s['total_requests']
report += f"""
{'=' * 40}
TOTAL: {total_requests:,} requests | ${total_cost:.4f}
π‘ HolySheep AI Tip:
Using DeepSeek V3.2 ($0.42/1M tokens) instead of Claude Sonnet 4.5 ($15/1M)
can save up to 97% on token costs!
"""
return report
Usage
if __name__ == "__main__":
monitor = APIMonitor()
# Simulate logging some requests
monitor.log_request(
model="deepseek-v3.2",
input_tokens=150,
output_tokens=350,
latency_ms=32.5,
success=True,
cost_per_million=0.42
)
# Get your report
print(monitor.generate_cost_report())
Common Errors and Fixes
Even with careful planning, you'll encounter issues when working with AI APIs. Here are the most common problems and their solutions, based on real-world experience from production deployments.
Error 1: Authentication Failed (401 Error)
Problem: You're getting a 401 Unauthorized error when making API calls.
# β WRONG - Common mistakes that cause 401 errors:
Mistake 1: Wrong header format
headers = {
"Authorization": API_KEY # Missing "Bearer " prefix!
}
Mistake 2: Typo in header name
headers = {
"Authoriztion": f"Bearer {API_KEY}" # Typo!
}
Mistake 3: Wrong content type
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "text/plain" # Should be application/json
}
β
CORRECT - Proper authentication setup:
import os
def get_auth_headers(api_key: str = None):
"""
Get properly formatted authentication headers.
Never hardcode API keys in production code!
"""
# Get key from environment variable or parameter
key = api_key or os.getenv("HOLYSHEEP_API_KEY")
if not key:
raise ValueError(
"API key not found. Set HOLYSHEEP_API_KEY environment variable "
"or pass api_key parameter."
)
# Validate key format (HolySheep AI keys start with 'hs_')
if not key.startswith(("hs_", "sk-")):
raise ValueError(
"Invalid API key format. HolySheep AI keys should start with 'hs_'"
)
return {
"Authorization": f"Bearer {key}", # Include "Bearer " prefix!
"Content-Type": "application/json" # Always use JSON content type
}
Test your authentication
headers = get_auth_headers("YOUR_HOLYSHEEP_API_KEY")
print(f"β
Auth headers prepared: {list(headers.keys())}")
Error 2: Model Not Found (404 Error)
Problem: You're specifying a model that doesn't exist or has been deprecated.
# β WRONG - Using outdated or incorrect model names:
payload = {
"model": "gpt-4", # Too generic, specify exact version
"model": "gpt-4.0", # Old version format
"model": "claude-3-sonnet", # Incomplete version number
}
β
CORRECT - Using precise, current model identifiers:
def validate_model_name(model: str) -> tuple[bool, str]:
"""
Validate model name against known supported models.
Returns (is_valid, suggestion).
"""
# Current valid models (update this list as models change)
VALID_MODELS = {
"gpt-4.1": "Current GPT-4.1 model, $8/1M tokens",
"claude-sonnet-4.5": "Claude Sonnet 4.5, $15/1M tokens",
"gemini-2.5-flash": "Gemini 2.5 Flash, $2.50/1M tokens",
"deepseek-v3.2": "DeepSeek V3.2, $0.42/1M tokens - best value!",
}
if model in VALID_MODELS:
return True, f"Valid model: {VALID_MODELS[model]}"
# Find similar models (helps catch typos)
similar = [m for m in VALID_MODELS if model.lower() in m.lower()]
if similar:
return False, f"Did you mean: {', '.join(similar)}?"
return False, f"Model not found. Available: {list(VALID_MODELS.keys())}"
Test validation
test_models = ["gpt-4.1", "gpt-4", "deepseek-v3.2", "unknown-model"]
for model in test_models:
valid, message = validate_model_name(model)
status = "β
" if valid else "β"
print(f"{status} {model}: {message}")
Error 3: Rate Limit Exceeded (429 Error)
Problem: You're making too many requests and hitting rate limits.
# β WRONG - No rate limiting, causing 429 errors:
def bad_batch_processing(messages: List[str], api_key: str):
"""This will definitely hit rate limits!"""
results = []
for msg in messages: # 1000+ messages in a loop
response = send_request(msg, api_key) # No delay!
results.append(response)
return results
β
CORRECT - Implementing proper rate limiting with exponential backoff:
import time
import random
from functools import wraps
class RateLimitedClient:
"""
A client wrapper that automatically handles rate limiting.
Implements exponential backoff to avoid overwhelming the API.
"""
def __init__(self, base_client, max_retries: int = 5):
self.client = base_client
self.max_retries = max_retries
self.requests_made = 0
def send_with_rate_limit_handling(self, messages: List[Dict]) -> Dict:
"""
Send request with automatic rate limit handling.
Uses exponential backoff when rate limited.
"""
base_delay = 1.0 # Start with 1 second
max_delay = 60.0 # Cap at 60 seconds
for attempt in range(self.max_retries):
result = self.client.send_request(messages)
if result.get("status_code") != 429:
# Not a rate limit error, return result
return result
# Calculate delay with exponential backoff + jitter
delay = min(base_delay * (2 ** attempt), max_delay)
jitter = random.uniform(0, delay * 0.1)
total_delay = delay + jitter
print(f"β³ Rate limited. Waiting {total_delay:.1f}s before retry...")
time.sleep(total_delay)
return {
"success": False,
"error": "Max retries exceeded due to rate limiting",
"suggestion": "Consider upgrading your HolySheep AI plan or reducing request frequency"
}
def batch_process_with_throttling(self, items: List[str],
delay_between: float = 0.1) -> List[Dict]:
"""
Process multiple items with a small delay between each request.
Ideal for bulk operations that don't need instant responses.
"""
results = []
total = len(items)
for i, item in enumerate(items, 1):
print(f"π€ Processing {i}/{total}...")
# Add small delay to avoid rate limits
if i > 1:
time.sleep(delay_between)
result = self.client.send_request([{"role": "user", "content": item}])
results.append(result)
self.requests_made += 1
# Log progress every 100 requests
if i % 100 == 0:
print(f"π Progress: {i}/{total} requests made")
return results
Usage example
def process_user_messages(messages: List[str], api_key: str) -> List[str]:
"""Process messages with proper rate limit handling"""
base_client = VersionAwareAIClient(api_key)
limited_client = RateLimitedClient(base_client)
results = []
for msg in messages:
result = limited_client.send_with_rate_limit_handling(
[{"role": "user", "content": msg}]
)
if result.get("success"):
response_text = result["data"]["choices"][0]["message"]["content"]
results.append(response_text)
else:
results.append(f"Error: {result.get('error', 'Unknown error')}")
return results
Error 4: Response Parsing Failures
Problem: The API returns a response, but you can't parse it correctly.
# β WRONG - Naive response parsing that breaks on unexpected formats:
def bad_parse_response(response_json):
"""This will crash if the API changes response structure!"""
return response_json["choices"][0]["message"]["content"]
β
CORRECT - Robust parsing with multiple fallbacks:
def robust_parse_response(response: requests.Response) -> Dict:
"""
Parse API response with multiple fallback strategies.
Handles various response formats and edge cases.
"""
# Strategy 1: Try standard JSON parsing
try:
data = response.json()
# Validate expected structure
if "choices" in data and len(data["choices"]) > 0:
choice = data["choices"][0]
# Handle different content formats
if "message" in choice:
content = choice["message"].get("content", "")
elif "text" in choice:
content = choice["text"]
elif "delta" in choice:
content = choice["delta"].get("content", "")
else:
content = str(choice)
return {
"success": True,
"content": content,
"model": data.get("model", "unknown"),
"usage": data.get("usage", {}),
"raw": data
}
else:
return {
"success": False,
"error": "Unexpected response structure",
"raw": data
}
except json.JSONDecodeError:
# Strategy 2: Try to extract content from text response
try:
text = response.text
# Try common patterns
import re
content_match = re.search(r'"content":\s*"([^"]+)"', text)
if content_match:
return {
"success": True,
"content": content_match.group(1),
"parse_method": "regex_fallback"
}
except Exception:
pass
return {
"success": False,
"error": "Could not parse response",
"status_code": response.status_code,
"raw_text": response.text[:200]
}
Usage
response = requests.post(endpoint, headers=headers, json=payload)
result = robust_parse_response(response)
if result["success"]:
print(f"β
Response: {result['content']}")
else: