Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / storage / __init__.py @ aa9c7402

History | View | Annotate | Download (10.6 kB)

1 3e6f33ca Stavros Sachtouris
#a Copyright 2011 GRNET S.A. All rights reserved.
2 3e6f33ca Stavros Sachtouris
#
3 3e6f33ca Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 3e6f33ca Stavros Sachtouris
# without modification, are permitted provided that the following
5 3e6f33ca Stavros Sachtouris
# conditions are met:
6 3e6f33ca Stavros Sachtouris
#
7 3e6f33ca Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 3e6f33ca Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 3e6f33ca Stavros Sachtouris
#      disclaimer.
10 3e6f33ca Stavros Sachtouris
#
11 3e6f33ca Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 3e6f33ca Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 3e6f33ca Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 3e6f33ca Stavros Sachtouris
#      provided with the distribution.
15 3e6f33ca Stavros Sachtouris
#
16 3e6f33ca Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 3e6f33ca Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 3e6f33ca Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 3e6f33ca Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 3e6f33ca Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 3e6f33ca Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 3e6f33ca Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 3e6f33ca Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 3e6f33ca Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 3e6f33ca Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 3e6f33ca Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 3e6f33ca Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 3e6f33ca Stavros Sachtouris
#
29 3e6f33ca Stavros Sachtouris
# The views and conclusions contained in the software and
30 3e6f33ca Stavros Sachtouris
# documentation are those of the authors and should not be
31 3e6f33ca Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 3e6f33ca Stavros Sachtouris
# or implied, of GRNET S.A.
33 3e6f33ca Stavros Sachtouris
34 3e6f33ca Stavros Sachtouris
from kamaki.clients import Client, ClientError
35 3e6f33ca Stavros Sachtouris
from kamaki.clients.utils import filter_in, filter_out, path4url
36 3e6f33ca Stavros Sachtouris
37 3e6f33ca Stavros Sachtouris
38 3e6f33ca Stavros Sachtouris
class StorageClient(Client):
39 3e6f33ca Stavros Sachtouris
    """OpenStack Object Storage API 1.0 client"""
40 3e6f33ca Stavros Sachtouris
41 3e6f33ca Stavros Sachtouris
    def __init__(self, base_url, token, account=None, container=None):
42 3e6f33ca Stavros Sachtouris
        super(StorageClient, self).__init__(base_url, token)
43 3e6f33ca Stavros Sachtouris
        self.account = account
44 3e6f33ca Stavros Sachtouris
        self.container = container
45 3e6f33ca Stavros Sachtouris
46 3e6f33ca Stavros Sachtouris
    def _assert_account(self):
47 3e6f33ca Stavros Sachtouris
        if not self.account:
48 3e6f33ca Stavros Sachtouris
            raise ClientError("No account provided")
49 3e6f33ca Stavros Sachtouris
50 3e6f33ca Stavros Sachtouris
    def _assert_container(self):
51 3e6f33ca Stavros Sachtouris
        self._assert_account()
52 3e6f33ca Stavros Sachtouris
        if not self.container:
53 3e6f33ca Stavros Sachtouris
            raise ClientError("No container provided")
54 3e6f33ca Stavros Sachtouris
55 3e6f33ca Stavros Sachtouris
    def get_account_info(self):
56 3e6f33ca Stavros Sachtouris
        """
57 3e6f33ca Stavros Sachtouris
        :returns: (dict)
58 3e6f33ca Stavros Sachtouris
        """
59 3e6f33ca Stavros Sachtouris
        self._assert_account()
60 3e6f33ca Stavros Sachtouris
        path = path4url(self.account)
61 3e6f33ca Stavros Sachtouris
        r = self.head(path, success=(204, 401))
62 3e6f33ca Stavros Sachtouris
        if r.status_code == 401:
63 3e6f33ca Stavros Sachtouris
            raise ClientError("No authorization", status=401)
64 3e6f33ca Stavros Sachtouris
        reply = r.headers
65 3e6f33ca Stavros Sachtouris
        return reply
66 3e6f33ca Stavros Sachtouris
67 3e6f33ca Stavros Sachtouris
    def replace_account_meta(self, metapairs):
68 3e6f33ca Stavros Sachtouris
        """
69 3e6f33ca Stavros Sachtouris
        :param metapais: (dict) key:val metadata pairs
70 3e6f33ca Stavros Sachtouris
        """
71 3e6f33ca Stavros Sachtouris
        self._assert_account()
72 3e6f33ca Stavros Sachtouris
        path = path4url(self.account)
73 3e6f33ca Stavros Sachtouris
        for key, val in metapairs.items():
74 3e6f33ca Stavros Sachtouris
            self.set_header('X-Account-Meta-' + key, val)
75 3e6f33ca Stavros Sachtouris
        r = self.post(path, success=202)
76 3e6f33ca Stavros Sachtouris
        r.release()
77 3e6f33ca Stavros Sachtouris
78 3e6f33ca Stavros Sachtouris
    def del_account_meta(self, metakey):
79 3e6f33ca Stavros Sachtouris
        """
80 3e6f33ca Stavros Sachtouris
        :param metakey: (str) metadatum key
81 3e6f33ca Stavros Sachtouris
        """
82 3e6f33ca Stavros Sachtouris
        headers = self.get_account_info()
83 3e6f33ca Stavros Sachtouris
        self.headers = filter_out(
84 3e6f33ca Stavros Sachtouris
            headers,
85 3e6f33ca Stavros Sachtouris
            'X-Account-Meta-' + metakey,
86 3e6f33ca Stavros Sachtouris
            exactMatch=True)
87 3e6f33ca Stavros Sachtouris
        if len(self.headers) == len(headers):
88 3e6f33ca Stavros Sachtouris
            raise ClientError('X-Account-Meta-%s not found' % metakey, 404)
89 3e6f33ca Stavros Sachtouris
        path = path4url(self.account)
90 3e6f33ca Stavros Sachtouris
        r = self.post(path, success=202)
91 3e6f33ca Stavros Sachtouris
        r.release()
92 3e6f33ca Stavros Sachtouris
93 3e6f33ca Stavros Sachtouris
    def create_container(self, container):
94 3e6f33ca Stavros Sachtouris
        """
95 3e6f33ca Stavros Sachtouris
        :param container: (str)
96 3e6f33ca Stavros Sachtouris

97 3e6f33ca Stavros Sachtouris
        :raises ClientError: 202 Container already exists
98 3e6f33ca Stavros Sachtouris
        """
99 3e6f33ca Stavros Sachtouris
        self._assert_account()
100 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, container)
101 3e6f33ca Stavros Sachtouris
        r = self.put(path, success=(201, 202))
102 3e6f33ca Stavros Sachtouris
        r.release()
103 3e6f33ca Stavros Sachtouris
        if r.status_code == 202:
104 3e6f33ca Stavros Sachtouris
            raise ClientError("Container already exists", r.status_code)
105 3e6f33ca Stavros Sachtouris
106 3e6f33ca Stavros Sachtouris
    def get_container_info(self, container):
107 3e6f33ca Stavros Sachtouris
        """
108 3e6f33ca Stavros Sachtouris
        :param container: (str)
109 3e6f33ca Stavros Sachtouris

110 3e6f33ca Stavros Sachtouris
        :returns: (dict)
111 3e6f33ca Stavros Sachtouris

112 3e6f33ca Stavros Sachtouris
        :raises ClientError: 404 Container does not exist
113 3e6f33ca Stavros Sachtouris
        """
114 3e6f33ca Stavros Sachtouris
        self._assert_account()
115 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, container)
116 3e6f33ca Stavros Sachtouris
        r = self.head(path, success=(204, 404))
117 3e6f33ca Stavros Sachtouris
        if r.status_code == 404:
118 3e6f33ca Stavros Sachtouris
            raise ClientError("Container does not exist", r.status_code)
119 3e6f33ca Stavros Sachtouris
        reply = r.headers
120 3e6f33ca Stavros Sachtouris
        return reply
121 3e6f33ca Stavros Sachtouris
122 3e6f33ca Stavros Sachtouris
    def delete_container(self, container):
123 3e6f33ca Stavros Sachtouris
        """
124 3e6f33ca Stavros Sachtouris
        :param container: (str)
125 3e6f33ca Stavros Sachtouris

126 3e6f33ca Stavros Sachtouris
        :raises ClientError: 404 Container does not exist
127 3e6f33ca Stavros Sachtouris
        :raises ClientError: 409 Container not empty
128 3e6f33ca Stavros Sachtouris
        """
129 3e6f33ca Stavros Sachtouris
        self._assert_account()
130 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, container)
131 3e6f33ca Stavros Sachtouris
        r = self.delete(path, success=(204, 404, 409))
132 3e6f33ca Stavros Sachtouris
        if r.status_code == 404:
133 3e6f33ca Stavros Sachtouris
            raise ClientError("Container does not exist", r.status_code)
134 3e6f33ca Stavros Sachtouris
        elif r.status_code == 409:
135 3e6f33ca Stavros Sachtouris
            raise ClientError("Container is not empty", r.status_code)
136 3e6f33ca Stavros Sachtouris
137 3e6f33ca Stavros Sachtouris
    def list_containers(self):
138 3e6f33ca Stavros Sachtouris
        """
139 3e6f33ca Stavros Sachtouris
        :returns: (dict)
140 3e6f33ca Stavros Sachtouris
        """
141 3e6f33ca Stavros Sachtouris
        self._assert_account()
142 3e6f33ca Stavros Sachtouris
        self.set_param('format', 'json')
143 3e6f33ca Stavros Sachtouris
        path = path4url(self.account)
144 3e6f33ca Stavros Sachtouris
        r = self.get(path, success=(200, 204))
145 3e6f33ca Stavros Sachtouris
        reply = r.json
146 3e6f33ca Stavros Sachtouris
        return reply
147 3e6f33ca Stavros Sachtouris
148 3e6f33ca Stavros Sachtouris
    def upload_object(self, obj, f, size=None):
149 3e6f33ca Stavros Sachtouris
        """ A simple (naive) implementation.
150 3e6f33ca Stavros Sachtouris

151 3e6f33ca Stavros Sachtouris
        :param obj: (str)
152 3e6f33ca Stavros Sachtouris

153 3e6f33ca Stavros Sachtouris
        :param f: an open for reading file descriptor
154 3e6f33ca Stavros Sachtouris

155 3e6f33ca Stavros Sachtouris
        :param size: (int) number of bytes to upload
156 3e6f33ca Stavros Sachtouris
        """
157 3e6f33ca Stavros Sachtouris
        self._assert_container()
158 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, self.container, obj)
159 c2bf1c19 Stavros Sachtouris
        data = f.read(size) if size else f.read()
160 3e6f33ca Stavros Sachtouris
        r = self.put(path, data=data, success=201)
161 3e6f33ca Stavros Sachtouris
        r.release()
162 3e6f33ca Stavros Sachtouris
163 3e6f33ca Stavros Sachtouris
    def create_object(
164 3e6f33ca Stavros Sachtouris
            self, obj,
165 3e6f33ca Stavros Sachtouris
            content_type='application/octet-stream', content_length=0):
166 3e6f33ca Stavros Sachtouris
        """
167 3e6f33ca Stavros Sachtouris
        :param obj: (str) directory-object name
168 3e6f33ca Stavros Sachtouris
        :param content_type: (str) explicitly set content_type
169 3e6f33ca Stavros Sachtouris
        :param content_length: (int) explicitly set content length
170 3e6f33ca Stavros Sachtouris
        """
171 3e6f33ca Stavros Sachtouris
        self._assert_container()
172 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, self.container, obj)
173 3e6f33ca Stavros Sachtouris
        self.set_header('Content-Type', content_type)
174 3e6f33ca Stavros Sachtouris
        self.set_header('Content-length', str(content_length))
175 3e6f33ca Stavros Sachtouris
        r = self.put(path, success=201)
176 3e6f33ca Stavros Sachtouris
        r.release()
177 3e6f33ca Stavros Sachtouris
178 3e6f33ca Stavros Sachtouris
    def create_directory(self, obj):
179 3e6f33ca Stavros Sachtouris
        """
180 3e6f33ca Stavros Sachtouris
        :param obj: (str) directory-object name
181 3e6f33ca Stavros Sachtouris
        """
182 3e6f33ca Stavros Sachtouris
        self._assert_container()
183 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, self.container, obj)
184 3e6f33ca Stavros Sachtouris
        self.set_header('Content-Type', 'application/directory')
185 3e6f33ca Stavros Sachtouris
        self.set_header('Content-length', '0')
186 3e6f33ca Stavros Sachtouris
        r = self.put(path, success=201)
187 3e6f33ca Stavros Sachtouris
        r.release()
188 3e6f33ca Stavros Sachtouris
189 3e6f33ca Stavros Sachtouris
    def get_object_info(self, obj):
190 3e6f33ca Stavros Sachtouris
        """
191 3e6f33ca Stavros Sachtouris
        :param obj: (str)
192 3e6f33ca Stavros Sachtouris

193 3e6f33ca Stavros Sachtouris
        :returns: (dict)
194 3e6f33ca Stavros Sachtouris
        """
195 3e6f33ca Stavros Sachtouris
        self._assert_container()
196 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, self.container, obj)
197 3e6f33ca Stavros Sachtouris
        r = self.head(path, success=200)
198 3e6f33ca Stavros Sachtouris
        reply = r.headers
199 3e6f33ca Stavros Sachtouris
        return reply
200 3e6f33ca Stavros Sachtouris
201 3e6f33ca Stavros Sachtouris
    def get_object_meta(self, obj):
202 3e6f33ca Stavros Sachtouris
        """
203 3e6f33ca Stavros Sachtouris
        :param obj: (str)
204 3e6f33ca Stavros Sachtouris

205 3e6f33ca Stavros Sachtouris
        :returns: (dict)
206 3e6f33ca Stavros Sachtouris
        """
207 3e6f33ca Stavros Sachtouris
        r = filter_in(self.get_object_info(obj), 'X-Object-Meta-')
208 3e6f33ca Stavros Sachtouris
        reply = {}
209 3e6f33ca Stavros Sachtouris
        for (key, val) in r.items():
210 3e6f33ca Stavros Sachtouris
            metakey = key.split('-')[-1]
211 3e6f33ca Stavros Sachtouris
            reply[metakey] = val
212 3e6f33ca Stavros Sachtouris
        return reply
213 3e6f33ca Stavros Sachtouris
214 3e6f33ca Stavros Sachtouris
    def del_object_meta(self, obj, metakey):
215 3e6f33ca Stavros Sachtouris
        """
216 3e6f33ca Stavros Sachtouris
        :param obj: (str)
217 3e6f33ca Stavros Sachtouris

218 3e6f33ca Stavros Sachtouris
        :param metakey: (str) the metadatum key
219 3e6f33ca Stavros Sachtouris
        """
220 3e6f33ca Stavros Sachtouris
        self._assert_container()
221 3e6f33ca Stavros Sachtouris
        self.set_header('X-Object-Meta-' + metakey, '')
222 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, self.container, obj)
223 3e6f33ca Stavros Sachtouris
        r = self.post(path, success=202)
224 3e6f33ca Stavros Sachtouris
        r.release()
225 3e6f33ca Stavros Sachtouris
226 3e6f33ca Stavros Sachtouris
    def replace_object_meta(self, metapairs):
227 3e6f33ca Stavros Sachtouris
        """
228 3e6f33ca Stavros Sachtouris
        :param metapairs: (dict) key:val metadata
229 3e6f33ca Stavros Sachtouris
        """
230 3e6f33ca Stavros Sachtouris
        self._assert_container()
231 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, self.container)
232 3e6f33ca Stavros Sachtouris
        for key, val in metapairs.items():
233 3e6f33ca Stavros Sachtouris
            self.set_header('X-Object-Meta-' + key, val)
234 3e6f33ca Stavros Sachtouris
        r = self.post(path, success=202)
235 3e6f33ca Stavros Sachtouris
        r.release()
236 3e6f33ca Stavros Sachtouris
237 3e6f33ca Stavros Sachtouris
    def copy_object(
238 3e6f33ca Stavros Sachtouris
            self, src_container, src_object, dst_container,
239 3e6f33ca Stavros Sachtouris
            dst_object=False):
240 3e6f33ca Stavros Sachtouris
        """Copy an objects from src_contaier:src_object to
241 3e6f33ca Stavros Sachtouris
            dst_container[:dst_object]
242 3e6f33ca Stavros Sachtouris

243 3e6f33ca Stavros Sachtouris
        :param src_container: (str)
244 3e6f33ca Stavros Sachtouris

245 3e6f33ca Stavros Sachtouris
        :param src_object: (str)
246 3e6f33ca Stavros Sachtouris

247 3e6f33ca Stavros Sachtouris
        :param dst_container: (str)
248 3e6f33ca Stavros Sachtouris

249 3e6f33ca Stavros Sachtouris
        :param dst_object: (str)
250 3e6f33ca Stavros Sachtouris
        """
251 3e6f33ca Stavros Sachtouris
        self._assert_account()
252 3e6f33ca Stavros Sachtouris
        dst_object = dst_object or src_object
253 3e6f33ca Stavros Sachtouris
        dst_path = path4url(self.account, dst_container, dst_object)
254 3e6f33ca Stavros Sachtouris
        self.set_header('X-Copy-From', path4url(src_container, src_object))
255 3e6f33ca Stavros Sachtouris
        self.set_header('Content-Length', 0)
256 3e6f33ca Stavros Sachtouris
        r = self.put(dst_path, success=201)
257 3e6f33ca Stavros Sachtouris
        r.release()
258 3e6f33ca Stavros Sachtouris
259 3e6f33ca Stavros Sachtouris
    def move_object(
260 3e6f33ca Stavros Sachtouris
            self, src_container, src_object, dst_container,
261 3e6f33ca Stavros Sachtouris
            dst_object=False):
262 3e6f33ca Stavros Sachtouris
        """Move an objects from src_contaier:src_object to
263 3e6f33ca Stavros Sachtouris
            dst_container[:dst_object]
264 3e6f33ca Stavros Sachtouris

265 3e6f33ca Stavros Sachtouris
        :param src_container: (str)
266 3e6f33ca Stavros Sachtouris

267 3e6f33ca Stavros Sachtouris
        :param src_object: (str)
268 3e6f33ca Stavros Sachtouris

269 3e6f33ca Stavros Sachtouris
        :param dst_container: (str)
270 3e6f33ca Stavros Sachtouris

271 3e6f33ca Stavros Sachtouris
        :param dst_object: (str)
272 3e6f33ca Stavros Sachtouris
        """
273 3e6f33ca Stavros Sachtouris
        self._assert_account()
274 3e6f33ca Stavros Sachtouris
        dst_object = dst_object or src_object
275 3e6f33ca Stavros Sachtouris
        dst_path = path4url(self.account, dst_container, dst_object)
276 3e6f33ca Stavros Sachtouris
        self.set_header('X-Move-From', path4url(src_container, src_object))
277 3e6f33ca Stavros Sachtouris
        self.set_header('Content-Length', 0)
278 3e6f33ca Stavros Sachtouris
        r = self.put(dst_path, success=201)
279 3e6f33ca Stavros Sachtouris
        r.release()
280 3e6f33ca Stavros Sachtouris
281 3e6f33ca Stavros Sachtouris
    def delete_object(self, obj):
282 3e6f33ca Stavros Sachtouris
        """
283 3e6f33ca Stavros Sachtouris
        :param obj: (str)
284 3e6f33ca Stavros Sachtouris

285 3e6f33ca Stavros Sachtouris
        :raises ClientError: 404 Object not found
286 3e6f33ca Stavros Sachtouris
        """
287 3e6f33ca Stavros Sachtouris
        self._assert_container()
288 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, self.container, obj)
289 3e6f33ca Stavros Sachtouris
        r = self.delete(path, success=(204, 404))
290 3e6f33ca Stavros Sachtouris
        if r.status_code == 404:
291 3e6f33ca Stavros Sachtouris
            raise ClientError("Object %s not found" % obj, r.status_code)
292 3e6f33ca Stavros Sachtouris
293 3e6f33ca Stavros Sachtouris
    def list_objects(self):
294 3e6f33ca Stavros Sachtouris
        """
295 3e6f33ca Stavros Sachtouris
        :returns: (dict)
296 3e6f33ca Stavros Sachtouris

297 3e6f33ca Stavros Sachtouris
        :raises ClientError: 404 Invalid account
298 3e6f33ca Stavros Sachtouris
        """
299 3e6f33ca Stavros Sachtouris
        self._assert_container()
300 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, self.container)
301 3e6f33ca Stavros Sachtouris
        self.set_param('format', 'json')
302 3e6f33ca Stavros Sachtouris
        r = self.get(path, success=(200, 204, 304, 404), )
303 3e6f33ca Stavros Sachtouris
        if r.status_code == 404:
304 3e6f33ca Stavros Sachtouris
            raise ClientError(
305 3e6f33ca Stavros Sachtouris
                "Invalid account (%s) for that container" % self.account,
306 3e6f33ca Stavros Sachtouris
                r.status_code)
307 3e6f33ca Stavros Sachtouris
        elif r.status_code == 304:
308 3e6f33ca Stavros Sachtouris
            return []
309 3e6f33ca Stavros Sachtouris
        return r.json
310 3e6f33ca Stavros Sachtouris
311 3e6f33ca Stavros Sachtouris
    def list_objects_in_path(self, path_prefix):
312 3e6f33ca Stavros Sachtouris
        """
313 3e6f33ca Stavros Sachtouris
        :param path_prefix: (str)
314 3e6f33ca Stavros Sachtouris

315 3e6f33ca Stavros Sachtouris
        :raises ClientError: 404 Invalid account
316 3e6f33ca Stavros Sachtouris

317 3e6f33ca Stavros Sachtouris
        :returns: (dict)
318 3e6f33ca Stavros Sachtouris
        """
319 3e6f33ca Stavros Sachtouris
        self._assert_container()
320 3e6f33ca Stavros Sachtouris
        path = path4url(self.account, self.container)
321 3e6f33ca Stavros Sachtouris
        self.set_param('format', 'json')
322 3e6f33ca Stavros Sachtouris
        self.set_param('path', path_prefix)
323 3e6f33ca Stavros Sachtouris
        r = self.get(path, success=(200, 204, 404))
324 3e6f33ca Stavros Sachtouris
        if r.status_code == 404:
325 3e6f33ca Stavros Sachtouris
            raise ClientError(
326 3e6f33ca Stavros Sachtouris
                "Invalid account (%s) for that container" % self.account,
327 3e6f33ca Stavros Sachtouris
                r.status_code)
328 3e6f33ca Stavros Sachtouris
        reply = r.json
329 3e6f33ca Stavros Sachtouris
        return reply