Revision e3fd7f91 pithos/lib/client.py

b/pithos/lib/client.py
4 4
import json
5 5
import types
6 6
import socket
7
import pithos.api.faults
8

  
9
ERROR_CODES = {304:'Not Modified',
10
               400:'Bad Request',
11
               401:'Unauthorized',
12
               404:'Not Found',
13
               409:'Conflict',
14
               411:'Length Required',
15
               412:'Precondition Failed',
16
               416:'Range Not Satisfiable',
17
               422:'Unprocessable Entity',
18
               503:'Service Unavailable'}
7 19

  
8 20
class Fault(Exception):
9
    def __init__(self, data=''):
21
    def __init__(self, data='', status=None):
22
        if data == '' and status in ERROR_CODES.keys():
23
            data = ERROR_CODES[status]
10 24
        Exception.__init__(self, data)
11 25
        self.data = data
12

  
26
        self.status = status
13 27

  
14 28
class Client(object):
15 29
    def __init__(self, host, account, api='v1', verbose=False, debug=False):
......
20 34
        self.api = api
21 35
        self.verbose = verbose or debug
22 36
        self.debug = debug
23
    
37

  
24 38
    def _chunked_transfer(self, path, method='PUT', f=stdin, headers=None,
25 39
                          blocksize=1024):
26 40
        http = HTTPConnection(self.host)
......
58 72
        
59 73
        # get response
60 74
        resp = http.getresponse()
75
        
61 76
        headers = dict(resp.getheaders())
62 77
        
63 78
        if self.verbose:
......
71 86
            print data
72 87
            print
73 88
        
89
        if data:
90
            assert data[-1] == '\n'
91
        #remove trailing enter
92
        data = data and data[:-1] or data
93
        
94
        if int(resp.status) in ERROR_CODES.keys():
95
            raise Fault(data, int(resp.status))
96
        
74 97
        return resp.status, headers, data
75 98

  
76 99
    def req(self, method, path, body=None, headers=None, format='text',
......
96 119
            kwargs['body'] = body
97 120
            kwargs['headers']['Content-Type'] = 'application/octet-stream'
98 121
        #print '****', method, full_path, kwargs
99
        #TODO catch socket.error
100
        conn.request(method, full_path, **kwargs)
122
        try:
123
            conn.request(method, full_path, **kwargs)
124
        except socket.error, e:
125
            raise Fault(status=503)
126
            
101 127
        resp = conn.getresponse()
102 128
        headers = dict(resp.getheaders())
103 129
        
......
117 143
        #remove trailing enter
118 144
        data = data and data[:-1] or data
119 145
        
146
        if int(resp.status) in ERROR_CODES.keys():
147
            raise Fault(data, int(resp.status))
148
        
149
        #print '*',  resp.status, headers, data
120 150
        return resp.status, headers, data
121 151

  
122 152
    def delete(self, path, format='text'):
......
147 177

  
148 178
    def _get_metadata(self, path, prefix=None, params=None):
149 179
        status, headers, data = self.head(path, params=params)
150
        if status == '404':
151
            return None
152 180
        prefixlen = prefix and len(prefix) or 0
153 181
        meta = {}
154 182
        for key, val in headers.items():
......
189 217
        if status == 202:
190 218
            return False
191 219
        elif status != 201:
192
            raise Fault(data)
220
            raise Fault(data, int(status))
193 221
        return True
194 222

  
195 223
    def delete_container(self, container):
......
222 250
        path = '/%s/%s' % (container, object)
223 251
        if not chunked and f != stdin:
224 252
            data = f and f.read() or None
225
            self.put(path, data, headers=headers)
253
            return self.put(path, data, headers=headers)
226 254
        else:
227
            self._chunked_transfer(path, 'PUT', f, headers=headers,
255
            return self._chunked_transfer(path, 'PUT', f, headers=headers,
228 256
                                   blocksize=1024)
229 257

  
230 258
    def update_object(self, container, object, f=stdin, chunked=False,

Also available in: Unified diff