##// END OF EJS Templates
apply json_clean to comm_msg content...
MinRK -
Show More
@@ -1,142 +1,133 b''
1 1 """Base class for a Comm"""
2 2
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
13 5
14 6 import uuid
15 7
16 8 from IPython.config import LoggingConfigurable
17 9 from IPython.core.getipython import get_ipython
18 10
11 from IPython.utils.jsonutil import json_clean
19 12 from IPython.utils.traitlets import Instance, Unicode, Bytes, Bool, Dict, Any
20 13
21 #-----------------------------------------------------------------------------
22 # Code
23 #-----------------------------------------------------------------------------
24 14
25 15 class Comm(LoggingConfigurable):
26 16
27 17 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
28 18 def _shell_default(self):
29 19 return get_ipython()
30 20
31 21 iopub_socket = Any()
32 22 def _iopub_socket_default(self):
33 23 return self.shell.kernel.iopub_socket
34 24 session = Instance('IPython.kernel.zmq.session.Session')
35 25 def _session_default(self):
36 26 if self.shell is None:
37 27 return
38 28 return self.shell.kernel.session
39 29
40 30 target_name = Unicode('comm')
41 31
42 32 topic = Bytes()
43 33 def _topic_default(self):
44 34 return ('comm-%s' % self.comm_id).encode('ascii')
45 35
46 36 _open_data = Dict(help="data dict, if any, to be included in comm_open")
47 37 _close_data = Dict(help="data dict, if any, to be included in comm_close")
48 38
49 39 _msg_callback = Any()
50 40 _close_callback = Any()
51 41
52 42 _closed = Bool(False)
53 43 comm_id = Unicode()
54 44 def _comm_id_default(self):
55 45 return uuid.uuid4().hex
56 46
57 47 primary = Bool(True, help="Am I the primary or secondary Comm?")
58 48
59 49 def __init__(self, target_name='', data=None, **kwargs):
60 50 if target_name:
61 51 kwargs['target_name'] = target_name
62 52 super(Comm, self).__init__(**kwargs)
63 53 get_ipython().comm_manager.register_comm(self)
64 54 if self.primary:
65 55 # I am primary, open my peer.
66 56 self.open(data)
67 57
68 58 def _publish_msg(self, msg_type, data=None, metadata=None, **keys):
69 59 """Helper for sending a comm message on IOPub"""
70 60 data = {} if data is None else data
71 61 metadata = {} if metadata is None else metadata
62 content = json_clean(dict(data=data, comm_id=self.comm_id, **keys))
72 63 self.session.send(self.iopub_socket, msg_type,
73 dict(data=data, comm_id=self.comm_id, **keys),
74 metadata=metadata,
64 content,
65 metadata=json_clean(metadata),
75 66 parent=self.shell.get_parent(),
76 67 ident=self.topic,
77 68 )
78 69
79 70 def __del__(self):
80 71 """trigger close on gc"""
81 72 self.close()
82 73
83 74 # publishing messages
84 75
85 76 def open(self, data=None, metadata=None):
86 77 """Open the frontend-side version of this comm"""
87 78 if data is None:
88 79 data = self._open_data
89 80 self._publish_msg('comm_open', data, metadata, target_name=self.target_name)
90 81
91 82 def close(self, data=None, metadata=None):
92 83 """Close the frontend-side version of this comm"""
93 84 if self._closed:
94 85 # only close once
95 86 return
96 87 if data is None:
97 88 data = self._close_data
98 89 self._publish_msg('comm_close', data, metadata)
99 90 self._closed = True
100 91
101 92 def send(self, data=None, metadata=None):
102 93 """Send a message to the frontend-side version of this comm"""
103 94 self._publish_msg('comm_msg', data, metadata)
104 95
105 96 # registering callbacks
106 97
107 98 def on_close(self, callback):
108 99 """Register a callback for comm_close
109 100
110 101 Will be called with the `data` of the close message.
111 102
112 103 Call `on_close(None)` to disable an existing callback.
113 104 """
114 105 self._close_callback = callback
115 106
116 107 def on_msg(self, callback):
117 108 """Register a callback for comm_msg
118 109
119 110 Will be called with the `data` of any comm_msg messages.
120 111
121 112 Call `on_msg(None)` to disable an existing callback.
122 113 """
123 114 self._msg_callback = callback
124 115
125 116 # handling of incoming messages
126 117
127 118 def handle_close(self, msg):
128 119 """Handle a comm_close message"""
129 120 self.log.debug("handle_close[%s](%s)", self.comm_id, msg)
130 121 if self._close_callback:
131 122 self._close_callback(msg)
132 123
133 124 def handle_msg(self, msg):
134 125 """Handle a comm_msg message"""
135 126 self.log.debug("handle_msg[%s](%s)", self.comm_id, msg)
136 127 if self._msg_callback:
137 128 self.shell.events.trigger('pre_execute')
138 129 self._msg_callback(msg)
139 130 self.shell.events.trigger('post_execute')
140 131
141 132
142 133 __all__ = ['Comm']
General Comments 0
You need to be logged in to leave comments. Login now