Comments on client

This commit is contained in:
Maël Kervella 2018-05-25 13:34:47 +00:00
parent 5de13c6467
commit b27e5cc92e

View file

@ -9,13 +9,33 @@ import stat
from . import endpoints
from . import exceptions
# Number of seconds before expiration where renewing the token is done
TIME_FOR_RENEW = 60
# Default name of the file to store tokens
DEFAULT_TOKEN_FILENAME = '.re2o.token'
class Re2oAPIClient:
"""
Object to handle the requests to Re2o API in a seemless way.
You must first initialize the client and then you can access
the API with dedicated functions that handle the authentication
process
"""
def __init__(self, hostname, username, password, token_file=None, use_tls=True):
"""
Create an API client.
:param hostname: (str) The hostname of the Re2o server to use
:param username: (str) The username to use
:param password: (str) The password to use
:param token_file: (str) A path to a file where re2o tokens are stored
If `None`, then `$HOME/DEFAULT_TOKEN_FILENAME` is used.
(Default: None)
:param use_tls: (bool) Should the client used TLS (recommended for
production). (Default: True)
"""
self.use_tls = use_tls
self.token_file = token_file or Path.home() / DEFAULT_TOKEN_FILENAME
self.hostname = hostname
@ -34,6 +54,10 @@ class Re2oAPIClient:
@property
def need_renew_token(self):
"""
True is the token expiration time is within less than `TIME_FOR_RENEW`
seconds
"""
return self.token['expiration'] > \
datetime.datetime.now(datetime.timezone.utc) + \
datetime.timedelta(seconds=TIME_FOR_RENEW)
@ -91,12 +115,23 @@ class Re2oAPIClient:
}
def get_token(self):
"""
Returns the token for the current connection
"""
if self.need_renew_token:
self.token = self._get_token_from_server()
return self.token['token']
def get(self, url, headers={}, params={}, *args, **kwargs):
headers = kwargs.pop('headers', {})
"""
GET requests on a given URL that acts like `requests.get` except that
authentication to the API is automatically done and JSON response is
decoded
:param url: (str) URL of the requests
:param: See `requests.get` params
:returns: (dict) The JSON-decoded result of the request
"""
headers.update({
'Authorization': 'Token {}'.format(self.get_token())
})
@ -107,7 +142,15 @@ class Re2oAPIClient:
return response.json()
def post(self, url, headers={}, params={}, *args, **kwargs):
headers = kwargs.pop('headers', {})
"""
POST requests on a given URL that acts like `requests.past` except
that authentication to the API is automatically done and JSON response
is decoded
:param url: (str) URL of the requests
:param: See `requests.post` params
:returns: (dict) The JSON-decoded result of the request
"""
headers.update({
'Authorization': 'Token {}'.format(self.get_token())
})
@ -118,6 +161,14 @@ class Re2oAPIClient:
return response.json()
def get_url_for(self, name, **kwargs):
"""
Retrieve the complete URL to use for a given endpoint's name
:param name: The name of the endpoint to look for.
`re2oapi.exception.NameNotExists` is raised of the name does not
correspond to any endpoint
:param kwargs: A dict with the parameters to use to format the URL
"""
return '{proto}://{host}{endpoint}'.format(
proto=('https' if self.use_tls else 'http'),
host=self.hostname,