PYTHON
Generic Python API Wrapper for Consistent Interactions
Build a reusable Python class to encapsulate API interactions, handling base URLs, headers, and error responses for cleaner and more maintainable API integrations.
import requests
import json
class ApiWrapper:
def __init__(self, base_url, api_key=None, default_headers=None):
self.base_url = base_url.rstrip('/')
self.headers = {'Content-Type': 'application/json'}
if api_key:
self.headers['Authorization'] = f'Bearer {api_key}'
if default_headers:
self.headers.update(default_headers)
def _request(self, method, endpoint, params=None, data=None, json_data=None, headers=None):
url = f"{self.base_url}/{endpoint.lstrip('/')}"
request_headers = self.headers.copy()
if headers:
request_headers.update(headers)
try:
response = requests.request(
method,
url,
params=params,
data=data,
json=json_data,
headers=request_headers,
timeout=10 # Add a timeout for robustness
)
response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
return response.json() if response.text else {}
except requests.exceptions.HTTPError as e:
try:
error_details = e.response.json()
except json.JSONDecodeError:
error_details = e.response.text
print(f"HTTP Error for {url}: {e.response.status_code} - {error_details}")
raise
except requests.exceptions.ConnectionError as e:
print(f"Connection Error for {url}: {e}")
raise
except requests.exceptions.Timeout as e:
print(f"Timeout Error for {url}: {e}")
raise
except requests.exceptions.RequestException as e:
print(f"An unexpected error occurred for {url}: {e}")
raise
def get(self, endpoint, params=None, headers=None):
return self._request('GET', endpoint, params=params, headers=headers)
def post(self, endpoint, data=None, json_data=None, headers=None):
return self._request('POST', endpoint, data=data, json_data=json_data, headers=headers)
def put(self, endpoint, data=None, json_data=None, headers=None):
return self._request('PUT', endpoint, data=data, json_data=json_data, headers=headers)
def delete(self, endpoint, headers=None):
return self._request('DELETE', endpoint, headers=headers)
# Example Usage:
# API_BASE_URL = "https://api.example.com"
# API_KEY = "your_secret_api_key"
# my_api = ApiWrapper(API_BASE_URL, api_key=API_KEY)
# try:
# # Fetch users
# users = my_api.get("/users", params={"limit": 5})
# print("Users:", users)
# # Create a new item
# new_item = my_api.post("/items", json_data={"name": "New Widget", "price": 29.99})
# print("New Item:", new_item)
# # Update an item
# updated_item = my_api.put("/items/123", json_data={"price": 34.99})
# print("Updated Item:", updated_item)
# except Exception as e:
# print(f"API interaction failed: {e}")
How it works: This Python `ApiWrapper` class provides a structured way to interact with an external REST API. It centralizes the base URL, default headers (like authentication tokens and content type), and robust error handling for various HTTP and network issues. By abstracting the `requests` library calls into `get`, `post`, `put`, and `delete` methods, it promotes consistency, reduces code duplication, and makes API integrations easier to manage and debug in a larger application.