Commits

Anonymous committed a52f564

removed *ResourceResult objects, too muhc complexity and not so usefull.
Now all tests pass and we get full unicode in response. While I'm here
change the Response object, now this is a real dict in which yould get
headers like httplib2.

Comments (0)

Files changed (8)

File contents unchanged.
File contents unchanged.

README.TXT

File contents unchanged.
     >>> res = Resource('http://friendpaste.com')
     >>> res.get('/5rOqE9XTz7lccLgZoQS4IP',headers={'Accept': 'application/json'})
     u'{"snippet": "hi!", "title": "", "id": "5rOqE9XTz7lccLgZoQS4IP", "language": "text", "revision": "386233396230"}'
-    >>> res.get('/5rOqE9XTz7lccLgZoQS4IP',headers={'Accept': 'application/json'}).http_code
+    >>> res.status
     200
 """
 import urllib
 
 __all__ = ['Resource', 'RestClient', 'ResourceNotFound', \
         'Unauthorized', 'RequestFailed', 'ResourceError',
-        'StrResourceResult', 'UnicodeResourceResult', 'RequestError']
+        'RequestError']
 __docformat__ = 'restructuredtext en'
 
 
     """Exception raised when a request is malformed"""
 
 
-class StrResourceResult(str):
-    """ result returned by `restclient.rest.RestClient`.
-    
-    you can get result like as string and  status code by result.http_code, 
-    or see anything about the response via result.response. For example, the entire 
-    result body is result.response.body.
-
-    .. code-block:: python
-
-            from restclient import RestClient
-            client = RestClient()
-            page = resource.request('GET', 'http://friendpaste.com')
-            print page
-            print "http code %s" % page.http_code
-
-    """
-    def __new__(cls, s, http_code, response):
-        self = str.__new__(cls, s)
-        self.http_code = http_code
-        self.response = response
-        return self
-
-class UnicodeResourceResult(unicode):
-    """ result returned by `restclient.rest.RestClient`.
-    
-    you can get result like as string and  status code by result.http_code, 
-    or see anything about the response via result.response. For example, the entire 
-    result body is result.response.body.
-
-    .. code-block:: python
-
-            from restclient import RestClient
-            client = RestClient()
-            page = resource.request('GET', 'http://friendpaste.com')
-            print page
-            print "http code %s" % page.http_code
-
-    """
-    def __new__(cls, s, http_code, response):
-        if not isinstance(s, unicode):
-            s = s.decode('utf-8')
-        self = unicode.__new__(cls, s)
-        self.http_code = http_code
-        self.response = response
-        return self
-
 class Resource(object):
     """A class that can be instantiated for access to a RESTful resource, 
     including authentication. 
         return self.client.request(method, self.uri, path=path,
                 body=payload, headers=headers, **params)
 
+    def get_response(self):
+        return self.client.get_response()
+    response = property(get_response)
+
+    def get_status(self):
+        return self.client.status
+    status = property(get_status)
+
     def update_uri(self, path):
         """
         to set a new uri absolute path
 
         self.transport = transport
 
-        self.status_code = None
+        self.status = None
         self.response = None
 
     def get(self, uri, path=None, headers=None, **params):
             if not 'Content-Length' in headers:
                 raise RequestError("'Content-Length' should be specified when body is a File like instance") 
         elif body is not None:
-            if not isinstance(body, unicode):            
-                is_unicode = False
             body = to_bytestring(body)
 
         try:
         except TransportError, e:
             raise RequestError(e)
 
-        status_code = int(resp.status)
-
+        self.status  = status_code = resp.status
+        self.response = resp
+        
         if status_code >= 400:
             if type(data) is dict:
                 error = (data.get('error'), data.get('reason'))
                 raise RequestFailed(error, http_code=status_code,
                     response=resp)
 
-        if not is_unicode:
-            return StrResourceResult(data, status_code, resp)
+        
         try:
-            return UnicodeResourceResult(data, status_code, resp)
+            return data.decode('utf-8')
         except UnicodeDecodeError:
-            return StrResourceResult(data, status_code, resp)
+            pass    
+        return data 
+
+    def get_response(self):
+        return self.response
 
     def make_uri(self, base, *path, **query):
         """Assemble a uri based on a base, any number of path segments, and query

restclient/transport.py

                                           self.status,
                                           self.final_url)
 
+class HTTPResponse(dict):
+    """An object more like email.Message than httplib.HTTPResponse."""
+
+    final_url = None
+    
+    "Status code returned by server. "
+    status = 200
+
+    """Reason phrase returned by server."""
+    reason = "Ok"
+
+    def __init__(self, info):
+        for key, value in info.iteritems(): 
+            self[key] = value 
+        self.status = int(self.get('status', self.status))
+        self.final_url = self.get('final_url', self.final_url)
+
+    def __getattr__(self, name):
+        if name == 'dict':
+            return self 
+        else:  
+            raise AttributeError, name
+
+    def __repr__(self):
+        return "<%s status %s for %s>" % (self.__class__.__name__,
+                                          self.status,
+                                          self.final_url)
+
+
+
+
 class HTTPTransportBase(object):
     """ Interface for HTTP clients """
 
 
     def _make_response(self, final_url=None, status=None, headers=None,
             body=None):
-        resp = HTTPResponse()
-        resp.headers = headers or {}
-        resp.status = status
-        resp.final_url = final_url
-        resp.body = body
+        infos = headers or {}
+        infos.update({
+            'status': status,
+            'final_url': final_url
+        })
+        resp = HTTPResponse(infos)
         return resp, body 
     
 class HTTPLib2Transport(HTTPTransportBase):
         except KeyError:
             final_url = url
 
-        resp = HTTPResponse()
-        resp.headers = dict(httplib2_response.items())
-        resp.status = int(httplib2_response.status)
-        resp.final_url = final_url
-        resp.body = content
-
+        
+        resp = HTTPResponse(httplib2_response)
         return resp, content
 
     def add_credentials(self, user, password):

tests/_server_test.py

         for k, v in cgi.parse_qsl(self.parsed_uri[4]):
             self.query[k] = v.decode('utf-8')
         path = self.parsed_uri[2]
-        print path 
 
         if path == "/":
             extra_headers = [('Content-type', 'text/plain')]

tests/resource_test.py

     def testGet(self):
         result = self.res.get()
         self.assert_(result == "welcome")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testUnicode(self):
         result = self.res.get('/unicode')
     def testUrlWithAccents(self):
         result = self.res.get('/éàù')
         self.assert_(result == "ok")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testUrlUnicode(self):
         result = self.res.get(u'/test')
         self.assert_(result == "ok")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
         result = self.res.get(u'/éàù')
         self.assert_(result == "ok")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testGetWithContentType(self):
         result = self.res.get('/json', headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
         def bad_get():
             result = self.res.get('/json', headers={'Content-Type': 'text/plain'})
         self.assertRaises(RequestFailed, bad_get) 
 
     def testGetWithQuery(self):
         result = self.res.get('/query', test="testing")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testGetWithIntParam(self):
         result = self.res.get('/qint', test=1)
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testSimplePost(self):
         result = self.res.post(payload="test")
 
     def testPostByteString(self):
         result = self.res.post('/bytestring', payload="éàù@")
-        self.assert_(result == "éàù@")
+        self.assert_(result == u"éàù@")
 
     def testPostUnicode(self):
         result = self.res.post('/unicode', payload=u"éàù@")
     def testPostWithContentType(self):
         result = self.res.post('/json', payload="test",
                 headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
         def bad_post():
             result = self.res.post('/json', payload="test",
                     headers={'Content-Type': 'text/plain'})
     def testEmptyPost(self):
         result = self.res.post('/empty', payload="",
                 headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
         result = self.res.post('/empty',headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
 
     def testPostWithQuery(self):
         result = self.res.post('/query', test="testing")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testSimplePut(self):
         result = self.res.put(payload="test")
     def testPutWithContentType(self):
         result = self.res.put('/json', payload="test",
                 headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
         def bad_put():
             result = self.res.put('/json', payload="test",
                     headers={'Content-Type': 'text/plain'})
     def testEmptyPut(self):
         result = self.res.put('/empty', payload="",
                 headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
         result = self.res.put('/empty',headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
 
     def testPutWithQuery(self):
         result = self.res.put('/query', test="testing")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testHead(self):
         result = self.res.head('/ok')
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testDelete(self):
         result = self.res.delete('/delete')
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testFileSend(self):
         content_length = len("test")
                     'Content-Length': str(content_length)
                 })
 
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
 
     def testFileSend2(self):
         import StringIO
 
         res = Resource(self.url, transport)
         result = res.get('/auth')
-        self.assert_(result.http_code == 200)
+        self.assert_(res.response.status == 200)
 
         transport = HTTPLib2Transport()
         def niettest():

tests/transports_test.py

     def testUrlWithAccents(self):
         result = self.res.get('/éàù')
         self.assert_(result == "ok")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testUrlUnicode(self):
         result = self.res.get(u'/test')
         self.assert_(result == "ok")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
+
+        result = self.res.get(u'/éàù')
+        self.assert_(result == "ok")
+        self.assert_(self.res.response.status == 200)
 
     def testGetWithContentType(self):
         result = self.res.get('/json', headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
         def bad_get():
             result = self.res.get('/json', headers={'Content-Type': 'text/plain'})
         self.assertRaises(RequestFailed, bad_get) 
 
     def testGetWithQuery(self):
         result = self.res.get('/query', test="testing")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
+
+    def testGetBinary(self):
+        import imghdr
+        import tempfile
+        res = Resource('http://e-engura.org', self.httptransport)
+        result = res.get('/images/logo.gif')
+        self.assert_(res.response.status == 200)
+        fd, fname = tempfile.mkstemp(suffix='.gif')
+        f = os.fdopen(fd, "wb")
+        f.write(result)
+        f.close()
+        self.assert_(imghdr.what(fname) == 'gif')
 
 
     def testSimplePost(self):
 
     def testPostByteString(self):
         result = self.res.post('/bytestring', payload="éàù@")
-        self.assert_(result == "éàù@")
+        self.assert_(result == u"éàù@")
 
     def testPostUnicode(self):
         result = self.res.post('/unicode', payload=u"éàù@")
     def testPostWithContentType(self):
         result = self.res.post('/json', payload="test",
                 headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
         def bad_post():
             result = self.res.post('/json', payload="test",
                     headers={'Content-Type': 'text/plain'})
     def testEmptyPost(self):
         result = self.res.post('/empty', payload="",
                 headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
         result = self.res.post('/empty',headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
 
     def testPostWithQuery(self):
         result = self.res.post('/query', test="testing")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testSimplePut(self):
         result = self.res.put(payload="test")
     def testPutWithContentType(self):
         result = self.res.put('/json', payload="test",
                 headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
         def bad_put():
             result = self.res.put('/json', payload="test",
                     headers={'Content-Type': 'text/plain'})
     def testEmptyPut(self):
         result = self.res.put('/empty', payload="",
                 headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
         result = self.res.put('/empty',headers={'Content-Type': 'application/json'})
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
 
     def testPuWithQuery(self):
         result = self.res.put('/query', test="testing")
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testHead(self):
         result = self.res.head('/ok')
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testDelete(self):
         result = self.res.delete('/delete')
-        self.assert_(result.http_code == 200)
+        self.assert_(self.res.response.status == 200)
 
     def testFileSend(self):
         content_length = len("test")
                     'Content-Length': str(content_length)
                 })
 
-        self.assert_(result.http_code == 200 )
+        self.assert_(self.res.response.status == 200 )
 
     def testAuth(self):
         httptransport = self.httptransport 
         
         res = Resource(self.url, httptransport)
         result = res.get('/auth')
-        self.assert_(result.http_code == 200)
+        self.assert_(res.response.status == 200)
 
         httptransport.add_credentials("test", "test2")