Workflow Step: Step 1 of 2: Generate Code (collab → generate_code)
This document provides a comprehensive, detailed, and professional output for generating production-ready code to integrate with an external API. This deliverable focuses on a common scenario: interacting with a RESTful API using Python, handling authentication, making requests, and robustly managing responses and errors.
This initial step of the "API Integration Builder" workflow focuses on generating the core code required to establish communication with a target external API. Our goal is to provide a robust, maintainable, and secure foundation for your API integration needs. The generated code will be modular, include best practices for error handling, authentication, and logging, and serve as a template you can adapt for various API endpoints and functionalities.
Before diving into the code, it's essential to understand the fundamental components involved in successful API integration:
/users, /products/{id}).Authorization, Content-Type, User-Agent).To provide concrete, actionable code, we'll use a realistic (albeit fictional) scenario: integrating with a "PantheraData API" to manage user data.
https://api.pantheradata.com/v1/usersGET * id (optional, query parameter): Filter by user ID.
* limit (optional, query parameter): Limit the number of results.
* offset (optional, query parameter): Offset for pagination.
Authorization header as Bearer <YOUR_API_KEY>.For GET /users (list all users):
#### 4.2. Code Structure Overview
The code will be structured into a single Python file (`panthera_api_client.py`) containing:
1. **Imports:** Necessary libraries like `requests`, `json`, `logging`, `time`.
2. **Configuration:** Constants for the API base URL and API key (ideally loaded from environment variables in a real application).
3. **Custom Exceptions:** Specific exceptions for API-related errors, allowing for granular error handling.
4. **`PantheraAPIClient` Class:**
* `__init__`: Initializes the client with the base URL and API key.
* `_make_request`: A private helper method to encapsulate common request logic (headers, error checking, retries, logging).
* Specific endpoint methods (e.g., `get_users`): Public methods that leverage `_make_request` to interact with specific API endpoints.
5. **Example Usage:** Demonstrates how to instantiate and use the client.
#### 4.3. `panthera_api_client.py`
python
import requests
import json
import logging
import time
import os
PANTHERA_API_BASE_URL = os.getenv("PANTHERA_API_BASE_URL", "https://api.pantheradata.com/v1")
PANTHERA_API_KEY = os.getenv("PANTHERA_API_KEY", "YOUR_SECURE_API_KEY_HERE") # Replace with your actual key
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
class PantheraAPIError(Exception):
"""Base exception for Panthera API errors."""
def __init__(self, message, status_code=None, error_code=None, response_data=None):
super().__init__(message)
self.status_code = status_code
self.error_code = error_code
self.response_data = response_data
logger.error(f"API Error: Status {status_code}, Code {error_code}, Message: {message}, Data: {response_data}")
class RateLimitExceededError(PantheraAPIError):
"""Exception for when API rate limits are exceeded (HTTP 429)."""
pass
class UnauthorizedError(PantheraAPIError):
"""Exception for authentication failures (HTTP 401)."""
pass
class NotFoundError(PantheraAPIError):
"""Exception for resource not found errors (HTTP 404)."""
pass
class ServerError(PantheraAPIError):
"""Exception for server-side errors (HTTP 5xx)."""
pass
class PantheraAPIClient:
"""
A client for interacting with the PantheraData API.
Handles authentication, request construction, error handling, and retries.
"""
def __init__(self, base_url: str, api_key: str, timeout: int = 30):
"""
Initializes the API client.
Args:
base_url (str): The base URL of the PantheraData API.
api_key (str): Your PantheraData API key.
timeout (int): Default timeout for HTTP requests in seconds.
"""
if not base_url:
raise ValueError("API Base URL cannot be empty.")
if not api_key:
raise ValueError("API Key cannot be empty.")
self.base_url = base_url
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"Accept": "application/json"
}
self.timeout = timeout
self.session = requests.Session() # Use a session for connection pooling and efficiency
logger.info(f"PantheraAPIClient initialized with base URL: {self.base_url}")
def _make_request(self, method: str, endpoint: str, params: dict = None, data: dict = None,
json_data: dict = None, max_retries: int = 3, backoff_factor: float = 0.5):
"""
Internal helper method to make an HTTP request to the API.
Args:
method (str): HTTP method (GET, POST, PUT, DELETE, PATCH).
endpoint (str): The API endpoint (e.g., "/users").
params (dict, optional): Dictionary of query parameters.
data (dict, optional): Dictionary of form-encoded data.
json_data (dict, optional): Dictionary of JSON data for the request body.
max_retries (int): Maximum number of retries for transient errors.
backoff_factor (float): Factor for exponential backoff between retries.
Returns:
dict: The JSON response from the API.
Raises:
PantheraAPIError: For any API-related errors.
requests.exceptions.RequestException: For network-related errors.
"""
url = f"{self.base_url}{endpoint}"
retry_count = 0
while retry_count <= max_retries:
try:
logger.debug(f"Making {method} request to {url} (Attempt {retry_count + 1}/{max_retries + 1})")
response = self.session.request(
method=method,
url=url,
headers=self.headers,
params=params,
data=data,
json=json_data,
timeout=self.timeout
)
response.raise_for_status() # Raises HTTPError for bad responses (4xx or 5xx)
# Attempt to parse JSON response
try:
return response.json()
except json.JSONDecodeError:
logger.warning(f"Failed to decode JSON response from {url}. Response text: {response.text[:200]}...")
# If API returns non-JSON for success, we might return raw text or raise a specific error
raise PantheraAPIError(
f"Failed to parse JSON response for {endpoint}",
status_code=response.status_code,
response_data=response.text
)
except requests.exceptions.HTTPError as e:
status_code = e.response.status_code
error_response_data = None
try:
error_response_data = e.response.json()
error_message = error_response_data.get("error", {}).get("message", str(e))
error_code = error_response_data.get("error", {}).get("code")
except json.JSONDecodeError:
error_message = f"HTTP Error {status_code}: {e.response.text}"
error_response_data = e.response.text
error_code = "unknown_error"
if status_code == 401:
raise UnauthorizedError(error_message, status_code, error_code, error_response_
This document outlines the completion of Step 2 of 2 in the "API Integration Builder" workflow, focusing on generating the necessary code to integrate with an external API for creating a project.
The primary objective of this step is to provide a robust, functional code snippet that enables your application to programmatically create a new project within an external project management system via its API. This integration will facilitate automated project creation, reducing manual effort and ensuring data consistency across systems.
To successfully utilize the generated code, please ensure the following critical prerequisites are met:
https://api.yourprojectmanager.com/v1/projects). This is typically a POST endpoint.\n