I'm creating a Python API client, after thinking and checking some open source Python clients I created this class, and I'm looking for any feedback (design, best practices...), this is an example URL of the API:
https://www.api.com/collection/resource.json?userid=id&key=apikey&command=value
Here's my class using the requests library:
import requests
class APIClient(object):
"""Creates an API client object
:param userid: the API userid found in the control panel
:param api_key: the API key found in the control panel Settings > API
"""
def __init__(self, userid=None, api_key=None):
# userid and api key sent with every request
self.userid = userid
self.key = api_key
# the base production api url
self.base_url = None
# the sandbox api url
self.test_url = None
# boolean value to indicate which url to use
self.testing = False
# the error description if it occured
self.error = None
def request(self, method='GET', path=None, params=None):
"""Makes a request to the API with the given parameters
:param method: the HTTP method to use
:param path: the api path to request
:param params: the parameters to be sent
"""
# if we're testing use the sandbox url
api_url = self.test_url if self.testing else self.base_url
# add the authentication parameters (sent with every request)
params.update({
'userid': self.userid,
'key': self.key
})
# the api request result
result = None
try:
# send a request to the api server
r = requests.request(
method = method,
url = api_url + path + '.json',
params = params,
headers = {'User-Agent': 'Python API Client'}
)
# raise an exception if status code is not 200
if r.status_code is not 200:
raise Exception
else:
result = r.json()
except requests.ConnectionError:
self.error = 'API connection error.'
except requests.HTTPError:
self.error = 'An HTTP error occurred.'
except requests.Timeout:
self.error = 'Request timed out.'
except Exception:
self.error = 'An unexpected error occurred.'
return result
And here's a usage example:
from api import APIClient
# create the client
api = APIClient()
# authentication
api.userid = '123456'
api.key = '0tKk8fAyHTlUv'
# api urls
api.base_url = 'https://api.com/'
api.test_url = 'https://test.api.com/'
# api in testing mode
api.testing = True
# create a request
r = api.request(
method = 'GET',
# this will be appended to the base or test url and add .json at the end
path = 'collection/resource',
params = {
'string-command': 'string',
'list-command': ['a', 'b', 'c'],
'boolean-command': False
}
)
# how can I improve the way I get the API result and the error checking ?
# I currently use:
if api.error:
print api.error
else:
print r
# what about using something like ?:
if api.request.ok:
print api.request.result
else:
print api.request.error
My questions are:
- Is this a good design for use in a website ? and is it safe for multiple requests ?
- Should I store the API result in a property
api.result
instead of returning it when callingapi.request()
? - How can I improve the way I get the API result ? is the second example better ?
- Finally how can I improve my code ?