Package s3 :: Module objects
[hide private]
[frames] | no frames]

Source Code for Module s3.objects

  1  from StringIO import StringIO 
  2  from s3.errors import S3Error 
  3  from s3.parsers import parseListKeys 
  4   
5 -class S3Object(object):
6 """ 7 S3Object class 8 """
9 - def __init__(self, key, data, metadata, last_modified=None, bucket=None):
10 self.key = key 11 self.data = data 12 self.metadata = {} 13 for key in metadata: 14 self.metadata[key.lower()] = metadata[key] 15 self.last_modified = last_modified 16 self._bucket = bucket
17
18 - def save(self):
19 """ 20 Save a modified (or same) S3Object to the bucket associated with it. 21 """ 22 if self._bucket: 23 self._bucket.save(self) 24 else: 25 raise S3Error('No bucket selected', 'Object has no bucket associated with itself', self.key)
26
27 - def delete(self):
28 """ 29 Deletes an S3Object from the bucket. 30 """ 31 if self._bucket: 32 self._bucket.delete(self) 33 else: 34 raise S3Error('No bucket selected', 'Object has no bucket associated with itself', self.key)
35 36
37 - def get_meta_for_headers(self):
38 """ 39 Returns a dictionary of metadata keys prepared for inserting them into headers. 40 """ 41 headers = {} 42 for key in self.metadata: 43 headers['x-amz-meta-' + key] = self.metadata[key] 44 return headers
45 46
47 -class S3Bucket(object):
48 """ 49 S3Bucket class 50 51 Behaves like a dictionary of keys in the bucket, with some additional methods. 52 """ 53
54 - def __init__(self, name, connection):
55 self.name = name 56 self._s3_conn = connection
57
58 - def _request(self, method='', obj=None, send_io=None, params=None, headers=None, *args):
59 return getattr(self._s3_conn.clone(), method)(self.name, obj, send_io=send_io, 60 params=params, headers=headers, 61 *args)
62
63 - def __str__(self):
64 return self.name
65
66 - def __repr__(self):
67 return self.name
68 69
70 - def get(self, key, headers={}):
71 """ 72 Get an S3Object from the bucket. 73 74 @param key: Key of the object 75 @type key: string 76 @param headers: Dictionary of additional headers 77 @type headers: dict 78 @return: Selected S3Object if found or None 79 @rtype: S3Object 80 """ 81 response = self._request('GET', key, headers=headers) 82 headers = response.getheaders() 83 data = response.read() 84 metadata = {} 85 last_modified = '' 86 for header in headers: 87 if header[0].startswith('x-amz-meta-'): 88 metadata[header[0][11:]] = header[1] 89 elif header[0] == 'Last-Modified': 90 last_modified = header[1] 91 return S3Object(key, data, metadata, last_modified, self)
92 93
94 - def head(self, key, headers={}):
95 """ 96 Get an object's headers from bucket. 97 98 @param key: Key of the object 99 @type key: string 100 @param headers: Dictionary of additional headers 101 @type headers: dict 102 @return: Dictionary of object headers 103 @rtype: dict 104 """ 105 return dict(self._request('HEAD', key, headers=headers).getheaders())
106 107
108 - def list(self, prefix=None, marker=None, max_keys=None, delimiter=None):
109 """ 110 List bucket objects. 111 112 @param prefix: Limits the response to keys which begin with the 113 indicated prefix. You can use prefixes to separate a 114 bucket into different sets of keys in a way similar to 115 how a file system uses folders. 116 @type prefix: string 117 @param marker: Indicates where in the bucket to begin listing. 118 The list will only include keys that occur 119 lexicographically after marker. This is convenient for 120 pagination: To get the next page of results use the 121 last key of the current page as the marker. 122 @type marker: string 123 @param max_keys: The maximum number of keys you'd like to see in the 124 response body. The server may return fewer than this 125 many keys, but will not return more. 126 @type max_keys: int 127 @param delimiter: Causes keys that contain the same string between the 128 prefix and the first occurrence of the delimiter to be 129 rolled up into a single result element in the 130 CommonPrefixes collection. These rolled-up keys are 131 not returned elsewhere in the response. 132 @type delimiter: char 133 """ 134 keys = self.keys(prefix=prefix, marker=marker, max_keys=max_keys, delimiter=delimiter) 135 objects = [] 136 for key in keys: 137 objects.append(self.get(key)) 138 return objects
139 140
141 - def save(self, s3object, headers={}):
142 """ 143 Save an S3Object into bucket. 144 145 @param s3object: An S3Object that has to be saved 146 @type s3object: S3Object 147 @param headers: Dictionary of additional headers 148 @type headers: dict 149 """ 150 data = s3object.data 151 if isinstance(data, str) or isinstance(data, unicode): 152 data = StringIO(data) 153 for key in s3object.metadata: 154 headers['x-amz-meta-' + key] = s3object.metadata[key] 155 self._request('PUT', s3object.key, send_io=data, headers=headers)
156 157
158 - def delete(self, objects):
159 """ 160 Delete an S3Object, a key or list of keys or objects from bucket. 161 162 @param objects: S3Object, S3Object key, or list of both to be deleted 163 @type objects: S3Object, string, list of S3Objects or list of strings 164 """ 165 if not isinstance(objects, list): 166 objects = [objects,] 167 for obj in objects: 168 if isinstance(obj, S3Object): 169 self._request('DELETE', obj.key) 170 else: 171 self._request('DELETE', obj)
172 173
174 - def keys(self, prefix=None, marker=None, max_keys=None, delimiter=None):
175 """ 176 Returns a flat list of object keys in bucket. 177 178 @param prefix: Limits the response to keys which begin with the 179 indicated prefix. You can use prefixes to separate a 180 bucket into different sets of keys in a way similar to 181 how a file system uses folders. 182 @type prefix: string 183 @param marker: Indicates where in the bucket to begin listing. 184 The list will only include keys that occur 185 lexicographically after marker. This is convenient for 186 pagination: To get the next page of results use the 187 last key of the current page as the marker. 188 @type marker: string 189 @param max_keys: The maximum number of keys you'd like to see in the 190 response body. The server may return fewer than this 191 many keys, but will not return more. 192 @type max_keys: int 193 @param delimiter: Causes keys that contain the same string between the 194 prefix and the first occurrence of the delimiter to be 195 rolled up into a single result element in the 196 CommonPrefixes collection. These rolled-up keys are 197 not returned elsewhere in the response. 198 @type delimiter: char 199 """ 200 params = {} 201 if prefix: params['prefix'] = prefix 202 if marker: params['marker'] = marker 203 if max_keys: params['max-keys'] = max_keys 204 if delimiter: params['delimiter'] = delimiter 205 206 response = self._request('GET', params=params) 207 return parseListKeys(response.read())
208 209 values = list 210
211 - def items(self):
212 """ 213 Returns (key, value) pairs, where, keys are object names, and values are S3Objects. 214 215 @return: List of (bucket name, bucket) pairs 216 @rtype: list 217 """ 218 return zip(self.keys(), self.list())
219
220 - def has_key(self, key):
221 """ 222 Does key exists in bucket. 223 """ 224 return key in self.keys(prefix=key)
225 226
227 - def __getitem__(self, key):
228 """ 229 Get an S3Object from bucket. 230 """ 231 return self.get(key)
232 233
234 - def __delitem__(self, s3object):
235 """ 236 Delete a key from bucket. 237 """ 238 self.delete(s3object)
239