Revision bcb7c5a8 pithos/lib/client.py

b/pithos/lib/client.py
59 59
        self.status = status
60 60

  
61 61
class Client(object):
62
    def __init__(self, host, account, api='v1', verbose=False, debug=False):
62
    def __init__(self, host, token, account, api='v1', verbose=False, debug=False):
63 63
        """`host` can also include a port, e.g '127.0.0.1:8000'."""
64 64
        
65 65
        self.host = host
......
67 67
        self.api = api
68 68
        self.verbose = verbose or debug
69 69
        self.debug = debug
70
        self.token = token
70 71
    
71 72
    def _chunked_transfer(self, path, method='PUT', f=stdin, headers=None,
72 73
                          blocksize=1024):
......
75 76
        # write header
76 77
        path = '/%s/%s%s' % (self.api, self.account, path)
77 78
        http.putrequest(method, path)
79
        http.putheader('X-Auth-Token', self.token)
78 80
        http.putheader('Content-Type', 'application/octet-stream')
79 81
        http.putheader('Transfer-Encoding', 'chunked')
80 82
        if headers:
......
141 143
        
142 144
        kwargs = {}
143 145
        kwargs['headers'] = headers or {}
146
        kwargs['headers']['X-Auth-Token'] = self.token
144 147
        if not headers or \
145 148
        'Transfer-Encoding' not in headers \
146 149
        or headers['Transfer-Encoding'] != 'chunked':
147 150
            kwargs['headers']['Content-Length'] = len(body) if body else 0
148 151
        if body:
149 152
            kwargs['body'] = body
150
            kwargs['headers']['Content-Type'] = 'application/octet-stream'
151
        #print '****', method, full_path, kwargs
153
        kwargs['headers'].setdefault('Content-Type', 'application/octet-stream')
152 154
        try:
153 155
            conn.request(method, full_path, **kwargs)
154 156
        except socket.error, e:
......
196 198
        status, headers, data = self.get(path, format=format, headers=headers,
197 199
                                         params=params)
198 200
        if detail:
199
            data = json.loads(data)
201
            data = json.loads(data) if data else ''
200 202
        else:
201 203
            data = data.strip().split('\n')
202 204
        return data
......
258 260
    def delete_account_metadata(self, meta=[]):
259 261
        self._delete_metadata('', 'account', meta)
260 262
    
261
    def set_account_groups(self, groups):
263
    def set_account_groups(self, **groups):
262 264
        headers = {}
263 265
        for key, val in groups.items():
264 266
            headers['X-Account-Group-%s' % key.capitalize()] = val
......
283 285
    def _filter_trashed(self, l):
284 286
        return self._filter(l, {'trash':'true'})
285 287
    
286
    def list_objects(self, container, detail=False, params=None, headers=None,
287
                     include_trashed=False):
288
    def list_objects(self, container, detail=False, headers=None,
289
                     include_trashed=False, **params):
288 290
        l = self._list('/' + container, detail, params, headers)
289 291
        if not include_trashed:
290 292
            l = self._filter_trashed(l)
291 293
        return l
292 294
    
293
    def create_container(self, container, headers=None):
295
    def create_container(self, container, headers=None, **meta):
296
        for k,v in meta.items():
297
            headers['X_CONTAINER_META_%s' %k.strip().upper()] = v.strip()
294 298
        status, header, data = self.put('/' + container, headers=headers)
295 299
        if status == 202:
296 300
            return False
......
314 318
        path = '/%s' % (container)
315 319
        self._delete_metadata(path, 'container', meta)
316 320
    
321
    def set_container_policies(self, container, **policies):
322
        path = '/%s' % (container)
323
        headers = {}
324
        print ''
325
        for key, val in policies.items():
326
            headers['X-Container-Policy-%s' % key.capitalize()] = val
327
        self.post(path, headers=headers)
328
    
317 329
    # Storage Object Services
318 330
    
319 331
    def retrieve_object(self, container, object, detail=False, headers=None,
......
331 343
        self.create_object(container, object, f=None, headers=h)
332 344
    
333 345
    def create_object(self, container, object, f=stdin, chunked=False,
334
                      blocksize=1024, headers=None):
346
                      blocksize=1024, headers=None, use_hashes=False, **meta):
335 347
        """
336 348
        creates an object
337 349
        if f is None then creates a zero length object
338 350
        if f is stdin or chunked is set then performs chunked transfer 
339 351
        """
340 352
        path = '/%s/%s' % (container, object)
341
        if not chunked and f != stdin:
353
        for k,v in meta.items():
354
            headers['X_OBJECT_META_%s' %k.strip().upper()] = v.strip()
355
        if not chunked:
356
            format = 'json' if use_hashes else 'text'
342 357
            data = f.read() if f else None
343
            return self.put(path, data, headers=headers)
358
            if data:
359
                if format == 'json':
360
                    data = eval(data)
361
                    data = json.dumps(data)
362
            return self.put(path, data, headers=headers, format=format)
344 363
        else:
345 364
            return self._chunked_transfer(path, 'PUT', f, headers=headers,
346 365
                                   blocksize=1024)
347 366
    
348 367
    def update_object(self, container, object, f=stdin, chunked=False,
349
                      blocksize=1024, headers=None):
368
                      blocksize=1024, headers=None, offset=None, **meta):
350 369
        path = '/%s/%s' % (container, object)
370
        for k,v in meta.items():
371
            headers['X_OBJECT_META_%s' %k.strip().upper()] = v.strip()
372
        if offset:
373
            headers['Content-Range'] = 'bytes %s-/*' % offset
374
        else:
375
            headers['Content-Range'] = 'bytes */*'
376
        
351 377
        if not chunked and f != stdin:
352 378
            data = f.read() if f else None
353 379
            self.post(path, data, headers=headers)

Also available in: Unified diff