Elliptics version update: 2.19.2.8
[elliptics.git] / bindings / python / elliptics.py
blobada0a5ed7ce6a14700f76df0ff26565b65ff1b29
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 import hashlib
4 import binascii
5 import struct
7 import libelliptics_python
8 from libelliptics_python import log_level, command_flags, io_flags
11 class NodeStatus(libelliptics_python.dnet_node_status):
12 def __repr__(self):
13 return "<NodeStatus nflags:%x, status_flags:%x, log_mask:%x>" % (self.nflags, self.status_flags, self.log_mask)
16 class Id(libelliptics_python.elliptics_id):
17 """
18 Elliptics ID wrapper
19 It has 2 constructors:
20 Id()
21 Id(list_id, group type)
23 list_id - list of 64 bytes, id of the object itself
24 group - group ID of the object
25 type - column
26 """
27 pass
30 class Range(libelliptics_python.elliptics_range):
31 """
32 Structure that describes range request
33 start, end - IDs of the start and the end of the range
34 offset, size - offset to read from and size of bytes to read, applied for each key
35 cflags - command flags like locking so on (default is 0, see cflags class for defenitions)
36 ioflags - command IO flags (default is 0, see ioflags class for definitions)
37 group - group ID of the object
38 type - column
39 """
40 pass
43 class Logger(libelliptics_python.elliptics_log_file):
44 """
45 Logger, that needed in Node constructor
46 Constructor takes 2 arguments: log file name (default is "/dev/stderr")
47 and log level (default is log_level.error, see log_level class for definitions)
48 """
49 log_file_name = ""
50 llevel = log_level.error
52 def __init__(self, log_file_name = "/dev/stderr", llevel = log_level.error):
53 """
54 log_file_name - name of the log file, default value is "/dev/stderr"
55 log_level - logging level, see log_level class for definitions
56 """
57 self.log_file_name = log_file_name
58 self.llevel = llevel
59 super(Logger, self).__init__(log_file_name, llevel)
61 def log(self, message, level):
62 """
63 log some message into elliptics log file
64 message - text message
65 level - log level, default is log_level.error (see log_level class for definitions)
66 """
67 super(Logger, self).log(level, message)
69 def __repr__(self):
70 return "<Logger log_file_name:\"%s\" log_level:%d>" % (self.log_file_name, self.llevel)
73 class Node(libelliptics_python.elliptics_node_python):
74 """
75 Main client class. Constructor takes 1 argument: Logger object
76 """
78 def __init__(self, log=None):
79 """
80 log - Logger object
81 """
82 super(Node, self).__init__(log or Logger())
84 def add_remote(self, addr, port, family=2):
85 """
86 Add address of elliptics storage node and connect to it
87 Usually you do not want to exit if client failed to connect to remote node, so catch up exceptions
88 But if no remote nodes were successfully added (check get_routes()) then client should not continue
89 addr - storage address
90 port - storage port
91 family - IP protocol family: 2 for IPv4 (default value) and 10 for IPv6
92 """
93 super(Node, self).add_remote(addr, port, family)
95 class Session(libelliptics_python.elliptics_session):
96 """
97 Session class. Constructor takes 1 argument: Node object
98 """
100 def __init__(self, node=None):
102 node - None object
104 super(Session, self).__init__(node)
106 def add_groups(self, groups):
108 Set groups to work with
109 groups - list of groups
111 super(Session, self).add_groups(groups)
113 @property
114 def groups(self):
115 return super(Session, self).get_groups()
117 def get_routes(self):
119 Get routing table
121 return value:
122 list - list of node addresses
124 return super(Session, self).get_routes()
126 def stat_log(self):
128 Get nodes statistics
130 return value:
131 string - storage nodes statistics
133 return super(Session, self).stat_log()
135 def lookup_addr(self, *args, **kwargs):
137 Lookup where key should be located by its ID or key and group_id pair
138 signatures:
139 lookup_addr(key, group_id)
140 lookup_addr(id)
142 key - remote key name
143 group_id - group
144 id - object of Id class
146 return value:
147 string - node address
149 return super(Session, self).lookup_addr(*args, **{})
151 def read_file(self, key, filename, offset = 0, size = 0, column = 0):
153 Read file from elliptics by name/ID
154 signatures:
155 read_file(key, filename, offset, size, column)
156 read_file(id, filename, offset, size)
158 key - remote key name
159 column - column type (default is 0, 1 is reserved for metadata)
160 id - object of Id class
162 filename - name of local file where data will be saved
163 offset - read file from this offset (default 0)
164 size - number of bytes to read, 0 means whole file (default is 0)
166 if isinstance(key, basestring):
167 new_args = [str(key), filename, offset, size, column]
168 else:
169 new_args = [key, filename, offset, size]
171 super(Session, self).read_file(*new_args)
173 def write_file(self, key, filename, local_offset = 0, offset = 0, size = 0, \
174 cflags = command_flags.default, ioflags = io_flags.default, column = 0):
176 Write file into elliptics by name/ID
177 signatures:
178 write_file(key, filename, local_offset, offset, size, cflags, ioflags, column)
179 write_file(id, filename, local_offset, offset, size, cflags, ioflags)
181 key - remote key name
182 column - column type (default is 0, 1 is reserved for metadata)
183 id - object of Id class
185 filename - name of local file
186 local_offset - read local file from this offset (default 0)
187 offset - write file from this offset (default 0)
188 size - number of bytes to write, 0 means whole file (default is 0)
189 cflags - command flags (default is 0, see command_flags class for definitions)
190 ioflags - command IO flags (default is 0, see io_flags class for definitions)
192 if isinstance(key, basestring):
193 new_args = [str(key), filename, local_offset, offset, size, cflags, ioflags, column]
194 else:
195 new_args = [key, filename, local_offset, offset, size, cflags, ioflags]
197 super(Session, self).read_file(*new_args)
199 def _create_read_args(self, key, offset = 0, size = 0, cflags = command_flags.default, ioflags = io_flags.default, column = 0):
200 if isinstance(key, basestring):
201 return [str(key), offset, size, cflags, ioflags, column]
202 else:
203 return [key, offset, size, cflags, ioflags]
205 def read_data(self, key, offset = 0, size = 0, cflags = command_flags.default, ioflags = io_flags.default, column = 0):
207 Read data from elliptics by name/ID
208 signatures:
209 read_data(key, offset, size, cflags, ioflags, column)
210 read_data(id, offset, size, cflags, ioflags)
212 key - remote key name
213 column - column type (default is 0, 1 is reserved for metadata)
214 id - object of Id class
216 offset - read file from this offset (default 0)
217 size - number of bytes to read, 0 means whole file (default is 0)
218 cflags - command flags (default is 0, see command_flags class for definitions)
219 ioflags - command IO flags (default is 0, see io_flags class for definitions)
221 return value:
222 string - key value content
224 return super(Session, self).read_data(*self._create_read_args(key, offset, size, cflags, ioflags, column))
226 read = read_data
228 def read_latest(self, key, offset = 0, size = 0, cflags = command_flags.default, ioflags = io_flags.default, column = 0):
230 Read data from elliptics by name/ID with the latest update_date in metadata
231 signatures:
232 read_latest(key, offset, size, cflags, ioflags, column)
233 read_latest(id, offset, size, cflags, ioflags)
235 key - remote key name
236 column - column type (default is 0, 1 is reserved for metadata)
237 id - object of Id class
239 offset - read file from this offset (default 0)
240 size - number of bytes to read, 0 means whole file (default is 0)
241 cflags - command flags flags (default is 0, see command_flags class for definitions)
242 ioflags - command IO flags (default is 0, see io_flags class for definitions)
244 return value:
245 string - key value content
247 return super(Session, self).read_latest(*self._create_read_args(key, offset, size, cflags, ioflags, column))
249 def create_write_args(self, key, data, offset, ioflags, cflags, column):
250 if isinstance(key, basestring):
251 return [str(key), data, offset, cflags, ioflags, column]
252 else:
253 return [key, data, offset, cflags, ioflags]
255 def write_data(self, key, data, offset = 0, cflags = command_flags.default, ioflags = io_flags.default, column = 0):
257 Write data into elliptics by name/ID
258 signatures:
259 write_data(key, data, offset, cflags, ioflags, column)
260 write_data(id, data, offset, cflags, ioflags)
262 key - remote key name
263 column - column type (default is 0, 1 is reserved for metadata)
264 id - object of Id class
266 data - data to be written
267 offset - write data in remote from this offset (default 0)
268 cflags - command flags flags (default is 0, see command_flags class for definitions)
269 ioflags - command IO flags (default is 0, see io_flags class for definitions)
271 return value:
272 string - nodes and paths where data was stored
274 return super(Session, self).write_data(*self.create_write_args(key, data, offset, ioflags, cflags, column))
276 def write_metadata(self, key, cflags = command_flags.default, name = None, groups = None):
278 Write metadata into elliptics by name/ID
279 signatures:
280 write_metadata(key, cflags)
281 write_metadata(id, name, groups, cflags)
283 key - remote key name
284 id - object of Id class
286 name - key name
287 groups - groups where data was stored
288 cflags - command flags (default is 0, see command_flags class for definitions)
290 if isinstance(key, basestring):
291 new_args = [str(key), cflags]
292 else:
293 new_args = [key, name, groups, cflags]
295 super(Session, self).write_metadata(*new_args)
297 def write(self, key, data):
299 Simple write
301 self.write_data(key, data)
302 self.write_metadata(key)
304 def remove(self, key, cflags = command_flags.default, ioflags = io_flags.default, column = 0):
306 Remove key by name/ID
307 signatures:
308 remove(key, cflags, ioflags, column)
309 remove(id, cflags, ioflags)
311 key - remote key name
312 column - column type (default is 0, 1 is reserved for metadata)
313 id - object of Id class
315 cflags - command flags flags (default is 0, see command_flags class for definitions)
316 ioflags - command IO flags (default is 0, see io_flags class for definitions)
318 if isinstance(key, basestring):
319 new_args = [str(key), cflags, ioflags, column]
320 else:
321 new_args = [key, cflags, ioflags]
323 super(Session, self).remove(*new_args)
325 def execute(self, *args, **kwargs):
327 Execite server-side script
328 signatures:
329 exec(id, event, data, binary)
330 exec(key, event, data, binary)
331 exec(event, data, binary)
333 key - remote key name
334 id - object of Id class
336 event - server-side event name
337 data - data for given event
338 binary - binary data (its logical meaning is the same as for data, it was added for convenience)
340 If execute() is called with 3 arguments script will be started on all storage nodes.
341 If id or key is specified script will be started on the node which hosts given key/id.
343 return value:
344 string - result of the script execution
346 return super(Session, self).execute(*args, **{})
348 def update_status(self, key, status = None, update = 0):
350 Update elliptics status and log mask
351 signatures:
352 update_status(id, status, update)
353 update_status((addr, port, family), status, update)
355 key - remote key name
356 id - object of Id class
358 addr - storage address
359 port - storage port
360 family - IP protocol family: 2 for IPv4 (default value) and 10 for IPv6
361 status - new node status, object of SessionStatus class
362 update - update status or just return current (default is 0)
364 If update = 0 status will not be changed
366 return value:
367 SessionStatus - current node status
369 status = status or SessionStatus()
370 if hasattr(key, '__iter__'):
371 new_args = (key[0], key[1], key[2], status, update)
372 else:
373 new_args = (key, status, update)
375 ret = super(Session, self).update_status(*new_args)
376 ret.__class__ = SessionStatus
377 return ret
379 def bulk_read(self, keys, cflags = command_flags.default, raw=False):
381 Bulk read keys from elliptics
382 keys - list of keys by name
383 cflags - command flags (default is 0, see command_flags class for definitions)
385 return value:
386 dict: key - original key, value - data itself
387 if raw is True: list - list of strings, each string consists of 64 byte key (sha-512 of original key), 8 byte data length and data itself
389 if type(keys) in set([tuple, list, set, dict]):
390 keys = list(keys)
392 rv = super(Session, self).bulk_read(keys, cflags)
394 if raw:
395 return rv
397 if not rv:
398 return {}
400 keys = dict([(hashlib.sha512(key).hexdigest(), key) for key in keys])
402 rv_dict = {}
403 for r in rv:
404 key = binascii.hexlify(r[:64])
405 data_len = struct.unpack('Q', r[64:72])[0]
406 data = struct.unpack("%ss" % data_len, r[72:72 + data_len])[0]
407 rv_dict[keys[key]] = data
408 return rv_dict
410 def read_data_range(self, read_range):
412 Read keys from elliptics by range of IDs
413 read_range - object of Range class
415 return value:
416 list - list of strings, each string consists of 64 byte key, 8 byte data length and data itself
418 return super(Session, self).read_data_range(read_range)