import base64
import logging
import json
import requests


log = logging.getLogger(__name__)


class SessionError(Exception):
	"""Raised when a REST call gets a non-2XX HTTP error code."""


class Session(object):

	ENDPOINT_URL = 'https://www.clevertim.com/api'

	def __init__(self, api_key, endpoint_url=None):
		assert api_key, "Empty API key"
		self.api_key = api_key
		endpoint_url = endpoint_url or self.ENDPOINT_URL
		self.endpoint_url = endpoint_url.rstrip('/')

	def _get_url(self, endpoint, resource_id=None):
		url = self.endpoint_url
		if not endpoint.startswith('/'):
			url += '/'
		url += endpoint.rstrip('/')
		if resource_id:
			url += '/' + str(resource_id)
		return url

	def make_request(self, endpoint, resource_id=None, method='GET', payload=None):
		assert endpoint, "Empty endpoint"

		auth_token = base64.standard_b64encode(self.api_key + ':X')
		headers = {
			'Authorization': 'Basic %s' % (auth_token,),
			'Content-Type': 'application/json',
			'Accept': 'application/json'
		}

		url = self._get_url(endpoint, resource_id=resource_id)

		if method == "GET":
			log.debug("GET %s", url)
			r = requests.get(url, headers = headers)
		elif method == "POST":
			log.debug("POST %s %s", url, payload)
			r = requests.post(url, headers = headers, data = payload)
		elif method == "PUT":
			log.debug("PUT %s %s", url, payload)
			r = requests.put(url, headers = headers, data = payload)
		elif method == "DELETE":
			log.debug("DELETE %s", url)
			r = requests.delete(url, headers = headers)
		else:
			assert False, "Unknown method: '%s'" % (method,)

		status_code = r.status_code
		response = r.text

		if status_code != 200:
			raise SessionError("HTTP %s - %s" % (status_code, response))

		log.debug("Response %s %s", r.status_code, response)
		if response:
			return json.loads(response)

@@ -299,27 +299,48 @@
 int_url=None
+, enable_caching=True
 ):%0A
-
 %09%09assert api
@@ -483,16 +483,112 @@
 rip('/')
+%0A%09%09self.enable_caching = enable_caching%0A%09%09# used to cache GET requests%0A%09%09self.session_cache = %7B%7D
 %0A%0A%09def _
@@ -800,16 +800,109 @@
 rn url%0A%0A
+%09def _get_cache_key(self, endpoint, resource_id):%0A%09%09return '%25s%25s' %25 (endpoint, resource_id)%0A%0A
 %09def mak
@@ -967,24 +967,38 @@
 payload=None
+, reload=False
 ):%0A%09%09assert 
@@ -1283,16 +1283,35 @@
 ce_id)%0A%0A
+%09%09cache_key = None%0A
 %09%09if met
@@ -1320,24 +1320,248 @@
 d == %22GET%22:%0A
+%09%09%09if self.enable_caching:%0A%09%09%09%09cache_key = self._get_cache_key(endpoint, resource_id)%0A%09%09%09%09if not reload:%0A%09%09%09%09%09ret = self.session_cache.get(cache_key)%0A%09%09%09%09%09if ret:%0A%09%09%09%09%09%09log.debug(%22cache hit on GET %25s%22, url)%0A%09%09%09%09%09%09return ret%0A
 %09%09%09log.debug
@@ -2231,26 +2231,32 @@
 response)%0A%09%09
-if
+result =
  response:%0A%09
@@ -2256,37 +2256,241 @@
 onse
-:%0A%09%09%09return json.loads(response)
+ and json.loads(response) or None%0A%0A%09%09# update the cache%0A%09%09if cache_key:%0A%09%09%09if result is not None:%0A%09%09%09%09self.session_cache%5Bcache_key%5D = result%0A%09%09%09elif cache_key in self.session_cache:%0A%09%09%09%09del self.session_cache%5Bcache_key%5D%0A%0A%09%09return result
 %0A

add support for a session cache for GET requests