Llama 3.3 70B × api-client
7.7Class design + error handling + type hints + docs
correctness 8.0quality 6.0documentation 9.01706ms
$ 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.7correctness 8.0quality 6.0documentation 9.01706ms
# judge: Functionally correct with proper APIError subclass and docstrings, but lacks a requests.Session for connection reuse, has duplicated header logic, no timeout handling, and generic Dict types aren't parameterized.
$ cat llama-3.3-70b.api-client.r1.response
```python
import requests
from typing import Optional, Dict
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.
Args:
- base_url (str): The base URL of the API.
- api_key (str, optional): The API key to use for authentication. Defaults to None.
"""
def __init__(self, base_url: str, api_key: Optional[str] = None):
self.base_url = base_url
self.api_key = api_key
def get(self, path: str, params: Optional[Dict[str, str]] = None) -> Dict:
"""
Send a GET request to the API.
Args:
- path (str): The path of the API endpoint.
- params (Dict[str, str], optional): The query parameters. Defaults to None.
Returns:
- Dict: The JSON response from the API.
Raises:
- APIError: If the API returns a non-2xx status code.
"""
url = f"{self.base_url}{path}"
headers = {"Authorization": f"Bearer {self.api_key}"} if self.api_key else {}
response = requests.get(url, params=params, headers=headers)
self._check_response(response)
return response.json()
def post(self, path: str, data: Dict) -> Dict:
"""
Send a POST request to the API.
Args:
- path (str): The path of the API endpoint.
- data (Dict): The JSON data to send in the request body.
Returns:
- Dict: The JSON response from the API.
Raises:
- APIError: If the API returns a non-2xx status code.
"""
url = f"{self.base_url}{path}"
headers = {"Authorization": f"Bearer {self.api_key}"} if self.api_key else {}
response = requests.post(url, json=data, headers=headers)
self._check_response(response)
return response.json()
def _check_response(self, response: requests.Response) -> None:
"""
Check if the API response was successful.
Args:
- response (requests.Response): The API response.
Raises:
- APIError: If the API returns a non-2xx status code.
"""
if not response.ok:
raise APIError(response.status_code, response.text)
# Usage example:
if __name__ == "__main__":
client = APIClient("https://jsonplaceholder.typicode.com")
data = client.get("/posts/1")
print(data)
new_post = {"title": "My new post", "body": "This is my new post"}
created_post = client.post("/posts", new_post)
print(created_post)
```
In this code:
* We define a custom `APIError` exception to handle non-2xx API responses.
* The `APIClient` class has `get` and `post` methods for sending HTTP requests to the API.
* The `_check_response` method checks if the API response was successful and raises an `APIError` if not.
* In the usage example, we create an `APIClient` instance and use it to send GET and POST requests to a JSON placeholder API.