Llama 3.3 70B × api-client
7.0Class design + error handling + type hints + docs
correctness 7.0quality 6.0documentation 8.01859ms
$ cat api-client.prompt — what the model was asked
Write a Python class `APIClient` that wraps the `requests` library for a REST API. It should: (1) accept a base_url and optional api_key in __init__, (2) have a `get(path, params=None)` method and a `post(path, data)` method, (3) raise a custom `APIError` exception with the status code and message on non-2xx responses, (4) include type hints throughout, (5) have a complete docstring on the class and each public method. Show a usage example at the bottom.
run 1 of 1
7.0correctness 7.0quality 6.0documentation 8.01859ms
# judge: Solid, working implementation with correct type hints and proper APIError subclass, but doesn't use requests.Session for connection reuse, uses naive string concatenation for URLs instead of urljoin, and lacks timeout/error handling for non-JSON responses.
$ cat llama-3.3-70b.api-client.r1.response
```python
import requests
from typing import Optional, Dict, Any
class APIError(Exception):
"""Custom exception for API errors."""
def __init__(self, status_code: int, message: str):
self.status_code = status_code
self.message = message
super().__init__(f"API Error {status_code}: {message}")
class APIClient:
"""
A client for interacting with a REST API.
Attributes:
base_url (str): The base URL of the API.
api_key (Optional[str]): The API key for authentication (optional).
Methods:
get(path: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: Send a GET request to the API.
post(path: str, data: Dict[str, Any]) -> Dict[str, Any]: Send a POST request to the API.
"""
def __init__(self, base_url: str, api_key: Optional[str] = None):
"""
Initialize the API client.
Args:
base_url (str): The base URL of the API.
api_key (Optional[str]): The API key for authentication (optional).
"""
self.base_url = base_url
self.api_key = api_key
def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""
Send a GET request to the API.
Args:
path (str): The path of the API endpoint.
params (Optional[Dict[str, Any]]): The query parameters (optional).
Returns:
Dict[str, Any]: The response data.
Raises:
APIError: If the response status code is not 2xx.
"""
url = self.base_url + path
headers = {"Authorization": f"Bearer {self.api_key}"} if self.api_key else {}
response = requests.get(url, headers=headers, params=params)
self._check_response(response)
return response.json()
def post(self, path: str, data: Dict[str, Any]) -> Dict[str, Any]:
"""
Send a POST request to the API.
Args:
path (str): The path of the API endpoint.
data (Dict[str, Any]): The request body data.
Returns:
Dict[str, Any]: The response data.
Raises:
APIError: If the response status code is not 2xx.
"""
url = self.base_url + path
headers = {"Authorization": f"Bearer {self.api_key}"} if self.api_key else {}
response = requests.post(url, headers=headers, json=data)
self._check_response(response)
return response.json()
def _check_response(self, response: requests.Response) -> None:
"""
Check if the response status code is 2xx and raise an APIError if not.
Args:
response (requests.Response): The response object.
"""
if not response.ok:
raise APIError(response.status_code, response.text)
# Usage example:
if __name__ == "__main__":
client = APIClient("https://example.com/api", "your_api_key")
try:
response = client.get("/users")
print(response)
client.post("/users", {"name": "John Doe", "email": "john@example.com"})
except APIError as e:
print(f"API Error {e.status_code}: {e.message}")
```
In this code:
* We define a custom `APIError` exception class to represent API errors with a status code and message.
* The `APIClient` class is initialized with a `base_url` and an optional `api_key` for authentication.
* The `get` and `post` methods send GET and POST requests to the API, respectively, and return the response data as a dictionary.
* The `_check_response` method checks if the response status code is 2xx and raises an `APIError` if not.
* In the usage example, we create an instance of the `APIClient` class, send a GET request to retrieve users, and send a POST request to create a new user. We also catch and handle any `APIError` exceptions that may occur.