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