def deserialize(self, msg_list, content=True, copy=True): """Unserialize a msg_list to a nested message dict. This is roughly the inverse of serialize. The serialize/deserialize methods work with full message lists, whereas pack/unpack work with the individual message parts in the message list. Parameters ---------- msg_list : list of bytes or Message objects The list of message parts of the form [HMAC,p_header,p_parent, p_metadata,p_content,buffer1,buffer2,...]. content : bool (True) Whether to unpack the content dict (True), or leave it packed (False). copy : bool (True) Whether msg_list contains bytes (True) or the non-copying Message objects in each place (False). Returns ------- msg : dict The nested message dict with top-level keys [header, parent_header, content, buffers]. The buffers are returned as memoryviews. """ minlen = 5 message = {} if not copy: # pyzmq didn't copy the first parts of the message, so we'll do it for i in range(minlen): msg_list[i] = msg_list[i].bytes if self.auth is not None: signature = msg_list[0] if not signature: raise ValueError("Unsigned Message") if signature in self.digest_history: raise ValueError("Duplicate Signature: %r" % signature) self._add_digest(signature) check = self.sign(msg_list[1:5]) if not compare_digest(signature, check): raise ValueError("Invalid Signature: %r" % signature) if not len(msg_list) >= minlen: raise TypeError("malformed message, must have at least %i elements"%minlen) header = self.unpack(msg_list[1]) message['header'] = extract_dates(header) message['msg_id'] = header['msg_id'] message['msg_type'] = header['msg_type'] message['parent_header'] = extract_dates(self.unpack(msg_list[2])) message['metadata'] = self.unpack(msg_list[3]) if content: message['content'] = self.unpack(msg_list[4]) else: message['content'] = msg_list[4] buffers = [memoryview(b) for b in msg_list[5:]] if buffers and buffers[0].shape is None: # force copy to workaround pyzmq #646 buffers = [memoryview(b.bytes) for b in msg_list[5:]] message['buffers'] = buffers # adapt to the current version return adapt(message)
def deserialize_binary_message(bmsg): """deserialize a message from a binary blog Header: 4 bytes: number of msg parts (nbufs) as 32b int 4 * nbufs bytes: offset for each buffer as integer as 32b int Offsets are from the start of the buffer, including the header. Returns ------- message dictionary """ nbufs = struct.unpack('!i', bmsg[:4])[0] offsets = list(struct.unpack('!' + 'I' * nbufs, bmsg[4:4 * (nbufs + 1)])) offsets.append(None) bufs = [] for start, stop in zip(offsets[:-1], offsets[1:]): bufs.append(bmsg[start:stop]) msg = json.loads(bufs[0].decode('utf8')) msg['header'] = extract_dates(msg['header']) msg['parent_header'] = extract_dates(msg['parent_header']) msg['buffers'] = bufs[1:] return msg
def deserialize_binary_message(bmsg): """deserialize a message from a binary blog Header: 4 bytes: number of msg parts (nbufs) as 32b int 4 * nbufs bytes: offset for each buffer as integer as 32b int Offsets are from the start of the buffer, including the header. Returns ------- message dictionary """ nbufs = struct.unpack('!i', bmsg[:4])[0] offsets = list(struct.unpack('!' + 'I' * nbufs, bmsg[4:4*(nbufs+1)])) offsets.append(None) bufs = [] for start, stop in zip(offsets[:-1], offsets[1:]): bufs.append(bmsg[start:stop]) msg = json.loads(bufs[0].decode('utf8')) msg['header'] = extract_dates(msg['header']) msg['parent_header'] = extract_dates(msg['parent_header']) msg['buffers'] = bufs[1:] return msg
def unserialize(self, msg_list, content=True, copy=True): """Unserialize a msg_list to a nested message dict. This is roughly the inverse of serialize. The serialize/unserialize methods work with full message lists, whereas pack/unpack work with the individual message parts in the message list. Parameters ---------- msg_list : list of bytes or Message objects The list of message parts of the form [HMAC,p_header,p_parent, p_metadata,p_content,buffer1,buffer2,...]. content : bool (True) Whether to unpack the content dict (True), or leave it packed (False). copy : bool (True) Whether to return the bytes (True), or the non-copying Message object in each place (False). Returns ------- msg : dict The nested message dict with top-level keys [header, parent_header, content, buffers]. """ minlen = 5 message = {} if not copy: for i in range(minlen): msg_list[i] = msg_list[i].bytes if self.auth is not None: signature = msg_list[0] if not signature: raise ValueError("Unsigned Message") if signature in self.digest_history: raise ValueError("Duplicate Signature: %r" % signature) self._add_digest(signature) check = self.sign(msg_list[1:5]) if not signature == check: raise ValueError("Invalid Signature: %r" % signature) if not len(msg_list) >= minlen: raise TypeError( "malformed message, must have at least %i elements" % minlen) header = self.unpack(msg_list[1]) message['header'] = extract_dates(header) message['msg_id'] = header['msg_id'] message['msg_type'] = header['msg_type'] message['parent_header'] = extract_dates(self.unpack(msg_list[2])) message['metadata'] = self.unpack(msg_list[3]) if content: message['content'] = self.unpack(msg_list[4]) else: message['content'] = msg_list[4] message['buffers'] = msg_list[5:] # print("received: %s: %s\n %s" % (message['msg_type'], message['header'], message['content'])) # adapt to the current version return adapt(message)
def unserialize(self, msg_list, content=True, copy=True): """Unserialize a msg_list to a nested message dict. This is roughly the inverse of serialize. The serialize/unserialize methods work with full message lists, whereas pack/unpack work with the individual message parts in the message list. Parameters ---------- msg_list : list of bytes or Message objects The list of message parts of the form [HMAC,p_header,p_parent, p_metadata,p_content,buffer1,buffer2,...]. content : bool (True) Whether to unpack the content dict (True), or leave it packed (False). copy : bool (True) Whether to return the bytes (True), or the non-copying Message object in each place (False). Returns ------- msg : dict The nested message dict with top-level keys [header, parent_header, content, buffers]. """ minlen = 5 message = {} if not copy: for i in range(minlen): msg_list[i] = msg_list[i].bytes if self.auth is not None: signature = msg_list[0] if not signature: raise ValueError("Unsigned Message") if signature in self.digest_history: raise ValueError("Duplicate Signature: %r" % signature) self._add_digest(signature) check = self.sign(msg_list[1:5]) if not signature == check: raise ValueError("Invalid Signature: %r" % signature) if not len(msg_list) >= minlen: raise TypeError("malformed message, must have at least %i elements"%minlen) header = self.unpack(msg_list[1]) message['header'] = extract_dates(header) message['msg_id'] = header['msg_id'] message['msg_type'] = header['msg_type'] message['parent_header'] = extract_dates(self.unpack(msg_list[2])) message['metadata'] = self.unpack(msg_list[3]) if content: message['content'] = self.unpack(msg_list[4]) else: message['content'] = msg_list[4] message['buffers'] = msg_list[5:] # print("received: %s: %s\n %s" % (message['msg_type'], message['header'], message['content'])) # adapt to the current version return adapt(message)
def _check_packers(self): """check packers for binary data and datetime support.""" pack = self.pack unpack = self.unpack # check simple serialization msg = dict(a=[1,'hi']) try: packed = pack(msg) except Exception: raise ValueError("packer could not serialize a simple message") # ensure packed message is bytes if not isinstance(packed, bytes): raise ValueError("message packed to %r, but bytes are required"%type(packed)) # check that unpack is pack's inverse try: unpacked = unpack(packed) except Exception: raise ValueError("unpacker could not handle the packer's output") # check datetime support msg = dict(t=datetime.now()) try: unpacked = unpack(pack(msg)) except Exception: self.pack = lambda o: pack(squash_dates(o)) self.unpack = lambda s: extract_dates(unpack(s))
def _check_packers(self): """check packers for binary data and datetime support.""" pack = self.pack unpack = self.unpack # check simple serialization msg = dict(a=[1, 'hi']) try: packed = pack(msg) except Exception: raise ValueError("packer could not serialize a simple message") # ensure packed message is bytes if not isinstance(packed, bytes): raise ValueError("message packed to %r, but bytes are required" % type(packed)) # check that unpack is pack's inverse try: unpacked = unpack(packed) except Exception: raise ValueError("unpacker could not handle the packer's output") # check datetime support msg = dict(t=datetime.now()) try: unpacked = unpack(pack(msg)) except Exception: self.pack = lambda o: pack(squash_dates(o)) self.unpack = lambda s: extract_dates(unpack(s))
def test_date_default(): data = dict(today=datetime.datetime.now(), utcnow=tz.utcnow()) jsondata = json.dumps(data, default=jsonutil.date_default) nt.assert_in("+00", jsondata) nt.assert_equal(jsondata.count("+00"), 1) extracted = jsonutil.extract_dates(json.loads(jsondata)) for dt in extracted.values(): nt.assert_true(isinstance(dt, datetime.datetime))
def _datetime_test(self, session): content = dict(t=datetime.now()) metadata = dict(t=datetime.now()) p = session.msg('msg') msg = session.msg('msg', content=content, metadata=metadata, parent=p['header']) smsg = session.serialize(msg) msg2 = session.unserialize(session.feed_identities(smsg)[1]) assert isinstance(msg2['header']['date'], datetime) self.assertEqual(msg['header'], msg2['header']) self.assertEqual(msg['parent_header'], msg2['parent_header']) self.assertEqual(msg['parent_header'], msg2['parent_header']) assert isinstance(msg['content']['t'], datetime) assert isinstance(msg['metadata']['t'], datetime) assert isinstance(msg2['content']['t'], string_types) assert isinstance(msg2['metadata']['t'], string_types) self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content'])) self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
def _datetime_test(self, session): content = dict(t=datetime.now()) metadata = dict(t=datetime.now()) p = session.msg('msg') msg = session.msg('msg', content=content, metadata=metadata, parent=p['header']) smsg = session.serialize(msg) msg2 = session.deserialize(session.feed_identities(smsg)[1]) assert isinstance(msg2['header']['date'], datetime) self.assertEqual(msg['header'], msg2['header']) self.assertEqual(msg['parent_header'], msg2['parent_header']) self.assertEqual(msg['parent_header'], msg2['parent_header']) assert isinstance(msg['content']['t'], datetime) assert isinstance(msg['metadata']['t'], datetime) assert isinstance(msg2['content']['t'], string_types) assert isinstance(msg2['metadata']['t'], string_types) self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content'])) self.assertEqual(msg['content'], jsonutil.extract_dates(msg2['content']))
def test_date_default(): data = dict(today=datetime.datetime.now(), utcnow=tz.utcnow()) jsondata = json.dumps(data, default=jsonutil.date_default) nt.assert_in("+00", jsondata) nt.assert_equal(jsondata.count("+00"), 1) extracted = jsonutil.extract_dates(json.loads(jsondata)) for dt in list(extracted.values()): nt.assert_true(isinstance(dt, datetime.datetime))
def _convert_dict(ds): if ds is None: return ds else: if isinstance(ds, bytes): # If I understand the sqlite doc correctly, this will always be utf8 ds = ds.decode("utf8") return extract_dates(json.loads(ds))
def _convert_dict(ds): if ds is None: return ds else: if isinstance(ds, bytes): # If I understand the sqlite doc correctly, this will always be utf8 ds = ds.decode('utf8') return extract_dates(json.loads(ds))
def _check_packers(self): """check packers for binary data and datetime support.""" pack = self.pack unpack = self.unpack # check simple serialization msg = dict(a=[1, 'hi']) try: packed = pack(msg) except Exception as e: msg = "packer '{packer}' could not serialize a simple message: {e}{jsonmsg}" if self.packer == 'json': jsonmsg = "\nzmq.utils.jsonapi.jsonmod = %s" % jsonapi.jsonmod else: jsonmsg = "" raise ValueError( msg.format(packer=self.packer, e=e, jsonmsg=jsonmsg)) # ensure packed message is bytes if not isinstance(packed, bytes): raise ValueError("message packed to %r, but bytes are required" % type(packed)) # check that unpack is pack's inverse try: unpacked = unpack(packed) assert unpacked == msg except Exception as e: msg = "unpacker '{unpacker}' could not handle output from packer '{packer}': {e}{jsonmsg}" if self.packer == 'json': jsonmsg = "\nzmq.utils.jsonapi.jsonmod = %s" % jsonapi.jsonmod else: jsonmsg = "" raise ValueError( msg.format(packer=self.packer, unpacker=self.unpacker, e=e, jsonmsg=jsonmsg)) # check datetime support msg = dict(t=datetime.now()) try: unpacked = unpack(pack(msg)) except Exception: self.pack = lambda o: pack(squash_dates(o)) self.unpack = lambda s: extract_dates(unpack(s))
def test_extract_dates(): timestamps = [ '2013-07-03T16:34:52.249482', '2013-07-03T16:34:52.249482Z', '2013-07-03T16:34:52.249482Z-0800', '2013-07-03T16:34:52.249482Z+0800', '2013-07-03T16:34:52.249482Z+08:00', '2013-07-03T16:34:52.249482Z-08:00', '2013-07-03T16:34:52.249482-0800', '2013-07-03T16:34:52.249482+0800', '2013-07-03T16:34:52.249482+08:00', '2013-07-03T16:34:52.249482-08:00', ] extracted = jsonutil.extract_dates(timestamps) ref = extracted[0] for dt in extracted: nt.assert_true(isinstance(dt, datetime.datetime)) nt.assert_equal(dt, ref)
def test_extract_dates(): timestamps = [ "2013-07-03T16:34:52.249482", "2013-07-03T16:34:52.249482Z", "2013-07-03T16:34:52.249482Z-0800", "2013-07-03T16:34:52.249482Z+0800", "2013-07-03T16:34:52.249482Z+08:00", "2013-07-03T16:34:52.249482Z-08:00", "2013-07-03T16:34:52.249482-0800", "2013-07-03T16:34:52.249482+0800", "2013-07-03T16:34:52.249482+08:00", "2013-07-03T16:34:52.249482-08:00", ] extracted = jsonutil.extract_dates(timestamps) ref = extracted[0] for dt in extracted: nt.assert_true(isinstance(dt, datetime.datetime)) nt.assert_equal(dt, ref)
def _check_packers(self): """check packers for binary data and datetime support.""" pack = self.pack unpack = self.unpack # check simple serialization msg = dict(a=[1,'hi']) try: packed = pack(msg) except Exception as e: msg = "packer '{packer}' could not serialize a simple message: {e}{jsonmsg}" if self.packer == 'json': jsonmsg = "\nzmq.utils.jsonapi.jsonmod = %s" % jsonapi.jsonmod else: jsonmsg = "" raise ValueError( msg.format(packer=self.packer, e=e, jsonmsg=jsonmsg) ) # ensure packed message is bytes if not isinstance(packed, bytes): raise ValueError("message packed to %r, but bytes are required"%type(packed)) # check that unpack is pack's inverse try: unpacked = unpack(packed) assert unpacked == msg except Exception as e: msg = "unpacker '{unpacker}' could not handle output from packer '{packer}': {e}{jsonmsg}" if self.packer == 'json': jsonmsg = "\nzmq.utils.jsonapi.jsonmod = %s" % jsonapi.jsonmod else: jsonmsg = "" raise ValueError( msg.format(packer=self.packer, unpacker=self.unpacker, e=e, jsonmsg=jsonmsg) ) # check datetime support msg = dict(t=datetime.now()) try: unpacked = unpack(pack(msg)) except Exception: self.pack = lambda o: pack(squash_dates(o)) self.unpack = lambda s: extract_dates(unpack(s))
def unserialize(self, msg_list, content=True, copy=True): """Unserialize a msg_list to a nested message dict. This is roughly the inverse of serialize. The serialize/unserialize methods work with full message lists, whereas pack/unpack work with the individual message parts in the message list. Parameters ---------- msg_list : list of bytes or Message objects The list of message parts of the form [HMAC,p_header,p_parent, p_metadata,p_content,buffer1,buffer2,...]. content : bool (True) Whether to unpack the content dict (True), or leave it packed (False). copy : bool (True) Whether to return the bytes (True), or the non-copying Message object in each place (False). Returns ------- msg : dict The nested message dict with top-level keys [header, parent_header, content, buffers]. """ erlang_debug = False minlen = 5 message = {} if not copy: for i in range(minlen): msg_list[i] = msg_list[i].bytes if self.auth is not None: signature = msg_list[0] if not signature: raise ValueError("Unsigned Message") if signature in self.digest_history: raise ValueError("Duplicate Signature: %r" % signature) self._add_digest(signature) check = self.sign(msg_list[1:5]) if not signature == check: raise ValueError("Invalid Signature: %r" % signature) if not len(msg_list) >= minlen: raise TypeError("malformed message, must have at least %i elements"%minlen) header = self.unpack(msg_list[1]) message['header'] = extract_dates(header) message['msg_id'] = header['msg_id'] message['msg_type'] = header['msg_type'] message['parent_header'] = extract_dates(self.unpack(msg_list[2])) message['metadata'] = self.unpack(msg_list[3]) if content: message['content'] = self.unpack(msg_list[4]) else: message['content'] = msg_list[4] ################################################################################### ##IERLANG CODE##################################################################### ##Extract header elements from erlang strings ierl_header = extract_dates(header) try: ierl_header['username'] = self.erl_string_to_string(ierl_header['username'], erlang_debug) except Exception: ierl_header['username'] = "******" ##If using the ERLANG_KERNEL then parse the erlang strings if ierl_header['username'] == "ierlang_kernel": ierl_header['session'] = self.erl_string_to_string(ierl_header['session'], erlang_debug) ierl_header['msg_id'] = self.erl_string_to_string(ierl_header['msg_id'], erlang_debug) ierl_header['msg_type'] = self.erl_string_to_string(ierl_header['msg_type'], erlang_debug) #Build message dict message['header'] = ierl_header message['msg_id'] = self.erl_string_to_string(header["msg_id"], erlang_debug) if content: ierl_msg_content = self.unpack(msg_list[4]) message['content'] = self.ierlang_content_parser(ierl_msg_content, ierl_header['msg_type'], erlang_debug) else: ierl_msg_content = msg_list[4] message['content'] = {} if erlang_debug: print("\n") print("[IErlang/IPython] Received message from kernel....") print("[IErlang/IPython] header = " + str(message['header'])) print("[IErlang/IPython] msg_id = " + str(message['msg_id'])) print("[IErlang/IPython] parent_header = " + str(message['parent_header'])) print("[IErlang/IPython] metadata = " + str(message['metadata'])) print("[IErlang/IPython] content = " + str(message['content'])) print("\n") ##END IERLANG CODE##################################################################### message['buffers'] = msg_list[5:] return message
if isinstance(key, unicode): obj[squash_unicode(key)] = obj.pop(key) elif isinstance(obj, list): for i, v in enumerate(obj): obj[i] = squash_unicode(v) elif isinstance(obj, unicode): obj = obj.encode('utf8') return obj #----------------------------------------------------------------------------- # globals and defaults #----------------------------------------------------------------------------- key = 'on_unknown' if jsonapi.jsonmod.__name__ == 'jsonlib' else 'default' json_packer = lambda obj: jsonapi.dumps(obj, **{key: date_default}) json_unpacker = lambda s: extract_dates(jsonapi.loads(s)) pickle_packer = lambda o: pickle.dumps(o, -1) pickle_unpacker = pickle.loads default_packer = json_packer default_unpacker = json_unpacker DELIM = b"<IDS|MSG>" #----------------------------------------------------------------------------- # Classes #----------------------------------------------------------------------------- class SessionFactory(LoggingConfigurable):
def _convert_dict(ds): if ds is None: return ds else: return extract_dates(json.loads(ds))
obj[squash_unicode(key)] = obj.pop(key) elif isinstance(obj, list): for i,v in enumerate(obj): obj[i] = squash_unicode(v) elif isinstance(obj, unicode): obj = obj.encode('utf8') return obj #----------------------------------------------------------------------------- # globals and defaults #----------------------------------------------------------------------------- _version_info_list = list(IPython.version_info) # ISO8601-ify datetime objects json_packer = lambda obj: jsonapi.dumps(obj, default=date_default) json_unpacker = lambda s: extract_dates(jsonapi.loads(s)) pickle_packer = lambda o: pickle.dumps(o,-1) pickle_unpacker = pickle.loads default_packer = json_packer default_unpacker = json_unpacker DELIM = b"<IDS|MSG>" # singleton dummy tracker, which will always report as done DONE = zmq.MessageTracker() #----------------------------------------------------------------------------- # Mixin tools for apps that use Sessions #-----------------------------------------------------------------------------
# jsonlib behaves a bit differently, so handle that where it affects us if jsonapi.jsonmod.__name__ == 'jsonlib': # kwarg for serializing unknown types (datetime) is different dumps_kwargs = dict(on_unknown=date_default) # By default, jsonlib unpacks floats as Decimal instead of float, # which can foul things up loads_kwargs = dict(use_float=True) else: # ISO8601-ify datetime objects dumps_kwargs = dict(default=date_default) # nothing to specify for loads loads_kwargs = dict() json_packer = lambda obj: jsonapi.dumps(obj, **dumps_kwargs) json_unpacker = lambda s: extract_dates(jsonapi.loads(s, **loads_kwargs)) pickle_packer = lambda o: pickle.dumps(o,-1) pickle_unpacker = pickle.loads default_packer = json_packer default_unpacker = json_unpacker DELIM=b"<IDS|MSG>" #----------------------------------------------------------------------------- # Mixin tools for apps that use Sessions #----------------------------------------------------------------------------- session_aliases = dict(