Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / storage.py @ 80f0d425

History | View | Annotate | Download (10.9 kB)

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

96 d88ba587 Stavros Sachtouris
        :raises ClientError: 202 Container already exists
97 d88ba587 Stavros Sachtouris
        """
98 d88ba587 Stavros Sachtouris
        self._assert_account()
99 af3b2b36 Stavros Sachtouris
        path = path4url(self.account, container)
100 6a0b1658 Giorgos Verigakis
        r = self.put(path, success=(201, 202))
101 d88ba587 Stavros Sachtouris
        r.release()
102 6a0b1658 Giorgos Verigakis
        if r.status_code == 202:
103 16d445fe Giorgos Verigakis
            raise ClientError("Container already exists", r.status_code)
104 44b8928d Giorgos Verigakis
105 6c4778ae Stavros Sachtouris
    def get_container_info(self, container):
106 d88ba587 Stavros Sachtouris
        """
107 d88ba587 Stavros Sachtouris
        :param container: (str)
108 d88ba587 Stavros Sachtouris

109 d88ba587 Stavros Sachtouris
        :returns: (dict)
110 d88ba587 Stavros Sachtouris

111 d88ba587 Stavros Sachtouris
        :raises ClientError: 404 Container does not exist
112 d88ba587 Stavros Sachtouris
        """
113 d88ba587 Stavros Sachtouris
        self._assert_account()
114 af3b2b36 Stavros Sachtouris
        path = path4url(self.account, container)
115 6a0b1658 Giorgos Verigakis
        r = self.head(path, success=(204, 404))
116 6a0b1658 Giorgos Verigakis
        if r.status_code == 404:
117 6a0b1658 Giorgos Verigakis
            raise ClientError("Container does not exist", r.status_code)
118 5b263ba2 Stavros Sachtouris
        reply = r.headers
119 5b263ba2 Stavros Sachtouris
        return reply
120 44b8928d Giorgos Verigakis
121 b66dfee7 Stavros Sachtouris
    def delete_container(self, container):
122 d88ba587 Stavros Sachtouris
        """
123 d88ba587 Stavros Sachtouris
        :param container: (str)
124 d88ba587 Stavros Sachtouris

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

150 d88ba587 Stavros Sachtouris
        :param obj: (str)
151 d88ba587 Stavros Sachtouris

152 d88ba587 Stavros Sachtouris
        :param f: an open for reading file descriptor
153 d88ba587 Stavros Sachtouris

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

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

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

218 d88ba587 Stavros Sachtouris
        :param metakey: (str) the metadatum key
219 d88ba587 Stavros Sachtouris
        """
220 d88ba587 Stavros Sachtouris
        self._assert_container()
221 3dabe5d2 Stavros Sachtouris
        self.set_header('X-Object-Meta-' + metakey, '')
222 4375e020 Stavros Sachtouris
        path = path4url(self.account, self.container, obj)
223 3dabe5d2 Stavros Sachtouris
        r = self.post(path, success=202)
224 3dabe5d2 Stavros Sachtouris
        r.release()
225 d0b42fb4 Stavros Sachtouris
226 e742badc Stavros Sachtouris
    def replace_object_meta(self, metapairs):
227 d88ba587 Stavros Sachtouris
        """
228 d88ba587 Stavros Sachtouris
        :param metapairs: (dict) key:val metadata
229 d88ba587 Stavros Sachtouris
        """
230 d88ba587 Stavros Sachtouris
        self._assert_container()
231 3dabe5d2 Stavros Sachtouris
        path = path4url(self.account, self.container)
232 e742badc Stavros Sachtouris
        for key, val in metapairs:
233 3dabe5d2 Stavros Sachtouris
            self.set_header('X-Object-Meta-' + key, val)
234 5b263ba2 Stavros Sachtouris
        r = self.post(path, success=202)
235 3dabe5d2 Stavros Sachtouris
        r.release()
236 0e4bec91 Stavros Sachtouris
237 d88ba587 Stavros Sachtouris
    def get_object(self, obj):
238 d88ba587 Stavros Sachtouris
        """
239 d88ba587 Stavros Sachtouris
        :param obj: (str)
240 d88ba587 Stavros Sachtouris

241 d88ba587 Stavros Sachtouris
        :returns: (int, int) # of objects, size in bytes
242 d88ba587 Stavros Sachtouris
        """
243 d88ba587 Stavros Sachtouris
        self._assert_container()
244 d88ba587 Stavros Sachtouris
        path = path4url(self.account, self.container, obj)
245 2f749e6e Stavros Sachtouris
        r = self.get(path, success=200)
246 6a0b1658 Giorgos Verigakis
        size = int(r.headers['content-length'])
247 5b263ba2 Stavros Sachtouris
        cnt = r.content
248 5b263ba2 Stavros Sachtouris
        return cnt, size
249 44b8928d Giorgos Verigakis
250 3dabe5d2 Stavros Sachtouris
    def copy_object(self, src_container, src_object, dst_container,
251 3dabe5d2 Stavros Sachtouris
        dst_object=False):
252 d88ba587 Stavros Sachtouris
        """Copy an objects from src_contaier:src_object to
253 d88ba587 Stavros Sachtouris
            dst_container[:dst_object]
254 d88ba587 Stavros Sachtouris

255 d88ba587 Stavros Sachtouris
        :param src_container: (str)
256 d88ba587 Stavros Sachtouris

257 d88ba587 Stavros Sachtouris
        :param src_object: (str)
258 d88ba587 Stavros Sachtouris

259 d88ba587 Stavros Sachtouris
        :param dst_container: (str)
260 d88ba587 Stavros Sachtouris

261 d88ba587 Stavros Sachtouris
        :param dst_object: (str)
262 d88ba587 Stavros Sachtouris
        """
263 d88ba587 Stavros Sachtouris
        self._assert_account()
264 c2867610 Stavros Sachtouris
        dst_object = dst_object or src_object
265 c2867610 Stavros Sachtouris
        dst_path = path4url(self.account, dst_container, dst_object)
266 c2867610 Stavros Sachtouris
        self.set_header('X-Copy-From', path4url(src_container, src_object))
267 c2867610 Stavros Sachtouris
        self.set_header('Content-Length', 0)
268 5b263ba2 Stavros Sachtouris
        r = self.put(dst_path, success=201)
269 3dabe5d2 Stavros Sachtouris
        r.release()
270 c2867610 Stavros Sachtouris
271 3dabe5d2 Stavros Sachtouris
    def move_object(self, src_container, src_object, dst_container,
272 3dabe5d2 Stavros Sachtouris
        dst_object=False):
273 d88ba587 Stavros Sachtouris
        """Move an objects from src_contaier:src_object to
274 d88ba587 Stavros Sachtouris
            dst_container[:dst_object]
275 d88ba587 Stavros Sachtouris

276 d88ba587 Stavros Sachtouris
        :param src_container: (str)
277 d88ba587 Stavros Sachtouris

278 d88ba587 Stavros Sachtouris
        :param src_object: (str)
279 d88ba587 Stavros Sachtouris

280 d88ba587 Stavros Sachtouris
        :param dst_container: (str)
281 d88ba587 Stavros Sachtouris

282 d88ba587 Stavros Sachtouris
        :param dst_object: (str)
283 d88ba587 Stavros Sachtouris
        """
284 d88ba587 Stavros Sachtouris
        self._assert_account()
285 eed330ab Stavros Sachtouris
        dst_object = dst_object or src_object
286 eed330ab Stavros Sachtouris
        dst_path = path4url(self.account, dst_container, dst_object)
287 eed330ab Stavros Sachtouris
        self.set_header('X-Move-From', path4url(src_container, src_object))
288 eed330ab Stavros Sachtouris
        self.set_header('Content-Length', 0)
289 5b263ba2 Stavros Sachtouris
        r = self.put(dst_path, success=201)
290 3dabe5d2 Stavros Sachtouris
        r.release()
291 eed330ab Stavros Sachtouris
292 d88ba587 Stavros Sachtouris
    def delete_object(self, obj):
293 d88ba587 Stavros Sachtouris
        """
294 d88ba587 Stavros Sachtouris
        :param obj: (str)
295 d88ba587 Stavros Sachtouris

296 d88ba587 Stavros Sachtouris
        :raises ClientError: 404 Object not found
297 d88ba587 Stavros Sachtouris
        """
298 d88ba587 Stavros Sachtouris
        self._assert_container()
299 d88ba587 Stavros Sachtouris
        path = path4url(self.account, self.container, obj)
300 bebdd0d6 Stavros Sachtouris
        r = self.delete(path, success=(204, 404))
301 bebdd0d6 Stavros Sachtouris
        if r.status_code == 404:
302 d88ba587 Stavros Sachtouris
            raise ClientError("Object %s not found" % obj, r.status_code)
303 3dabe5d2 Stavros Sachtouris
304 e2bd16d5 Stavros Sachtouris
    def list_objects(self):
305 d88ba587 Stavros Sachtouris
        """
306 d88ba587 Stavros Sachtouris
        :returns: (dict)
307 d88ba587 Stavros Sachtouris

308 d88ba587 Stavros Sachtouris
        :raises ClientError: 404 Invalid account
309 d88ba587 Stavros Sachtouris
        """
310 d88ba587 Stavros Sachtouris
        self._assert_container()
311 af3b2b36 Stavros Sachtouris
        path = path4url(self.account, self.container)
312 2f749e6e Stavros Sachtouris
        self.set_param('format', 'json')
313 2f749e6e Stavros Sachtouris
        r = self.get(path, success=(200, 204, 304, 404), )
314 175f40ab Stavros Sachtouris
        if r.status_code == 404:
315 3dabe5d2 Stavros Sachtouris
            raise ClientError(\
316 d88ba587 Stavros Sachtouris
                "Invalid account (%s) for that container" % self.account,
317 3dabe5d2 Stavros Sachtouris
                r.status_code)
318 16ce7b91 Stavros Sachtouris
        elif r.status_code == 304:
319 16ce7b91 Stavros Sachtouris
            return []
320 5b263ba2 Stavros Sachtouris
        reply = r.json
321 5b263ba2 Stavros Sachtouris
        return reply
322 e2bd16d5 Stavros Sachtouris
323 e2bd16d5 Stavros Sachtouris
    def list_objects_in_path(self, path_prefix):
324 d88ba587 Stavros Sachtouris
        """
325 d88ba587 Stavros Sachtouris
        :param path_prefix: (str)
326 d88ba587 Stavros Sachtouris

327 d88ba587 Stavros Sachtouris
        :raises ClientError: 404 Invalid account
328 d88ba587 Stavros Sachtouris

329 d88ba587 Stavros Sachtouris
        :returns: (dict)
330 d88ba587 Stavros Sachtouris
        """
331 d88ba587 Stavros Sachtouris
        self._assert_container()
332 af3b2b36 Stavros Sachtouris
        path = path4url(self.account, self.container)
333 2f749e6e Stavros Sachtouris
        self.set_param('format', 'json')
334 2f749e6e Stavros Sachtouris
        self.set_param('path', 'path_prefix')
335 2f749e6e Stavros Sachtouris
        r = self.get(path, success=(200, 204, 404))
336 a79f6d30 Stavros Sachtouris
        if r.status_code == 404:
337 3dabe5d2 Stavros Sachtouris
            raise ClientError(\
338 d88ba587 Stavros Sachtouris
                "Invalid account (%s) for that container" % self.account,
339 3dabe5d2 Stavros Sachtouris
                r.status_code)
340 5b263ba2 Stavros Sachtouris
        reply = r.json
341 5b263ba2 Stavros Sachtouris
        return reply