Skip to content
Browse files

Misc Additions

* Adds StorageObject.update(headers) to POST arbitrary headers to
a StorageObject.
* Adds optional additional headers to StorageObject.create() call
* Makes query parameter optional for search
  • Loading branch information...
1 parent cfa09f5 commit 2d0cc803b709c77056f6a4ba05e2de13fb61d1e5 @sudorandom sudorandom committed
Showing with 37 additions and 15 deletions.
  1. +6 −5 object_storage/client.py
  2. +2 −2 object_storage/container.py
  3. +14 −4 object_storage/storage_object.py
  4. +15 −4 tests/test_storage_object.py
View
11 object_storage/client.py
@@ -131,7 +131,7 @@ def is_dir(self):
""" Returns whether or not this is a directory. Always True. """
return True
- def search(self, q, options=None, **kwargs):
+ def search(self, q=None, options=None, **kwargs):
""" Access the search interface.
@param q: the search query. This can be None.
@param options: options for the search API. Valid options:
@@ -148,8 +148,9 @@ def search(self, q, options=None, **kwargs):
"""
default_params = {
'format': 'json',
- 'q': q
}
+ if q:
+ default_params['q'] = q
params = {}
options = options or {}
options.update(kwargs)
@@ -169,8 +170,7 @@ def search(self, q, options=None, **kwargs):
def _formatter(response):
""" Formats search results. """
headers = response.headers
- content = response.content
- items = json.loads(content)
+ items = json.loads(response.content)
objs = []
for item in items:
if 'type' not in item or item['type'] == 'container':
@@ -182,7 +182,8 @@ def _formatter(response):
objs.append(obj)
count = int(headers.get('x-search-items-count', 0))
total = int(headers.get('x-search-items-total', 0))
- return {'count': count, 'total': total, 'results': objs}
+ offset = int(headers.get('x-search-items-offset', 0))
+ return {'count': count, 'total': total, 'offset': offset, 'results': objs}
return self.make_request('GET', _path, headers=headers,
params=params,
formatter=_formatter)
View
4 object_storage/container.py
@@ -282,11 +282,11 @@ def make_private(self):
return self.make_request('POST', headers=headers)
disable_cdn = make_private
- def search(self, q, options=None, **kwargs):
+ def search(self, q=None, options=None, **kwargs):
""" Search within container. """
options = options or {}
options.update({'path': self.name})
- return self.client.search(q, options=options, **kwargs)
+ return self.client.search(q=q, options=options, **kwargs)
def get_object(self, name):
""" Calls get_object() on the client. """
View
18 object_storage/storage_object.py
@@ -191,6 +191,14 @@ def is_dir(self):
""" returns True if content_type is 'text/directory' or 'application/directory' """
return self.model.content_type in ['text/directory', 'application/directory']
+ def update(self, headers):
+ """ POSTs to the object to update metadata and other attributes
+
+ @param headers: dict of headers to POST to the object
+ @raises ResponseError
+ """
+ return self.make_request('POST', headers=headers)
+
def set_metadata(self, meta):
""" Sets metadata for the object
@@ -202,16 +210,18 @@ def set_metadata(self, meta):
meta_headers["X-Object-Meta-%s" % (k, )] = v
return self.make_request('POST', headers=meta_headers)
- def create(self):
+ def create(self, headers=None):
""" Create object
+ @param headers: dict of headers to add to the create object request
@raises ResponseError
@return: StorageObject - self
"""
content_type = self.content_type or mimetypes.guess_type(self.name)[0]
if not content_type:
content_type = 'application/octet-stream'
- headers = {'content-type': content_type, 'Content-Length': '0'}
+ h = {'content-type': content_type, 'Content-Length': '0'}
+ headers.update(h)
def _formatter(res):
return self
@@ -419,11 +429,11 @@ def _copy_to(res):
return new_obj.copy_from(self, *args, **kwargs)
return new_obj.make_request('PUT', headers={'Content-Length': '0'}, formatter=_copy_to)
- def search(self, q, options=None, **kwargs):
+ def search(self, q=None, options=None, **kwargs):
""" Search within path """
options = options or {}
options.update({'path': "%s/%s" % (self.container, self.name)})
- return self.client.search(q, options=options, **kwargs)
+ return self.client.search(q=q, options=options, **kwargs)
def prime_cdn(self, *args, **kwargs):
""" Prime the object for CDN usage """
View
19 tests/test_storage_object.py
@@ -14,12 +14,23 @@ def test_instance_setup(self):
def test_create(self):
# no content_type and no ext
- _headers = Mock()
_make_request = Mock()
- self.obj._headers = _headers
self.obj.make_request = _make_request
- result = self.obj.create()
- self.obj.make_request.called_once_with('PUT', headers=_headers)
+ self.obj.create(headers={'test1': 'test1value'})
+ self.assertEqual(self.obj.make_request.call_args[0][0], 'PUT')
+ self.assertEqual(self.obj.make_request.call_args[1]['headers'], {
+ 'test1': 'test1value',
+ 'Content-Length': '0',
+ 'content-type': 'application/octet-stream'})
+
+ def test_update(self):
+ # no content_type and no ext
+ _make_request = Mock()
+ self.obj.make_request = _make_request
+ self.obj.update({'test1': 'test1value'})
+ self.assertEqual(self.obj.make_request.call_args[0][0], 'POST')
+ self.assertEqual(self.obj.make_request.call_args[1]['headers'],
+ {'test1': 'test1value'})
def test_delete(self):
result = self.client.delete()

0 comments on commit 2d0cc80

Please sign in to comment.
Something went wrong with that request. Please try again.