Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / pithos_rest_api.py @ b335416e

History | View | Annotate | Download (30 kB)

1 afd9d603 Stavros Sachtouris
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 afd9d603 Stavros Sachtouris
#
3 afd9d603 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 afd9d603 Stavros Sachtouris
# without modification, are permitted provided that the following
5 afd9d603 Stavros Sachtouris
# conditions are met:
6 afd9d603 Stavros Sachtouris
#
7 afd9d603 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 afd9d603 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 afd9d603 Stavros Sachtouris
#      disclaimer.
10 afd9d603 Stavros Sachtouris
#
11 afd9d603 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 afd9d603 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 afd9d603 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 afd9d603 Stavros Sachtouris
#      provided with the distribution.
15 afd9d603 Stavros Sachtouris
#
16 afd9d603 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 afd9d603 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 afd9d603 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 afd9d603 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 afd9d603 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 afd9d603 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 afd9d603 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 afd9d603 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 afd9d603 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 afd9d603 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 afd9d603 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 afd9d603 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 afd9d603 Stavros Sachtouris
#
29 afd9d603 Stavros Sachtouris
# The views and conclusions contained in the software and
30 afd9d603 Stavros Sachtouris
# documentation are those of the authors and should not be
31 afd9d603 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 afd9d603 Stavros Sachtouris
# or implied, of GRNET S.A.
33 afd9d603 Stavros Sachtouris
34 436f2ce1 Stavros Sachtouris
from kamaki.clients.storage import StorageClient, ClientError
35 436f2ce1 Stavros Sachtouris
from kamaki.clients.utils import path4url, list2str
36 afd9d603 Stavros Sachtouris
37 afd9d603 Stavros Sachtouris
class PithosRestAPI(StorageClient):
38 afd9d603 Stavros Sachtouris
39 afd9d603 Stavros Sachtouris
    def account_head(self, until = None,
40 afd9d603 Stavros Sachtouris
        if_modified_since=None, if_unmodified_since=None, *args, **kwargs):
41 afd9d603 Stavros Sachtouris
        """ Full Pithos+ HEAD at account level
42 afd9d603 Stavros Sachtouris
        --- request parameters ---
43 afd9d603 Stavros Sachtouris
        @param until (string): optional timestamp
44 afd9d603 Stavros Sachtouris
        --- --- optional request headers ---
45 afd9d603 Stavros Sachtouris
        @param if_modified_since (string): Retrieve if account has changed since provided timestamp
46 afd9d603 Stavros Sachtouris
        @param if_unmodified_since (string): Retrieve if account has not changed since provided timestamp
47 afd9d603 Stavros Sachtouris
        """
48 afd9d603 Stavros Sachtouris
        self.assert_account()
49 afd9d603 Stavros Sachtouris
        path = path4url(self.account)
50 afd9d603 Stavros Sachtouris
51 afd9d603 Stavros Sachtouris
        self.set_param('until', until, iff = until is not None)
52 afd9d603 Stavros Sachtouris
        self.set_header('If-Modified-Since', if_modified_since)
53 afd9d603 Stavros Sachtouris
        self.set_header('If-Unmodified-Since', if_unmodified_since)
54 afd9d603 Stavros Sachtouris
55 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 204)
56 afd9d603 Stavros Sachtouris
        return self.head(path, *args, success=success, **kwargs)
57 afd9d603 Stavros Sachtouris
58 afd9d603 Stavros Sachtouris
    def account_get(self, limit=None, marker=None, format='json', show_only_shared=False, until=None,
59 afd9d603 Stavros Sachtouris
        if_modified_since=None, if_unmodified_since=None, *args, **kwargs):
60 afd9d603 Stavros Sachtouris
        """  Full Pithos+ GET at account level
61 afd9d603 Stavros Sachtouris
        --- request parameters ---
62 afd9d603 Stavros Sachtouris
        @param limit (integer): The amount of results requested (server will use default value if None)
63 afd9d603 Stavros Sachtouris
        @param marker (string): Return containers with name lexicographically after marker
64 afd9d603 Stavros Sachtouris
        @param format (string): reply format can be json or xml (default: json)
65 afd9d603 Stavros Sachtouris
        @param shared (bool): If true, only shared containers will be included in results
66 afd9d603 Stavros Sachtouris
        @param until (string): optional timestamp
67 afd9d603 Stavros Sachtouris
        --- --- optional request headers ---
68 afd9d603 Stavros Sachtouris
        @param if_modified_since (string): Retrieve if account has changed since provided timestamp
69 afd9d603 Stavros Sachtouris
        @param if_unmodified_since (string): Retrieve if account has not changed since provided timestamp
70 afd9d603 Stavros Sachtouris
        """
71 afd9d603 Stavros Sachtouris
        self.assert_account()
72 afd9d603 Stavros Sachtouris
73 afd9d603 Stavros Sachtouris
        self.set_param('format',format, iff = format is not None)
74 afd9d603 Stavros Sachtouris
        self.set_param('limit',limit, iff = limit is not None)
75 afd9d603 Stavros Sachtouris
        self.set_param('marker',marker, iff = marker is not None)
76 afd9d603 Stavros Sachtouris
        self.set_param('shared', iff = show_only_shared)
77 afd9d603 Stavros Sachtouris
        self.set_param('until',until, iff = until is not None)
78 afd9d603 Stavros Sachtouris
79 afd9d603 Stavros Sachtouris
        self.set_header('If-Modified-Since', if_modified_since)
80 afd9d603 Stavros Sachtouris
        self.set_header('If-Unmodified-Since', if_unmodified_since)
81 afd9d603 Stavros Sachtouris
82 afd9d603 Stavros Sachtouris
        path = path4url(self.account)
83 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', (200, 204))
84 afd9d603 Stavros Sachtouris
        return self.get(path, *args, success = success, **kwargs)
85 afd9d603 Stavros Sachtouris
86 afd9d603 Stavros Sachtouris
    def account_post(self, update=True,
87 afd9d603 Stavros Sachtouris
        groups={}, metadata=None, quota=None, versioning=None, *args, **kwargs):
88 afd9d603 Stavros Sachtouris
        """ Full Pithos+ POST at account level
89 afd9d603 Stavros Sachtouris
        --- request parameters ---
90 afd9d603 Stavros Sachtouris
        @param update (bool): if True, Do not replace metadata/groups
91 afd9d603 Stavros Sachtouris
        --- request headers ---
92 afd9d603 Stavros Sachtouris
        @groups (dict): Optional user defined groups in the form
93 afd9d603 Stavros Sachtouris
                    {   'group1':['user1', 'user2', ...], 
94 afd9d603 Stavros Sachtouris
                        'group2':['userA', 'userB', ...], ...
95 afd9d603 Stavros Sachtouris
                    }
96 afd9d603 Stavros Sachtouris
        @metadata (dict): Optional user defined metadata in the form
97 afd9d603 Stavros Sachtouris
                    {   'name1': 'value1',
98 afd9d603 Stavros Sachtouris
                        'name2': 'value2', ...
99 afd9d603 Stavros Sachtouris
                    }
100 afd9d603 Stavros Sachtouris
        @param quota(integer): If supported, sets the Account quota
101 afd9d603 Stavros Sachtouris
        @param versioning(string): If supported, sets the Account versioning
102 afd9d603 Stavros Sachtouris
                    to 'auto' or some other supported versioning string
103 afd9d603 Stavros Sachtouris
        """
104 afd9d603 Stavros Sachtouris
        self.assert_account()
105 afd9d603 Stavros Sachtouris
106 afd9d603 Stavros Sachtouris
        self.set_param('update', iff = update)
107 afd9d603 Stavros Sachtouris
108 afd9d603 Stavros Sachtouris
        for group, usernames in groups.items():
109 afd9d603 Stavros Sachtouris
            userstr = ''
110 afd9d603 Stavros Sachtouris
            dlm = ''
111 afd9d603 Stavros Sachtouris
            for user in usernames:
112 afd9d603 Stavros Sachtouris
                userstr = userstr + dlm + user
113 afd9d603 Stavros Sachtouris
                dlm = ','
114 afd9d603 Stavros Sachtouris
            self.set_header('X-Account-Group-'+group, userstr)
115 afd9d603 Stavros Sachtouris
        if metadata is not None:
116 afd9d603 Stavros Sachtouris
            for metaname, metaval in metadata.items():
117 afd9d603 Stavros Sachtouris
                self.set_header('X-Account-Meta-'+metaname, metaval)
118 afd9d603 Stavros Sachtouris
        self.set_header('X-Account-Policy-Quota', quota)
119 afd9d603 Stavros Sachtouris
        self.set_header('X-Account-Policy-Versioning', versioning)
120 afd9d603 Stavros Sachtouris
121 afd9d603 Stavros Sachtouris
        path = path4url(self.account)
122 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 202)
123 afd9d603 Stavros Sachtouris
        return self.post(path, *args, success=success, **kwargs)
124 afd9d603 Stavros Sachtouris
125 afd9d603 Stavros Sachtouris
    def container_head(self, until=None,
126 afd9d603 Stavros Sachtouris
        if_modified_since=None, if_unmodified_since=None, *args, **kwargs):
127 afd9d603 Stavros Sachtouris
        """ Full Pithos+ HEAD at container level
128 afd9d603 Stavros Sachtouris
        --- request params ---
129 afd9d603 Stavros Sachtouris
        @param until (string): optional timestamp
130 afd9d603 Stavros Sachtouris
        --- optional request headers --- 
131 afd9d603 Stavros Sachtouris
        @param if_modified_since (string): Retrieve if account has changed since provided timestamp
132 afd9d603 Stavros Sachtouris
        @param if_unmodified_since (string): Retrieve if account has not changed since provided timestamp
133 afd9d603 Stavros Sachtouris
        """
134 afd9d603 Stavros Sachtouris
        self.assert_container()
135 afd9d603 Stavros Sachtouris
136 afd9d603 Stavros Sachtouris
        self.set_param('until', until, iff=until is not None)
137 afd9d603 Stavros Sachtouris
138 afd9d603 Stavros Sachtouris
        self.set_header('If-Modified-Since', if_modified_since)
139 afd9d603 Stavros Sachtouris
        self.set_header('If-Unmodified-Since', if_unmodified_since)
140 afd9d603 Stavros Sachtouris
141 afd9d603 Stavros Sachtouris
        path = path4url(self.account, self.container)
142 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 204)
143 afd9d603 Stavros Sachtouris
        return self.head(path, *args, success=success, **kwargs)
144 afd9d603 Stavros Sachtouris
145 afd9d603 Stavros Sachtouris
    def container_get(self, limit = None, marker = None, prefix=None, delimiter=None, path = None,
146 afd9d603 Stavros Sachtouris
        format='json', meta=[], show_only_shared=False, until=None,
147 afd9d603 Stavros Sachtouris
        if_modified_since=None, if_unmodified_since=None, *args, **kwargs):
148 afd9d603 Stavros Sachtouris
        """ Full Pithos+ GET at container level
149 afd9d603 Stavros Sachtouris
        --- request parameters ---
150 afd9d603 Stavros Sachtouris
        @param limit (integer): The amount of results requested (server qill use default value if None)
151 afd9d603 Stavros Sachtouris
        @param marker (string): Return containers with name lexicographically after marker
152 afd9d603 Stavros Sachtouris
        @param prefix (string): Return objects starting with prefix
153 afd9d603 Stavros Sachtouris
        @param delimiter (string): Return objects up to the delimiter
154 afd9d603 Stavros Sachtouris
        @param path (string): assume prefix = path and delimiter = / (overwrites prefix
155 afd9d603 Stavros Sachtouris
        and delimiter)
156 afd9d603 Stavros Sachtouris
        @param format (string): reply format can be json or xml (default: json)
157 afd9d603 Stavros Sachtouris
        @param meta (list): Return objects that satisfy the key queries in the specified
158 afd9d603 Stavros Sachtouris
        comma separated list (use <key>, !<key> for existence queries, <key><op><value>
159 afd9d603 Stavros Sachtouris
        for value queries, where <op> can be one of =, !=, <=, >=, <, >)
160 afd9d603 Stavros Sachtouris
        @param shared (bool): If true, only shared containers will be included in results
161 afd9d603 Stavros Sachtouris
        @param until (string): optional timestamp
162 afd9d603 Stavros Sachtouris
        --- --- optional request headers ---
163 afd9d603 Stavros Sachtouris
        @param if_modified_since (string): Retrieve if account has changed since provided timestamp
164 afd9d603 Stavros Sachtouris
        @param if_unmodified_since (string): Retrieve if account has not changed since provided timestamp
165 afd9d603 Stavros Sachtouris
        """
166 afd9d603 Stavros Sachtouris
        self.assert_container()
167 afd9d603 Stavros Sachtouris
168 afd9d603 Stavros Sachtouris
        self.set_param('format', format, iff=format is not None)
169 afd9d603 Stavros Sachtouris
        self.set_param('limit', limit, iff=limit is not None)
170 afd9d603 Stavros Sachtouris
        self.set_param('marker', marker, iff=marker is not None)
171 afd9d603 Stavros Sachtouris
        if path is None:
172 afd9d603 Stavros Sachtouris
            self.set_param('prefix', prefix, iff=prefix is not None)
173 afd9d603 Stavros Sachtouris
            self.set_param('delimiter', delimiter, iff=delimiter is not None)
174 afd9d603 Stavros Sachtouris
        else:
175 afd9d603 Stavros Sachtouris
            self.set_param('path', path)
176 afd9d603 Stavros Sachtouris
        self.set_param('shared', iff=show_only_shared)
177 afd9d603 Stavros Sachtouris
        self.set_param('meta', list2str(meta), iff=meta is not None and len(meta) > 0)
178 afd9d603 Stavros Sachtouris
        self.set_param('until', until, iff=until is not None)
179 afd9d603 Stavros Sachtouris
180 afd9d603 Stavros Sachtouris
        self.set_header('If-Modified-Since', if_modified_since)
181 afd9d603 Stavros Sachtouris
        self.set_header('If-Unmodified-Since', if_unmodified_since)
182 afd9d603 Stavros Sachtouris
183 afd9d603 Stavros Sachtouris
        path = path4url(self.account, self.container)
184 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 200)
185 afd9d603 Stavros Sachtouris
        return self.get(path, *args, success=success, **kwargs)
186 afd9d603 Stavros Sachtouris
187 afd9d603 Stavros Sachtouris
    def container_put(self, quota=None, versioning=None, metadata=None, *args, **kwargs):
188 afd9d603 Stavros Sachtouris
        """ Full Pithos+ PUT at container level
189 afd9d603 Stavros Sachtouris
        --- request headers ---
190 afd9d603 Stavros Sachtouris
        @param quota (integer): Size limit in KB
191 afd9d603 Stavros Sachtouris
        @param versioning (string): 'auto' or other string supported by server
192 afd9d603 Stavros Sachtouris
        @metadata (dict): Optional user defined metadata in the form
193 afd9d603 Stavros Sachtouris
        {   'name1': 'value1',
194 afd9d603 Stavros Sachtouris
        'name2': 'value2', ...
195 afd9d603 Stavros Sachtouris
        }
196 afd9d603 Stavros Sachtouris
        """
197 afd9d603 Stavros Sachtouris
        self.assert_container()
198 afd9d603 Stavros Sachtouris
199 afd9d603 Stavros Sachtouris
        if metadata is not None:
200 afd9d603 Stavros Sachtouris
            for metaname, metaval in metadata.items():
201 afd9d603 Stavros Sachtouris
                self.set_header('X-Container-Meta-'+metaname, metaval)
202 afd9d603 Stavros Sachtouris
        self.set_header('X-Container-Policy-Quota', quota)
203 afd9d603 Stavros Sachtouris
        self.set_header('X-Container-Policy-Versioning', versioning)
204 afd9d603 Stavros Sachtouris
205 afd9d603 Stavros Sachtouris
        path = path4url(self.account, self.container)
206 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success',(201, 202))
207 afd9d603 Stavros Sachtouris
        return self.put(path, *args, success=success, **kwargs)
208 afd9d603 Stavros Sachtouris
209 afd9d603 Stavros Sachtouris
    def container_post(self, update=True, format='json',
210 afd9d603 Stavros Sachtouris
        quota=None, versioning=None, metadata=None, content_type=None, content_length=None,
211 afd9d603 Stavros Sachtouris
        transfer_encoding=None, *args, **kwargs):
212 afd9d603 Stavros Sachtouris
        """ Full Pithos+ POST at container level
213 afd9d603 Stavros Sachtouris
        --- request params ---
214 afd9d603 Stavros Sachtouris
        @param update (bool):  if True, Do not replace metadata/groups
215 afd9d603 Stavros Sachtouris
        @param format(string): json (default) or xml
216 afd9d603 Stavros Sachtouris
        --- request headers ---
217 afd9d603 Stavros Sachtouris
        @param quota (integer): Size limit in KB
218 afd9d603 Stavros Sachtouris
        @param versioning (string): 'auto' or other string supported by server
219 afd9d603 Stavros Sachtouris
        @metadata (dict): Optional user defined metadata in the form
220 afd9d603 Stavros Sachtouris
        {   'name1': 'value1',
221 afd9d603 Stavros Sachtouris
        'name2': 'value2', ...
222 afd9d603 Stavros Sachtouris
        }
223 afd9d603 Stavros Sachtouris
        @param content_type (string): set a custom content type
224 afd9d603 Stavros Sachtouris
        @param content_length (string): set a custrom content length
225 afd9d603 Stavros Sachtouris
        @param transfer_encoding (string): set a custrom transfer encoding
226 afd9d603 Stavros Sachtouris
        """
227 afd9d603 Stavros Sachtouris
        self.assert_container()
228 afd9d603 Stavros Sachtouris
229 afd9d603 Stavros Sachtouris
        self.set_param('format', format, iff=format is not None)
230 afd9d603 Stavros Sachtouris
        self.set_param('update', iff=update)
231 afd9d603 Stavros Sachtouris
232 afd9d603 Stavros Sachtouris
        if metadata is not None:
233 afd9d603 Stavros Sachtouris
            for metaname, metaval in metadata.items():
234 afd9d603 Stavros Sachtouris
                self.set_header('X-Container-Meta-'+metaname, metaval)
235 afd9d603 Stavros Sachtouris
        self.set_header('X-Container-Policy-Quota', quota)
236 afd9d603 Stavros Sachtouris
        self.set_header('X-Container-Policy-Versioning', versioning)
237 afd9d603 Stavros Sachtouris
        self.set_header('Content-Type', content_type)
238 afd9d603 Stavros Sachtouris
        self.set_header('Content-Length', content_length)
239 afd9d603 Stavros Sachtouris
        self.set_header('Transfer-Encoding', transfer_encoding)
240 afd9d603 Stavros Sachtouris
241 afd9d603 Stavros Sachtouris
        path = path4url(self.account, self.container)
242 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 202)
243 afd9d603 Stavros Sachtouris
        return self.post(path, *args, success=success, **kwargs)
244 afd9d603 Stavros Sachtouris
245 afd9d603 Stavros Sachtouris
    def container_delete(self, until=None, delimiter=None, *args, **kwargs):
246 afd9d603 Stavros Sachtouris
        """ Full Pithos+ DELETE at container level
247 afd9d603 Stavros Sachtouris
        --- request parameters ---
248 afd9d603 Stavros Sachtouris
        @param until (timestamp string): if defined, container is purged up to that time
249 afd9d603 Stavros Sachtouris
        """
250 afd9d603 Stavros Sachtouris
        self.assert_container()        
251 afd9d603 Stavros Sachtouris
252 afd9d603 Stavros Sachtouris
        self.set_param('until', until, iff=until is not None)
253 afd9d603 Stavros Sachtouris
        self.set_param('delimiter', delimiter, iff=delimiter is not None)
254 afd9d603 Stavros Sachtouris
255 afd9d603 Stavros Sachtouris
        path=path4url(self.account, self.container)
256 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 204)
257 afd9d603 Stavros Sachtouris
        return self.delete(path, success=success)
258 afd9d603 Stavros Sachtouris
259 afd9d603 Stavros Sachtouris
    def object_head(self, object, version=None, if_etag_match=None, if_etag_not_match = None,
260 afd9d603 Stavros Sachtouris
        if_modified_since = None, if_unmodified_since = None, *args, **kwargs):
261 afd9d603 Stavros Sachtouris
        """ Full Pithos+ HEAD at object level
262 afd9d603 Stavros Sachtouris
        --- request parameters ---
263 afd9d603 Stavros Sachtouris
        @param version (string): optional version identified
264 afd9d603 Stavros Sachtouris
        --- request headers ---
265 afd9d603 Stavros Sachtouris
        @param if_etag_match (string): if provided, return only results
266 afd9d603 Stavros Sachtouris
                with etag matching with this
267 afd9d603 Stavros Sachtouris
        @param if_etag_not_match (string): if provided, return only results
268 afd9d603 Stavros Sachtouris
                with etag not matching with this
269 afd9d603 Stavros Sachtouris
        @param if_modified_since (string): Retrieve if account has changed since provided timestamp
270 afd9d603 Stavros Sachtouris
        @param if_unmodified_since (string): Retrieve if account has not changed since provided timestamp
271 afd9d603 Stavros Sachtouris
        """
272 afd9d603 Stavros Sachtouris
        self.assert_container()
273 afd9d603 Stavros Sachtouris
274 afd9d603 Stavros Sachtouris
        self.set_param('version', version, iff=version is not None)
275 afd9d603 Stavros Sachtouris
276 afd9d603 Stavros Sachtouris
        self.set_header('If-Match', if_etag_match)
277 afd9d603 Stavros Sachtouris
        self.set_header('If-None-Match', if_etag_not_match)
278 afd9d603 Stavros Sachtouris
        self.set_header('If-Modified-Since', if_modified_since)
279 afd9d603 Stavros Sachtouris
        self.set_header('If-Unmodified-Since', if_unmodified_since)
280 afd9d603 Stavros Sachtouris
281 afd9d603 Stavros Sachtouris
        path=path4url(self.account, self.container, object)
282 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 200)
283 afd9d603 Stavros Sachtouris
        return self.head(path, *args, success=success, **kwargs)
284 afd9d603 Stavros Sachtouris
285 9a7efb0d Stavros Sachtouris
    def object_get(self, object, format='json', hashmap=False, version=None,
286 afd9d603 Stavros Sachtouris
        data_range=None, if_range=False, if_etag_match=None, if_etag_not_match = None,
287 afd9d603 Stavros Sachtouris
        if_modified_since = None, if_unmodified_since = None, *args, **kwargs):
288 afd9d603 Stavros Sachtouris
        """ Full Pithos+ GET at object level
289 afd9d603 Stavros Sachtouris
        --- request parameters ---
290 afd9d603 Stavros Sachtouris
        @param format (string): json (default) or xml
291 afd9d603 Stavros Sachtouris
        @param hashmap (bool): Optional request for hashmap
292 afd9d603 Stavros Sachtouris
        @param version (string): optional version identified
293 afd9d603 Stavros Sachtouris
        --- request headers ---
294 afd9d603 Stavros Sachtouris
        @param data_range (string): Optional range of data to retrieve
295 afd9d603 Stavros Sachtouris
        @param if_range (bool): 
296 afd9d603 Stavros Sachtouris
        @param if_etag_match (string): if provided, return only results
297 afd9d603 Stavros Sachtouris
                with etag matching with this
298 afd9d603 Stavros Sachtouris
        @param if_etag_not_match (string): if provided, return only results
299 afd9d603 Stavros Sachtouris
                with etag not matching with this
300 afd9d603 Stavros Sachtouris
        @param if_modified_since (string): Retrieve if account has changed since provided timestamp
301 afd9d603 Stavros Sachtouris
        @param if_unmodified_since (string): Retrieve if account has not changed since provided timestamp
302 afd9d603 Stavros Sachtouris
        """
303 afd9d603 Stavros Sachtouris
        self.assert_container()
304 afd9d603 Stavros Sachtouris
305 afd9d603 Stavros Sachtouris
        self.set_param('format', format, iff=format is not None)
306 afd9d603 Stavros Sachtouris
        self.set_param('version', version, iff=version is not None)
307 afd9d603 Stavros Sachtouris
        self.set_param('hashmap', hashmap, iff=hashmap)
308 afd9d603 Stavros Sachtouris
309 afd9d603 Stavros Sachtouris
        self.set_header('Range', data_range)
310 afd9d603 Stavros Sachtouris
        self.set_header('If-Range', '', if_range is True and data_range is not None)
311 afd9d603 Stavros Sachtouris
        self.set_header('If-Match', if_etag_match, )
312 afd9d603 Stavros Sachtouris
        self.set_header('If-None-Match', if_etag_not_match)
313 afd9d603 Stavros Sachtouris
        self.set_header('If-Modified-Since', if_modified_since)
314 afd9d603 Stavros Sachtouris
        self.set_header('If-Unmodified-Since', if_unmodified_since)
315 afd9d603 Stavros Sachtouris
316 afd9d603 Stavros Sachtouris
        path=path4url(self.account, self.container, object)
317 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 200)
318 afd9d603 Stavros Sachtouris
        return self.get(path, *args, success=success, **kwargs)
319 afd9d603 Stavros Sachtouris
320 afd9d603 Stavros Sachtouris
    def object_put(self, object, format='json', hashmap=False, delimiter = None, if_etag_match=None,
321 afd9d603 Stavros Sachtouris
        if_etag_not_match = None, etag=None, content_length = None, content_type=None,
322 afd9d603 Stavros Sachtouris
        transfer_encoding=None, copy_from=None, move_from=None, source_account=None,
323 afd9d603 Stavros Sachtouris
        source_version=None, content_encoding = None, content_disposition=None, manifest = None,
324 afd9d603 Stavros Sachtouris
        permitions =None, public = None, metadata=None, *args, **kwargs):
325 afd9d603 Stavros Sachtouris
        """ Full Pithos+ PUT at object level
326 afd9d603 Stavros Sachtouris
        --- request parameters ---
327 afd9d603 Stavros Sachtouris
        @param format (string): json (default) or xml
328 afd9d603 Stavros Sachtouris
        @param hashmap (bool): Optional hashmap provided instead of data
329 afd9d603 Stavros Sachtouris
        --- request headers ---
330 afd9d603 Stavros Sachtouris
        @param if_etag_match (string): if provided, return only results
331 afd9d603 Stavros Sachtouris
                with etag matching with this
332 afd9d603 Stavros Sachtouris
        @param if_etag_not_match (string): if provided, return only results
333 afd9d603 Stavros Sachtouris
                with etag not matching with this
334 afd9d603 Stavros Sachtouris
        @param etag (string): The MD5 hash of the object (optional to check written data)
335 afd9d603 Stavros Sachtouris
        @param content_length (integer): The size of the data written
336 afd9d603 Stavros Sachtouris
        @param content_type (string): The MIME content type of the object
337 afd9d603 Stavros Sachtouris
        @param transfer_encoding (string): Set to chunked to specify incremental uploading (if used, Content-Length is ignored)
338 afd9d603 Stavros Sachtouris
        @param copy_from (string): The source path in the form /<container>/<object>
339 afd9d603 Stavros Sachtouris
        @param move_from (string): The source path in the form /<container>/<object>
340 afd9d603 Stavros Sachtouris
        @param source_account (string): The source account to copy/move from
341 afd9d603 Stavros Sachtouris
        @param source_version (string): The source version to copy from
342 afd9d603 Stavros Sachtouris
        @param conent_encoding (string): The encoding of the object
343 afd9d603 Stavros Sachtouris
        @param content_disposition (string): The presentation style of the object
344 afd9d603 Stavros Sachtouris
        @param manifest (string): Object parts prefix in /<container>/<object> form
345 afd9d603 Stavros Sachtouris
        @param permitions (dict): Object permissions in the form (all fields are optional)
346 afd9d603 Stavros Sachtouris
                {'read':[user1, group1, user2, ...], 'write':['user3, group2, group3, ...]}
347 afd9d603 Stavros Sachtouris
        @param public (bool): If true, Object is publicly accessible, if false, not
348 afd9d603 Stavros Sachtouris
        @param metadata (dict): Optional user defined metadata in the form
349 afd9d603 Stavros Sachtouris
                {'meta-key-1':'meta-value-1', 'meta-key-2':'meta-value-2', ...}
350 afd9d603 Stavros Sachtouris
        """
351 afd9d603 Stavros Sachtouris
        self.assert_container()
352 afd9d603 Stavros Sachtouris
353 afd9d603 Stavros Sachtouris
        self.set_param('format', format, iff=format is not None)
354 afd9d603 Stavros Sachtouris
        self.set_param('hashmap', hashmap, iff=hashmap)
355 afd9d603 Stavros Sachtouris
        self.set_param('delimiter', delimiter, iff=delimiter is not None)
356 afd9d603 Stavros Sachtouris
357 afd9d603 Stavros Sachtouris
        self.set_header('If-Match', if_etag_match)
358 afd9d603 Stavros Sachtouris
        self.set_header('If-None-Match', if_etag_not_match)
359 afd9d603 Stavros Sachtouris
        self.set_header('ETag', etag)
360 afd9d603 Stavros Sachtouris
        self.set_header('Content-Length', content_length)
361 afd9d603 Stavros Sachtouris
        self.set_header('Content-Type', content_type)
362 afd9d603 Stavros Sachtouris
        self.set_header('Transfer-Encoding', transfer_encoding)
363 afd9d603 Stavros Sachtouris
        self.set_header('X-Copy-From', copy_from)
364 afd9d603 Stavros Sachtouris
        self.set_header('X-Move-From', move_from)
365 afd9d603 Stavros Sachtouris
        self.set_header('X-Source-Account', source_account)
366 afd9d603 Stavros Sachtouris
        self.set_header('X-Source-Version', source_version)
367 afd9d603 Stavros Sachtouris
        self.set_header('Content-Encoding', content_encoding)
368 afd9d603 Stavros Sachtouris
        self.set_header('Content-Disposition', content_disposition)
369 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Manifest', manifest)
370 afd9d603 Stavros Sachtouris
        perms = None
371 afd9d603 Stavros Sachtouris
        if permitions is not None:
372 afd9d603 Stavros Sachtouris
            for permition_type, permition_list in permitions.items():
373 afd9d603 Stavros Sachtouris
                if perms is None:
374 afd9d603 Stavros Sachtouris
                    perms = '' #Remove permitions
375 afd9d603 Stavros Sachtouris
                if len(permition_list) == 0:
376 afd9d603 Stavros Sachtouris
                    continue
377 afd9d603 Stavros Sachtouris
                perms += ';'+permition_type if len(perms) > 0 else permition_type
378 afd9d603 Stavros Sachtouris
                perms += '='+list2str(permition_list, seperator=',')
379 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Sharing', perms)
380 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Public', public)
381 afd9d603 Stavros Sachtouris
        if metadata is not None:
382 afd9d603 Stavros Sachtouris
            for key, val in metadata.items():
383 afd9d603 Stavros Sachtouris
                self.set_header('X-Object-Meta-'+key, val)
384 afd9d603 Stavros Sachtouris
385 afd9d603 Stavros Sachtouris
        path=path4url(self.account, self.container, object)
386 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 201)
387 afd9d603 Stavros Sachtouris
        return self.put(path, *args, success=success, **kwargs)
388 afd9d603 Stavros Sachtouris
389 afd9d603 Stavros Sachtouris
    def object_copy(self, object, destination, format='json', ignore_content_type=False,
390 afd9d603 Stavros Sachtouris
        if_etag_match=None, if_etag_not_match=None, destination_account=None,
391 afd9d603 Stavros Sachtouris
        content_type=None, content_encoding=None, content_disposition=None, source_version=None,
392 afd9d603 Stavros Sachtouris
        permitions=None, public=False, metadata=None, *args, **kwargs):
393 afd9d603 Stavros Sachtouris
        """ Full Pithos+ COPY at object level
394 afd9d603 Stavros Sachtouris
        --- request parameters ---
395 afd9d603 Stavros Sachtouris
        @param format (string): json (default) or xml
396 afd9d603 Stavros Sachtouris
        @param ignore_content_type (bool): Ignore the supplied Content-Type
397 afd9d603 Stavros Sachtouris
        --- request headers ---
398 afd9d603 Stavros Sachtouris
         @param if_etag_match (string): if provided, copy only results
399 afd9d603 Stavros Sachtouris
                with etag matching with this
400 afd9d603 Stavros Sachtouris
        @param if_etag_not_match (string): if provided, copy only results
401 afd9d603 Stavros Sachtouris
                with etag not matching with this
402 afd9d603 Stavros Sachtouris
        @param destination (string): The destination path in the form /<container>/<object>
403 afd9d603 Stavros Sachtouris
        @param destination_account (string): The destination account to copy to
404 afd9d603 Stavros Sachtouris
        @param content_type (string): The MIME content type of the object
405 afd9d603 Stavros Sachtouris
        @param content_encoding (string): The encoding of the object
406 afd9d603 Stavros Sachtouris
        @param content_disposition (string): The presentation style of the object
407 afd9d603 Stavros Sachtouris
        @param source_version (string): The source version to copy from
408 afd9d603 Stavros Sachtouris
        @param permitions (dict): Object permissions in the form (all fields are optional)
409 afd9d603 Stavros Sachtouris
                {'read':[user1, group1, user2, ...], 'write':['user3, group2, group3, ...]}
410 afd9d603 Stavros Sachtouris
                permitions override source permitions, removing any old permitions
411 afd9d603 Stavros Sachtouris
        @param public (bool): If true, Object is publicly accessible, if else, not
412 afd9d603 Stavros Sachtouris
        @param metadata (dict): Optional user defined metadata in the form
413 afd9d603 Stavros Sachtouris
                {'meta-key-1':'meta-value-1', 'meta-key-2':'meta-value-2', ...}
414 afd9d603 Stavros Sachtouris
                Metadata are appended to the source metadata. In case of same keys, they
415 afd9d603 Stavros Sachtouris
                replace the old metadata
416 afd9d603 Stavros Sachtouris
        """
417 afd9d603 Stavros Sachtouris
        self.assert_container()
418 afd9d603 Stavros Sachtouris
419 afd9d603 Stavros Sachtouris
        self.set_param('format', format, iff=format is not None)
420 afd9d603 Stavros Sachtouris
        self.set_param('ignore_content_type', iff=ignore_content_type)
421 afd9d603 Stavros Sachtouris
422 afd9d603 Stavros Sachtouris
        self.set_header('If-Match', if_etag_match)
423 afd9d603 Stavros Sachtouris
        self.set_header('If-None-Match', if_etag_not_match)
424 afd9d603 Stavros Sachtouris
        self.set_header('Destination', destination)
425 afd9d603 Stavros Sachtouris
        self.set_header('Destination-Account', destination_account)
426 afd9d603 Stavros Sachtouris
        self.set_header('Content-Type', content_type)
427 afd9d603 Stavros Sachtouris
        self.set_header('Content-Encoding', content_encoding)
428 afd9d603 Stavros Sachtouris
        self.set_header('Content-Disposition', content_disposition)
429 afd9d603 Stavros Sachtouris
        self.set_header('X-Source-Version', source_version)
430 afd9d603 Stavros Sachtouris
        perms = None
431 afd9d603 Stavros Sachtouris
        if permitions is not None:
432 afd9d603 Stavros Sachtouris
            for permition_type, permition_list in permitions.items():
433 afd9d603 Stavros Sachtouris
                if perms is None:
434 afd9d603 Stavros Sachtouris
                    perms = '' #Remove permitions
435 afd9d603 Stavros Sachtouris
                if len(permition_list) == 0:
436 afd9d603 Stavros Sachtouris
                    continue
437 afd9d603 Stavros Sachtouris
                perms += ';'+permition_type if len(perms) > 0 else permition_type
438 afd9d603 Stavros Sachtouris
                perms += '='+list2str(permition_list, seperator=',')
439 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Sharing', perms)
440 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Public', public)
441 afd9d603 Stavros Sachtouris
        if metadata is not None:
442 afd9d603 Stavros Sachtouris
            for key, val in metadata.items():
443 afd9d603 Stavros Sachtouris
                self.set_header('X-Object-Meta-'+key, val)
444 afd9d603 Stavros Sachtouris
445 afd9d603 Stavros Sachtouris
        path = path4url(self.account, self.container, object)
446 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 201)
447 afd9d603 Stavros Sachtouris
        return self.copy(path, *args, success=success, **kwargs)
448 afd9d603 Stavros Sachtouris
449 afd9d603 Stavros Sachtouris
    def object_move(self, object, format='json', ignore_content_type=False,
450 afd9d603 Stavros Sachtouris
        if_etag_match=None, if_etag_not_match=None, destination=None, destination_account=None,
451 afd9d603 Stavros Sachtouris
        content_type=None, content_encoding=None, content_disposition=None, permitions={},
452 afd9d603 Stavros Sachtouris
        public=False, metadata={}, *args, **kwargs):
453 afd9d603 Stavros Sachtouris
        """ Full Pithos+ COPY at object level
454 afd9d603 Stavros Sachtouris
        --- request parameters ---
455 afd9d603 Stavros Sachtouris
        @param format (string): json (default) or xml
456 afd9d603 Stavros Sachtouris
        @param ignore_content_type (bool): Ignore the supplied Content-Type
457 afd9d603 Stavros Sachtouris
        --- request headers ---
458 afd9d603 Stavros Sachtouris
         @param if_etag_match (string): if provided, return only results
459 afd9d603 Stavros Sachtouris
                with etag matching with this
460 afd9d603 Stavros Sachtouris
        @param if_etag_not_match (string): if provided, return only results
461 afd9d603 Stavros Sachtouris
                with etag not matching with this
462 afd9d603 Stavros Sachtouris
        @param destination (string): The destination path in the form /<container>/<object>
463 afd9d603 Stavros Sachtouris
        @param destination_account (string): The destination account to copy to
464 afd9d603 Stavros Sachtouris
        @param content_type (string): The MIME content type of the object
465 afd9d603 Stavros Sachtouris
        @param content_encoding (string): The encoding of the object
466 afd9d603 Stavros Sachtouris
        @param content_disposition (string): The presentation style of the object
467 afd9d603 Stavros Sachtouris
        @param source_version (string): The source version to copy from
468 afd9d603 Stavros Sachtouris
        @param permitions (dict): Object permissions in the form (all fields are optional)
469 afd9d603 Stavros Sachtouris
                {'read':[user1, group1, user2, ...], 'write':['user3, group2, group3, ...]}
470 afd9d603 Stavros Sachtouris
        @param public (bool): If true, Object is publicly accessible, if false, not
471 afd9d603 Stavros Sachtouris
        @param metadata (dict): Optional user defined metadata in the form
472 afd9d603 Stavros Sachtouris
                {'meta-key-1':'meta-value-1', 'meta-key-2':'meta-value-2', ...}
473 afd9d603 Stavros Sachtouris
        """
474 afd9d603 Stavros Sachtouris
        self.assert_container()
475 afd9d603 Stavros Sachtouris
476 afd9d603 Stavros Sachtouris
        self.set_param('format', format, iff=format is not None)
477 afd9d603 Stavros Sachtouris
        self.set_param('ignore_content_type', iff=ignore_content_type)
478 afd9d603 Stavros Sachtouris
479 afd9d603 Stavros Sachtouris
        self.set_header('If-Match', if_etag_match)
480 afd9d603 Stavros Sachtouris
        self.set_header('If-None-Match', if_etag_not_match)
481 afd9d603 Stavros Sachtouris
        self.set_header('Destination', destination)
482 afd9d603 Stavros Sachtouris
        self.set_header('Destination-Account', destination_account)
483 afd9d603 Stavros Sachtouris
        self.set_header('Content-Type', content_type)
484 afd9d603 Stavros Sachtouris
        self.set_header('Content-Encoding', content_encoding)
485 afd9d603 Stavros Sachtouris
        self.set_header('Content-Disposition', content_disposition)
486 afd9d603 Stavros Sachtouris
        perms = None
487 afd9d603 Stavros Sachtouris
        for permition_type, permition_list in permitions.items():
488 afd9d603 Stavros Sachtouris
            if perms is None:
489 afd9d603 Stavros Sachtouris
                perms = '' #Remove permitions
490 afd9d603 Stavros Sachtouris
            if len(permition_list) == 0:
491 afd9d603 Stavros Sachtouris
                continue
492 afd9d603 Stavros Sachtouris
            perms += ';'+permition_type if len(perms) > 0 else permition_type
493 afd9d603 Stavros Sachtouris
            perms += '='+list2str(permition_list, seperator=',')
494 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Sharing', perms)
495 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Public', public)
496 afd9d603 Stavros Sachtouris
        for key, val in metadata.items():
497 afd9d603 Stavros Sachtouris
            self.set_header('X-Object-Meta-'+key, val)
498 afd9d603 Stavros Sachtouris
499 afd9d603 Stavros Sachtouris
        path = path4url(self.account, self.container, object)
500 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 201)
501 afd9d603 Stavros Sachtouris
        return self.move(path, *args, success=success, **kwargs)
502 afd9d603 Stavros Sachtouris
503 afd9d603 Stavros Sachtouris
    def object_post(self, object, format='json', update=True,
504 afd9d603 Stavros Sachtouris
        if_etag_match=None, if_etag_not_match=None, content_length=None, content_type=None,
505 afd9d603 Stavros Sachtouris
        content_range=None, transfer_encoding=None, content_encoding=None, content_disposition=None,
506 afd9d603 Stavros Sachtouris
        source_object=None, source_account=None, source_version=None, object_bytes=None,
507 afd9d603 Stavros Sachtouris
        manifest=None, permitions={}, public=False, metadata={}, *args, **kwargs):
508 afd9d603 Stavros Sachtouris
        """ Full Pithos+ POST at object level
509 afd9d603 Stavros Sachtouris
        --- request parameters ---
510 afd9d603 Stavros Sachtouris
        @param format (string): json (default) or xml
511 afd9d603 Stavros Sachtouris
        @param update (bool): Do not replace metadata
512 afd9d603 Stavros Sachtouris
        --- request headers ---
513 afd9d603 Stavros Sachtouris
        @param if_etag_match (string): if provided, return only results
514 afd9d603 Stavros Sachtouris
                with etag matching with this
515 afd9d603 Stavros Sachtouris
        @param if_etag_not_match (string): if provided, return only results
516 afd9d603 Stavros Sachtouris
                with etag not matching with this
517 afd9d603 Stavros Sachtouris
        @param content_length (string): The size of the data written
518 afd9d603 Stavros Sachtouris
        @param content_type (string): The MIME content type of the object
519 afd9d603 Stavros Sachtouris
        @param content_range (string): The range of data supplied
520 afd9d603 Stavros Sachtouris
        @param transfer_encoding (string): Set to chunked to specify incremental uploading
521 afd9d603 Stavros Sachtouris
                (if used, Content-Length is ignored)
522 afd9d603 Stavros Sachtouris
        @param content_encoding (string): The encoding of the object
523 afd9d603 Stavros Sachtouris
        @param content_disposition (string): The presentation style of the object
524 afd9d603 Stavros Sachtouris
        @param source_object (string): Update with data from the object at path /<container>/<object>
525 afd9d603 Stavros Sachtouris
        @param source_account (string): The source account to update from
526 afd9d603 Stavros Sachtouris
        @param source_version (string): The source version to copy from
527 afd9d603 Stavros Sachtouris
        @param object_bytes (integer): The updated objects final size
528 afd9d603 Stavros Sachtouris
        @param manifest (string): Object parts prefix in /<container>/<object> form
529 afd9d603 Stavros Sachtouris
        @param permitions (dict): Object permissions in the form (all fields are optional)
530 afd9d603 Stavros Sachtouris
                {'read':[user1, group1, user2, ...], 'write':['user3, group2, group3, ...]}
531 afd9d603 Stavros Sachtouris
        @param public (bool): If true, Object is publicly accessible, if false, not
532 afd9d603 Stavros Sachtouris
        @param metadata (dict): Optional user defined metadata in the form
533 afd9d603 Stavros Sachtouris
                {'meta-key-1':'meta-value-1', 'meta-key-2':'meta-value-2', ...}
534 afd9d603 Stavros Sachtouris
        """
535 afd9d603 Stavros Sachtouris
        self.assert_container()
536 afd9d603 Stavros Sachtouris
537 afd9d603 Stavros Sachtouris
        self.set_param('format', format, iff=format is not None)
538 afd9d603 Stavros Sachtouris
        self.set_param('update', iff = update)
539 afd9d603 Stavros Sachtouris
540 afd9d603 Stavros Sachtouris
        self.set_header('If-Match', if_etag_match)
541 afd9d603 Stavros Sachtouris
        self.set_header('If-None-Match', if_etag_not_match)
542 afd9d603 Stavros Sachtouris
        self.set_header('Content-Length', content_length, iff=transfer_encoding is None)
543 afd9d603 Stavros Sachtouris
        self.set_header('Content-Type', content_type)
544 afd9d603 Stavros Sachtouris
        self.set_header('Content-Range', content_range)
545 afd9d603 Stavros Sachtouris
        self.set_header('Transfer-Encoding', transfer_encoding)
546 afd9d603 Stavros Sachtouris
        self.set_header('Content-Encoding', content_encoding)
547 afd9d603 Stavros Sachtouris
        self.set_header('Content-Disposition', content_disposition)
548 afd9d603 Stavros Sachtouris
        self.set_header('X-Source-Object', source_object)
549 afd9d603 Stavros Sachtouris
        self.set_header('X-Source-Account', source_account)
550 afd9d603 Stavros Sachtouris
        self.set_header('X-Source-Version', source_version)
551 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Bytes', object_bytes)
552 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Manifest', manifest)
553 afd9d603 Stavros Sachtouris
        perms = None
554 afd9d603 Stavros Sachtouris
        for permition_type, permition_list in permitions.items():
555 afd9d603 Stavros Sachtouris
            if perms is None:
556 afd9d603 Stavros Sachtouris
                perms = '' #Remove permitions
557 afd9d603 Stavros Sachtouris
            if len(permition_list) == 0:
558 afd9d603 Stavros Sachtouris
                continue
559 afd9d603 Stavros Sachtouris
            perms += ';'+permition_type if len(perms) > 0 else permition_type
560 afd9d603 Stavros Sachtouris
            perms += '='+list2str(permition_list, seperator=',')
561 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Sharing', perms)
562 afd9d603 Stavros Sachtouris
        self.set_header('X-Object-Public', public)
563 afd9d603 Stavros Sachtouris
        for key, val in metadata.items():
564 afd9d603 Stavros Sachtouris
            self.set_header('X-Object-Meta-'+key, val)
565 afd9d603 Stavros Sachtouris
566 afd9d603 Stavros Sachtouris
        path = path4url(self.account, self.container, object)
567 afd9d603 Stavros Sachtouris
        success=kwargs.pop('success', (202, 204))
568 afd9d603 Stavros Sachtouris
        return self.post(path, *args, success=success, **kwargs)
569 afd9d603 Stavros Sachtouris
       
570 afd9d603 Stavros Sachtouris
    def object_delete(self, object, until=None, delimiter=None, *args, **kwargs):
571 afd9d603 Stavros Sachtouris
        """ Full Pithos+ DELETE at object level
572 afd9d603 Stavros Sachtouris
        --- request parameters --- 
573 afd9d603 Stavros Sachtouris
        @param until (string): Optional timestamp
574 afd9d603 Stavros Sachtouris
        """
575 afd9d603 Stavros Sachtouris
        self.assert_container()
576 afd9d603 Stavros Sachtouris
577 afd9d603 Stavros Sachtouris
        self.set_param('until', until, iff=until is not None)
578 afd9d603 Stavros Sachtouris
        self.set_param('delimiter', delimiter, iff=delimiter is not None)
579 afd9d603 Stavros Sachtouris
580 afd9d603 Stavros Sachtouris
        path = path4url(self.account, self.container, object)
581 afd9d603 Stavros Sachtouris
        success = kwargs.pop('success', 204)
582 afd9d603 Stavros Sachtouris
        return self.delete(path, *args, success=success, **kwargs)