Revision 78348987 contrib/snf-pithos-tools/pithos/tools/lib/client.py

b/contrib/snf-pithos-tools/pithos/tools/lib/client.py
78 78
        self.debug = debug
79 79
        self.token = token
80 80

  
81
    def _req(self, method, path, body=None, headers={}, format='text', params={}):
81
    def _req(self, method, path, body=None, headers=None, format='text',
82
             params=None):
83
        headers = headers or {}
84
        params = params or {}
85

  
82 86
        p = urlparse(self.url)
83 87
        if p.scheme == 'http':
84 88
            conn = HTTPConnection(p.netloc)
......
109 113
        return _handle_response(resp, self.verbose, self.debug)
110 114

  
111 115
    def _chunked_transfer(self, path, method='PUT', f=stdin, headers=None,
112
                          blocksize=1024, params={}):
116
                          blocksize=1024, params=None):
113 117
        """perfomrs a chunked request"""
118
        params = params or {}
114 119
        p = urlparse(self.url)
115 120
        if p.scheme == 'http':
116 121
            conn = HTTPConnection(p.netloc)
......
154 159
        resp = conn.getresponse()
155 160
        return _handle_response(resp, self.verbose, self.debug)
156 161

  
157
    def delete(self, path, format='text', params={}):
162
    def delete(self, path, format='text', params=None):
163
        params = params or {}
158 164
        return self._req('DELETE', path, format=format, params=params)
159 165

  
160
    def get(self, path, format='text', headers={}, params={}):
166
    def get(self, path, format='text', headers=None, params=None):
167
        headers = headers or {}
168
        params = params or {}
161 169
        return self._req('GET', path, headers=headers, format=format,
162 170
                         params=params)
163 171

  
164
    def head(self, path, format='text', params={}):
172
    def head(self, path, format='text', params=None):
173
        params = params or {}
165 174
        return self._req('HEAD', path, format=format, params=params)
166 175

  
167
    def post(self, path, body=None, format='text', headers=None, params={}):
176
    def post(self, path, body=None, format='text', headers=None, params=None):
177
        params = params or {}
168 178
        return self._req('POST', path, body, headers=headers, format=format,
169 179
                         params=params)
170 180

  
171
    def put(self, path, body=None, format='text', headers=None, params={}):
181
    def put(self, path, body=None, format='text', headers=None, params=None):
182
        params = params or {}
172 183
        return self._req('PUT', path, body, headers=headers, format=format,
173 184
                         params=params)
174 185

  
175
    def _list(self, path, format='text', params={}, **headers):
186
    def _list(self, path, format='text', params=None, **headers):
187
        params = params or {}
176 188
        status, headers, data = self.get(path, format=format, headers=headers,
177 189
                                         params=params)
178 190
        if format == 'json':
......
183 195
            data = data.split('\n')[:-1] if data else ''
184 196
        return data
185 197

  
186
    def _get_metadata(self, path, prefix=None, params={}):
198
    def _get_metadata(self, path, prefix=None, params=None):
199
        params = params or {}
187 200
        status, headers, data = self.head(path, params=params)
188 201
        prefixlen = len(prefix) if prefix else 0
189 202
        meta = {}
......
235 248
            headers[k] = v
236 249
        return self.post(path, headers=headers)
237 250

  
238
    def _delete_metadata(self, path, entity, meta=[]):
251
    def _delete_metadata(self, path, entity, meta=None):
239 252
        """delete previously set metadata"""
253
        meta = meta or []
240 254
        ex_meta = self.retrieve_account_metadata(restricted=True)
241 255
        headers = {}
242 256
        prefix = 'x-%s-meta-' % entity
......
248 262
    # Storage Account Services
249 263

  
250 264
    def list_containers(self, format='text', limit=None,
251
                        marker=None, params={}, account=None, **headers):
265
                        marker=None, params=None, account=None, **headers):
252 266
        """lists containers"""
267
        params = params or {}
253 268
        account = account or self.account
254 269
        path = '/%s' % account
255 270
        params.update({'limit': limit, 'marker': marker})
......
268 283
        path = '/%s' % account
269 284
        return self._update_metadata(path, 'account', **meta)
270 285

  
271
    def delete_account_metadata(self, meta=[], account=None):
286
    def delete_account_metadata(self, meta=None, account=None):
272 287
        """deletes the account metadata"""
288
        meta = meta or []
273 289
        account = account or self.account
274 290
        path = '/%s' % account
275 291
        return self._delete_metadata(path, 'account', meta)
......
287 303

  
288 304
    def list_objects(self, container, format='text',
289 305
                     limit=None, marker=None, prefix=None, delimiter=None,
290
                     path=None, include_trashed=False, params={}, account=None,
306
                     path=None, include_trashed=False, params=None, account=None,
291 307
                     **headers):
292 308
        """returns a list with the container objects"""
309
        params = params or {}
293 310
        account = account or self.account
294 311
        params.update({'limit': limit, 'marker': marker, 'prefix': prefix,
295 312
                       'delimiter': delimiter, 'path': path})
......
300 317
            l = self._filter_trashed(l)
301 318
        return l
302 319

  
303
    def create_container(self, container, account=None, meta={}, **headers):
320
    def create_container(self, container, account=None, meta=None, **headers):
304 321
        """creates a container"""
322
        meta = meta or {}
305 323
        account = account or self.account
306 324
        if not headers:
307 325
            headers = {}
......
315 333
            raise Fault(data, int(status))
316 334
        return True
317 335

  
318
    def delete_container(self, container, params={}, account=None):
336
    def delete_container(self, container, params=None, account=None):
319 337
        """deletes a container"""
338
        params = params or {}
320 339
        account = account or self.account
321 340
        return self.delete('/%s/%s' % (account, container), params=params)
322 341

  
......
334 353
        return self._update_metadata('/%s/%s' % (account, container),
335 354
                                     'container', **meta)
336 355

  
337
    def delete_container_metadata(self, container, meta=[], account=None):
356
    def delete_container_metadata(self, container, meta=None, account=None):
338 357
        """deletes the container metadata"""
358
        meta = meta or []
339 359
        account = account or self.account
340 360
        path = '/%s/%s' % (account, container)
341 361
        return self._delete_metadata(path, 'container', meta)
342 362

  
343 363
    # Storage Object Services
344 364

  
345
    def request_object(self, container, object, format='text', params={},
365
    def request_object(self, container, object, format='text', params=None,
346 366
                       account=None, **headers):
347 367
        """returns tuple containing the status, headers and data response for an object request"""
368
        params = params or {}
348 369
        account = account or self.account
349 370
        path = '/%s/%s/%s' % (account, container, object)
350 371
        status, headers, data = self.get(path, format, headers, params)
351 372
        return status, headers, data
352 373

  
353
    def retrieve_object(self, container, object, format='text', params={},
374
    def retrieve_object(self, container, object, format='text', params=None,
354 375
                        account=None, **headers):
355 376
        """returns an object's data"""
377
        params = params or {}
356 378
        account = account or self.account
357 379
        t = self.request_object(container, object, format, params, account,
358 380
                                **headers)
......
364 386
        return data
365 387

  
366 388
    def retrieve_object_hashmap(
367
        self, container, object, format='json', params={},
389
        self, container, object, format='json', params=None,
368 390
            account=None, **headers):
369 391
        """returns the hashmap representing object's data"""
392
        params = params or {}
370 393
        if not params:
371 394
            params = {}
372 395
        params.update({'hashmap': None})
......
382 405
            container, object, account=account,
383 406
            **h)
384 407

  
385
    def create_object(self, container, object, f=stdin, format='text', meta={},
386
                      params={}, etag=None, content_type=None, content_encoding=None,
408
    def create_object(self, container, object, f=stdin, format='text', meta=None,
409
                      params=None, etag=None, content_type=None, content_encoding=None,
387 410
                      content_disposition=None, account=None, **headers):
388 411
        """creates a zero-length object"""
412
        meta = meta or {}
413
        params = params or {}
389 414
        account = account or self.account
390 415
        path = '/%s/%s/%s' % (account, container, object)
391 416
        for k, v in headers.items():
......
403 428
        data = f.read() if f else None
404 429
        return self.put(path, data, format, headers=headers, params=params)
405 430

  
406
    def create_zero_length_object(self, container, object, meta={}, etag=None,
431
    def create_zero_length_object(self, container, object, meta=None, etag=None,
407 432
                                  content_type=None, content_encoding=None,
408 433
                                  content_disposition=None, account=None,
409 434
                                  **headers):
435
        meta = meta or {}
410 436
        account = account or self.account
411 437
        args = locals().copy()
412 438
        for elem in ['self', 'container', 'headers', 'account']:
......
415 441
        return self.create_object(container, account=account, f=None, **args)
416 442

  
417 443
    def update_object(self, container, object, f=stdin,
418
                      offset=None, meta={}, params={}, content_length=None,
444
                      offset=None, meta=None, params=None, content_length=None,
419 445
                      content_type=None, content_encoding=None,
420 446
                      content_disposition=None, account=None, **headers):
447
        meta = meta or {}
448
        params = params or {}
421 449
        account = account or self.account
422 450
        path = '/%s/%s/%s' % (account, container, object)
423 451
        for k, v in headers.items():
......
442 470
        return self.post(path, data, headers=headers, params=params)
443 471

  
444 472
    def update_object_using_chunks(self, container, object, f=stdin,
445
                                   blocksize=1024, offset=None, meta={},
446
                                   params={}, content_type=None, content_encoding=None,
473
                                   blocksize=1024, offset=None, meta=None,
474
                                   params=None, content_type=None, content_encoding=None,
447 475
                                   content_disposition=None, account=None, **headers):
448 476
        """updates an object (incremental upload)"""
477
        params = params or {}
478
        meta = meta or {}
449 479
        account = account or self.account
450 480
        path = '/%s/%s/%s' % (account, container, object)
451 481
        headers = headers if not headers else {}
......
466 496
                                      blocksize=blocksize, params=params)
467 497

  
468 498
    def _change_obj_location(self, src_container, src_object, dst_container,
469
                             dst_object, remove=False, meta={}, account=None,
499
                             dst_object, remove=False, meta=None, account=None,
470 500
                             content_type=None, delimiter=None, **headers):
501
        meta = meta or {}
471 502
        account = account or self.account
472 503
        path = '/%s/%s/%s' % (account, dst_container, dst_object)
473 504
        headers = {} if not headers else headers
......
488 519
        return self.put(path, headers=headers, params=params)
489 520

  
490 521
    def copy_object(self, src_container, src_object, dst_container, dst_object,
491
                    meta={}, account=None, content_type=None, delimiter=None, **headers):
522
                    meta=None, account=None, content_type=None, delimiter=None, **headers):
492 523
        """copies an object"""
524
        meta = meta or {}
493 525
        account = account or self.account
494 526
        return self._change_obj_location(src_container, src_object,
495 527
                                         dst_container, dst_object, account=account,
......
497 529
                                         content_type=content_type, delimiter=delimiter, **headers)
498 530

  
499 531
    def move_object(self, src_container, src_object, dst_container,
500
                    dst_object, meta={}, account=None,
532
                    dst_object, meta=None, account=None,
501 533
                    content_type=None, **headers):
502 534
        """moves an object"""
535
        meta = meta or {}
503 536
        account = account or self.account
504 537
        return self._change_obj_location(src_container, src_object,
505 538
                                         dst_container, dst_object,
......
507 540
                                         meta=meta, content_type=content_type,
508 541
                                         **headers)
509 542

  
510
    def delete_object(self, container, object, params={}, account=None):
543
    def delete_object(self, container, object, params=None, account=None):
511 544
        """deletes an object"""
545
        params = params or {}
512 546
        account = account or self.account
513 547
        return self.delete('/%s/%s/%s' % (account, container, object),
514 548
                           params=params)
......
533 567
        path = '/%s/%s/%s' % (account, container, object)
534 568
        return self._update_metadata(path, 'object', **meta)
535 569

  
536
    def delete_object_metadata(self, container, object, meta=[], account=None):
570
    def delete_object_metadata(self, container, object, meta=None, account=None):
537 571
        """
538 572
        deletes object's metadata
539 573
        """
574
        meta = meta or []
540 575
        account = account or self.account
541 576
        path = '/%s/%s' % (account, container, object)
542 577
        return self._delete_metadata(path, 'object', meta)
......
557 592
            headers[k] = v
558 593
        return self.post(path, headers=headers, params=params)
559 594

  
560
    def _delete_metadata(self, path, entity, meta=[]):
595
    def _delete_metadata(self, path, entity, meta=None):
561 596
        """
562 597
        delete previously set metadata
563 598
        """
599
        meta = meta or []
564 600
        params = {'update': None}
565 601
        headers = {}
566 602
        prefix = 'x-%s-meta-' % entity
......
620 656
            groups[key] = val
621 657
        return groups
622 658

  
623
    def unset_account_groups(self, groups=[], account=None):
659
    def unset_account_groups(self, groups=None, account=None):
624 660
        """delete account groups"""
661
        groups = groups or []
625 662
        account = account or self.account
626 663
        path = '/%s' % account
627 664
        headers = {}
......
646 683
        return self.post(path, headers=headers)
647 684

  
648 685
    # Storage Container Services
649
    def create_container(self, container, account=None, meta={}, policies={}):
686
    def create_container(self, container, account=None, meta=None, policies=None):
650 687
        """creates a container"""
688
        meta = meta or {}
689
        policies = policies or {}
651 690
        args = {}
652 691
        for k, v in policies.items():
653 692
            args['X-Container-Policy-%s' % k.capitalize()] = v
......
655 694

  
656 695
    def list_objects(self, container, format='text',
657 696
                     limit=None, marker=None, prefix=None, delimiter=None,
658
                     path=None, shared=False, include_trashed=False, params={},
697
                     path=None, shared=False, include_trashed=False, params=None,
659 698
                     if_modified_since=None, if_unmodified_since=None, meta='',
660 699
                     until=None, account=None, public=False):
661 700
        """returns a list with the container objects"""
701
        params = params or {}
662 702
        account = account or self.account
663 703
        params = {'until': until, 'meta': meta}
664 704
        if shared:
......
711 751

  
712 752
    # Storage Object Services
713 753

  
714
    def retrieve_object(self, container, object, params={}, format='text',
754
    def retrieve_object(self, container, object, params=None, format='text',
715 755
                        range=None, if_range=None,
716 756
                        if_match=None, if_none_match=None,
717 757
                        if_modified_since=None, if_unmodified_since=None,
718 758
                        account=None, **headers):
719 759
        """returns an object"""
760
        params = params or {}
720 761
        account = account or self.account
721 762
        headers = {}
722 763
        l = ['range', 'if_range', 'if_match', 'if_none_match',
......
759 800
                                            format='json', **args)
760 801

  
761 802
    def create_zero_length_object(self, container, object,
762
                                  meta={}, etag=None, content_type=None,
803
                                  meta=None, etag=None, content_type=None,
763 804
                                  content_encoding=None,
764 805
                                  content_disposition=None,
765 806
                                  x_object_manifest=None, x_object_sharing=None,
766 807
                                  x_object_public=None, account=None):
767 808
        """createas a zero length object"""
809
        meta = meta or {}
768 810
        account = account or self.account
769 811
        args = locals().copy()
770 812
        for elem in ['self', 'container', 'object']:
......
773 815
                                                    **args)
774 816

  
775 817
    def create_folder(self, container, name,
776
                      meta={}, etag=None,
818
                      meta=None, etag=None,
777 819
                      content_encoding=None,
778 820
                      content_disposition=None,
779 821
                      x_object_manifest=None, x_object_sharing=None,
780 822
                      x_object_public=None, account=None):
823
        meta = meta or {}
781 824
        args = locals().copy()
782 825
        for elem in ['self', 'container', 'name']:
783 826
            args.pop(elem)
......
785 828
        return self.create_zero_length_object(container, name, **args)
786 829

  
787 830
    def create_object(self, container, object, f=stdin, format='text',
788
                      meta={}, params={}, etag=None, content_type=None,
831
                      meta=None, params=None, etag=None, content_type=None,
789 832
                      content_encoding=None, content_disposition=None,
790 833
                      x_object_manifest=None, x_object_sharing=None,
791 834
                      x_object_public=None, account=None):
792 835
        """creates an object"""
836
        meta = meta or {}
837
        params = params or {}
793 838
        account = account or self.account
794 839
        args = locals().copy()
795 840
        for elem in ['self', 'container', 'object']:
......
799 844
        return OOS_Client.create_object(self, container, object, **args)
800 845

  
801 846
    def create_object_using_chunks(self, container, object,
802
                                   f=stdin, blocksize=1024, meta={}, etag=None,
847
                                   f=stdin, blocksize=1024, meta=None, etag=None,
803 848
                                   content_type=None, content_encoding=None,
804 849
                                   content_disposition=None,
805 850
                                   x_object_sharing=None, x_object_manifest=None,
806 851
                                   x_object_public=None, account=None):
807 852
        """creates an object (incremental upload)"""
853
        meta = meta or {}
808 854
        account = account or self.account
809 855
        path = '/%s/%s/%s' % (account, container, object)
810 856
        headers = {}
......
822 868
        return self._chunked_transfer(path, 'PUT', f, headers=headers,
823 869
                                      blocksize=blocksize)
824 870

  
825
    def create_object_by_hashmap(self, container, object, hashmap={},
826
                                 meta={}, etag=None, content_encoding=None,
871
    def create_object_by_hashmap(self, container, object, hashmap=None,
872
                                 meta=None, etag=None, content_encoding=None,
827 873
                                 content_disposition=None, content_type=None,
828 874
                                 x_object_sharing=None, x_object_manifest=None,
829 875
                                 x_object_public=None, account=None):
830 876
        """creates an object by uploading hashes representing data instead of data"""
877
        meta = meta or {}
878
        hashmap = hashmap or {}
831 879
        account = account or self.account
832 880
        args = locals().copy()
833 881
        for elem in ['self', 'container', 'object', 'hashmap']:
......
850 898
                                  **headers)
851 899

  
852 900
    def update_object(self, container, object, f=stdin,
853
                      offset=None, meta={}, replace=False, content_length=None,
901
                      offset=None, meta=None, replace=False, content_length=None,
854 902
                      content_type=None, content_range=None,
855 903
                      content_encoding=None, content_disposition=None,
856 904
                      x_object_bytes=None, x_object_manifest=None,
857 905
                      x_object_sharing=None, x_object_public=None,
858 906
                      x_source_object=None, account=None):
859 907
        """updates an object"""
908
        meta = meta or {}
860 909
        account = account or self.account
861 910
        args = locals().copy()
862 911
        for elem in ['self', 'container', 'object', 'replace']:
......
866 915
        return OOS_Client.update_object(self, container, object, **args)
867 916

  
868 917
    def update_object_using_chunks(self, container, object, f=stdin,
869
                                   blocksize=1024, offset=None, meta={},
918
                                   blocksize=1024, offset=None, meta=None,
870 919
                                   replace=False, content_type=None, content_encoding=None,
871 920
                                   content_disposition=None, x_object_bytes=None,
872 921
                                   x_object_manifest=None, x_object_sharing=None,
873 922
                                   x_object_public=None, account=None):
874 923
        """updates an object (incremental upload)"""
924
        meta = meta or {}
875 925
        account = account or self.account
876 926
        args = locals().copy()
877 927
        for elem in ['self', 'container', 'object', 'replace']:
......
881 931
        return OOS_Client.update_object_using_chunks(self, container, object, **args)
882 932

  
883 933
    def update_from_other_source(self, container, object, source,
884
                                 offset=None, meta={}, content_range=None,
934
                                 offset=None, meta=None, content_range=None,
885 935
                                 content_encoding=None, content_disposition=None,
886 936
                                 x_object_bytes=None, x_object_manifest=None,
887 937
                                 x_object_sharing=None, x_object_public=None, account=None):
888 938
        """updates an object"""
939
        meta = meta or {}
889 940
        account = account or self.account
890 941
        args = locals().copy()
891 942
        for elem in ['self', 'container', 'object', 'source']:
......
933 984
        return self.post(path, headers=headers, params=params)
934 985

  
935 986
    def copy_object(self, src_container, src_object, dst_container, dst_object,
936
                    meta={}, public=False, version=None, account=None,
987
                    meta=None, public=False, version=None, account=None,
937 988
                    content_type=None, delimiter=None):
938 989
        """copies an object"""
990
        meta = meta or {}
939 991
        account = account or self.account
940 992
        headers = {}
941 993
        headers['x_object_public'] = public
......
948 1000
                                      **headers)
949 1001

  
950 1002
    def move_object(self, src_container, src_object, dst_container,
951
                    dst_object, meta={}, public=False,
1003
                    dst_object, meta=None, public=False,
952 1004
                    account=None, content_type=None, delimiter=None):
953 1005
        """moves an object"""
1006
        meta = meta or {}
954 1007
        headers = {}
955 1008
        headers['x_object_public'] = public
956 1009
        return OOS_Client.move_object(self, src_container, src_object,
......
977 1030
        self.update_object(container, object, f=None, x_object_sharing=sharing)
978 1031

  
979 1032

  
980
def _prepare_path(path, format='text', params={}):
1033
def _prepare_path(path, format='text', params=None):
1034
    params = params or {}
981 1035
    full_path = '%s?format=%s' % (quote(path), format)
982 1036

  
983 1037
    for k, v in params.items():

Also available in: Unified diff