import urllib
import urlparse

import requests

class ResponseError(Exception):

    def __init__(self, response, description, *args, **kwargs):
        self.response = response
        self.description = description
        self.status_code = response.status_code
        self.content = response.content
        super(ResponseError, self).__init__(*args, **kwargs)

    def __repr__(self):
        return 'Error status code: {}. Description: {}'.format(self.response.status_code, self.description)

    def __str__(self):
        return self.__repr__()

    def __unicode__(self):
        return self.__str__().decode()


class _client_request(object):
    def __init__(self, client, resource='/', method='get'):
        self.client = client
        self.resource = resource
        self.method = method

    def __call__(self, *args, **kwargs):
        method = getattr(self.client, self.method)
        return method(resource=self.resource, *args, **kwargs)


class _requests_method(object):
    def __init__(self, client, method):
        self.method = method
        self.client = client

    def __call__(self, resource='/', response_key=None, query=None, data=None, timeout=60, **kwargs):
        if data is not None:
            kwargs['json'] = data
        response = requests.request(self.method, self.client.url_for(resource, query), timeout=timeout, **kwargs)
        return self.client.handle_response(response, response_key=response_key)


class Resource(object):
    def __init__(self, client, resource='/'):
        self.client = client
        self.resource = resource

    def __getattr__(self, item):
        return _client_request(self.client, self.resource, item)


class Client(object):
    ok_statuses = (200, 202, )
    to_none_statuses = (404,)

    def __init__(self, endpoint, ok_statuses=None, to_none_statuses=None, empty_to_none=True):
        if endpoint.endswith('/'):
            endpoint = endpoint[:-1]
        if ok_statuses is not None:
            self.ok_statuses = ok_statuses
        if to_none_statuses is not None:
            self.to_none_statuses = to_none_statuses
        self.empty_to_none = empty_to_none
        self.endpoint = endpoint

    def url_for(self, resource='/', query=None):
        parsed_url = list(urlparse.urlparse(self.endpoint))
        parsed_url[2] = resource
        if query is not None:
            parsed_url[4] = urllib.urlencode(query, doseq=1)
        return urlparse.urlunparse(parsed_url)

    # result None if error
    def handle_response(self, response, response_key=None):
        status_code = response.status_code
        try:
            result = response.json()
        except Exception as e:
            raise ResponseError(response, str(e))

        if result:
            if response_key is not None and status_code in self.ok_statuses:
                if response_key in result:
                    result = result[response_key]
                else:
                    raise ResponseError(response, 'Response key not found!')
            elif response_key is not None and status_code in self.to_none_statuses:
                result = None
        if response_key is not None and self.empty_to_none and result is not None and not result:
            result = None

        return result

    def __getattr__(self, item):
        return _requests_method(self, item)

    def resource(self, resource='/'):
        return Resource(client=self, resource=resource)

@@ -41,16 +41,17 @@
 quests%0A%0A
+%0A
 class Re
@@ -74,17 +74,16 @@
 ption):%0A
-%0A
     def 
@@ -686,20 +686,17 @@
 resource
-='/'
+s
 , method
@@ -746,32 +746,33 @@
    self.resource
+s
  = resource%0A    
@@ -758,32 +758,33 @@
 urces = resource
+s
 %0A        self.me
@@ -902,46 +902,59 @@
     
-return method(resource=self.resource, 
+args = self.resources + args%0A        return method(
 *arg
@@ -1097,16 +1097,271 @@
 = client
+%0A        self.close_slash = client.close_slash%0A%0A    def build_resource(self, resources):%0A        resource = '/'.join(resources)%0A        if self.close_slash:%0A            if not resource.endswith('/'):%0A                resource += '/'%0A        return resource
 %0A%0A    de
@@ -1373,32 +1373,33 @@
 all__(self, 
+*
 resource
 ='/', respon
@@ -1390,78 +1390,350 @@
 urce
-='/', response_key=None, query=None, data=None, timeout=60, **kwargs):
+s, **kwargs):%0A        response_key = kwargs.pop('response_key', None)%0A        key = kwargs.pop('key', None)%0A        if key is not None:%0A            response_key = key%0A        query = kwargs.pop('query', None)%0A        data = kwargs.pop('data', None)%0A        timeout = kwargs.pop('timeout', 60)%0A        resource = self.build_resource(resources)
 %0A   
@@ -2043,36 +2043,33 @@
 client, resource
-='/'
+s
 ):%0A        self.
@@ -2105,16 +2105,17 @@
 resource
+s
  = resou
@@ -2109,32 +2109,33 @@
 urces = resource
+s
 %0A%0A    def __geta
@@ -2210,16 +2210,17 @@
 resource
+s
 , item)%0A
@@ -2271,17 +2271,16 @@
 00, 202,
- 
 )%0A    to
@@ -2396,16 +2396,34 @@
 one=True
+, close_slash=True
 ):%0A     
@@ -2701,24 +2701,63 @@
 pty_to_none%0A
+        self.close_slash = close_slash%0A
         self
@@ -3063,35 +3063,8 @@
 l)%0A%0A
-    # result None if error%0A
     
@@ -3941,32 +3941,33 @@
 ource(self, 
+*
 resource
 ='/'):%0A     
@@ -3954,20 +3954,17 @@
 resource
-='/'
+s
 ):%0A     
@@ -3986,15 +3986,8 @@
 rce(
-client=
 self
@@ -4000,15 +4000,7 @@
 urce
-=resource
+s
 )%0A

upgrade client, add simple resource builder