##// END OF EJS Templates
mention proxy methods in KernelClient docstring
MinRK -
Show More
@@ -1,194 +1,198 b''
1 """Base class to manage the interaction with a running kernel
1 """Base class to manage the interaction with a running kernel
2 """
2 """
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2013 The IPython Development Team
5 # Copyright (C) 2013 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 from __future__ import absolute_import
15 from __future__ import absolute_import
16
16
17 import zmq
17 import zmq
18
18
19 # Local imports
19 # Local imports
20 from IPython.config.configurable import LoggingConfigurable
20 from IPython.config.configurable import LoggingConfigurable
21 from IPython.utils.traitlets import (
21 from IPython.utils.traitlets import (
22 Any, Instance, Type,
22 Any, Instance, Type,
23 )
23 )
24
24
25 from .zmq.session import Session
25 from .zmq.session import Session
26 from .channels import (
26 from .channels import (
27 ShellChannel, IOPubChannel,
27 ShellChannel, IOPubChannel,
28 HBChannel, StdInChannel,
28 HBChannel, StdInChannel,
29 )
29 )
30 from .clientabc import KernelClientABC
30 from .clientabc import KernelClientABC
31 from .connect import ConnectionFileMixin
31 from .connect import ConnectionFileMixin
32
32
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # Main kernel client class
35 # Main kernel client class
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38 class KernelClient(LoggingConfigurable, ConnectionFileMixin):
38 class KernelClient(LoggingConfigurable, ConnectionFileMixin):
39 """Communicates with a single kernel on any host via zmq channels.
39 """Communicates with a single kernel on any host via zmq channels.
40
40
41 There are four channels associated with each kernel:
41 There are four channels associated with each kernel:
42
42
43 * shell: for request/reply calls to the kernel.
43 * shell: for request/reply calls to the kernel.
44 * iopub: for the kernel to publish results to frontends.
44 * iopub: for the kernel to publish results to frontends.
45 * hb: for monitoring the kernel's heartbeat.
45 * hb: for monitoring the kernel's heartbeat.
46 * stdin: for frontends to reply to raw_input calls in the kernel.
46 * stdin: for frontends to reply to raw_input calls in the kernel.
47
47
48 The methods of the channels are exposed as methods of the client itself
49 (KernelClient.execute, complete, history, etc.).
50 See the channels themselves for documentation of these methods.
51
48 """
52 """
49
53
50 # The PyZMQ Context to use for communication with the kernel.
54 # The PyZMQ Context to use for communication with the kernel.
51 context = Instance(zmq.Context)
55 context = Instance(zmq.Context)
52 def _context_default(self):
56 def _context_default(self):
53 return zmq.Context.instance()
57 return zmq.Context.instance()
54
58
55 # The Session to use for communication with the kernel.
59 # The Session to use for communication with the kernel.
56 session = Instance(Session)
60 session = Instance(Session)
57 def _session_default(self):
61 def _session_default(self):
58 return Session(config=self.config)
62 return Session(config=self.config)
59
63
60 # The classes to use for the various channels
64 # The classes to use for the various channels
61 shell_channel_class = Type(ShellChannel)
65 shell_channel_class = Type(ShellChannel)
62 iopub_channel_class = Type(IOPubChannel)
66 iopub_channel_class = Type(IOPubChannel)
63 stdin_channel_class = Type(StdInChannel)
67 stdin_channel_class = Type(StdInChannel)
64 hb_channel_class = Type(HBChannel)
68 hb_channel_class = Type(HBChannel)
65
69
66 # Protected traits
70 # Protected traits
67 _shell_channel = Any
71 _shell_channel = Any
68 _iopub_channel = Any
72 _iopub_channel = Any
69 _stdin_channel = Any
73 _stdin_channel = Any
70 _hb_channel = Any
74 _hb_channel = Any
71
75
72 #--------------------------------------------------------------------------
76 #--------------------------------------------------------------------------
73 # Channel proxy methods
77 # Channel proxy methods
74 #--------------------------------------------------------------------------
78 #--------------------------------------------------------------------------
75
79
76 def _get_msg(channel, *args, **kwargs):
80 def _get_msg(channel, *args, **kwargs):
77 return channel.get_msg(*args, **kwargs)
81 return channel.get_msg(*args, **kwargs)
78
82
79 def get_shell_msg(self, *args, **kwargs):
83 def get_shell_msg(self, *args, **kwargs):
80 """Get a message from the shell channel"""
84 """Get a message from the shell channel"""
81 return self.shell_channel.get_msg(*args, **kwargs)
85 return self.shell_channel.get_msg(*args, **kwargs)
82
86
83 def get_iopub_msg(self, *args, **kwargs):
87 def get_iopub_msg(self, *args, **kwargs):
84 """Get a message from the iopub channel"""
88 """Get a message from the iopub channel"""
85 return self.iopub_channel.get_msg(*args, **kwargs)
89 return self.iopub_channel.get_msg(*args, **kwargs)
86
90
87 def get_stdin_msg(self, *args, **kwargs):
91 def get_stdin_msg(self, *args, **kwargs):
88 """Get a message from the stdin channel"""
92 """Get a message from the stdin channel"""
89 return self.stdin_channel.get_msg(*args, **kwargs)
93 return self.stdin_channel.get_msg(*args, **kwargs)
90
94
91 #--------------------------------------------------------------------------
95 #--------------------------------------------------------------------------
92 # Channel management methods
96 # Channel management methods
93 #--------------------------------------------------------------------------
97 #--------------------------------------------------------------------------
94
98
95 def start_channels(self, shell=True, iopub=True, stdin=True, hb=True):
99 def start_channels(self, shell=True, iopub=True, stdin=True, hb=True):
96 """Starts the channels for this kernel.
100 """Starts the channels for this kernel.
97
101
98 This will create the channels if they do not exist and then start
102 This will create the channels if they do not exist and then start
99 them (their activity runs in a thread). If port numbers of 0 are
103 them (their activity runs in a thread). If port numbers of 0 are
100 being used (random ports) then you must first call
104 being used (random ports) then you must first call
101 :method:`start_kernel`. If the channels have been stopped and you
105 :method:`start_kernel`. If the channels have been stopped and you
102 call this, :class:`RuntimeError` will be raised.
106 call this, :class:`RuntimeError` will be raised.
103 """
107 """
104 if shell:
108 if shell:
105 self.shell_channel.start()
109 self.shell_channel.start()
106 for method in self.shell_channel.proxy_methods:
110 for method in self.shell_channel.proxy_methods:
107 setattr(self, method, getattr(self.shell_channel, method))
111 setattr(self, method, getattr(self.shell_channel, method))
108 if iopub:
112 if iopub:
109 self.iopub_channel.start()
113 self.iopub_channel.start()
110 for method in self.iopub_channel.proxy_methods:
114 for method in self.iopub_channel.proxy_methods:
111 setattr(self, method, getattr(self.iopub_channel, method))
115 setattr(self, method, getattr(self.iopub_channel, method))
112 if stdin:
116 if stdin:
113 self.stdin_channel.start()
117 self.stdin_channel.start()
114 for method in self.stdin_channel.proxy_methods:
118 for method in self.stdin_channel.proxy_methods:
115 setattr(self, method, getattr(self.stdin_channel, method))
119 setattr(self, method, getattr(self.stdin_channel, method))
116 self.shell_channel.allow_stdin = True
120 self.shell_channel.allow_stdin = True
117 else:
121 else:
118 self.shell_channel.allow_stdin = False
122 self.shell_channel.allow_stdin = False
119 if hb:
123 if hb:
120 self.hb_channel.start()
124 self.hb_channel.start()
121
125
122 def stop_channels(self):
126 def stop_channels(self):
123 """Stops all the running channels for this kernel.
127 """Stops all the running channels for this kernel.
124
128
125 This stops their event loops and joins their threads.
129 This stops their event loops and joins their threads.
126 """
130 """
127 if self.shell_channel.is_alive():
131 if self.shell_channel.is_alive():
128 self.shell_channel.stop()
132 self.shell_channel.stop()
129 if self.iopub_channel.is_alive():
133 if self.iopub_channel.is_alive():
130 self.iopub_channel.stop()
134 self.iopub_channel.stop()
131 if self.stdin_channel.is_alive():
135 if self.stdin_channel.is_alive():
132 self.stdin_channel.stop()
136 self.stdin_channel.stop()
133 if self.hb_channel.is_alive():
137 if self.hb_channel.is_alive():
134 self.hb_channel.stop()
138 self.hb_channel.stop()
135
139
136 @property
140 @property
137 def channels_running(self):
141 def channels_running(self):
138 """Are any of the channels created and running?"""
142 """Are any of the channels created and running?"""
139 return (self.shell_channel.is_alive() or self.iopub_channel.is_alive() or
143 return (self.shell_channel.is_alive() or self.iopub_channel.is_alive() or
140 self.stdin_channel.is_alive() or self.hb_channel.is_alive())
144 self.stdin_channel.is_alive() or self.hb_channel.is_alive())
141
145
142 @property
146 @property
143 def shell_channel(self):
147 def shell_channel(self):
144 """Get the shell channel object for this kernel."""
148 """Get the shell channel object for this kernel."""
145 if self._shell_channel is None:
149 if self._shell_channel is None:
146 self._shell_channel = self.shell_channel_class(
150 self._shell_channel = self.shell_channel_class(
147 self.context, self.session, self._make_url('shell')
151 self.context, self.session, self._make_url('shell')
148 )
152 )
149 return self._shell_channel
153 return self._shell_channel
150
154
151 @property
155 @property
152 def iopub_channel(self):
156 def iopub_channel(self):
153 """Get the iopub channel object for this kernel."""
157 """Get the iopub channel object for this kernel."""
154 if self._iopub_channel is None:
158 if self._iopub_channel is None:
155 self._iopub_channel = self.iopub_channel_class(
159 self._iopub_channel = self.iopub_channel_class(
156 self.context, self.session, self._make_url('iopub')
160 self.context, self.session, self._make_url('iopub')
157 )
161 )
158 return self._iopub_channel
162 return self._iopub_channel
159
163
160 @property
164 @property
161 def stdin_channel(self):
165 def stdin_channel(self):
162 """Get the stdin channel object for this kernel."""
166 """Get the stdin channel object for this kernel."""
163 if self._stdin_channel is None:
167 if self._stdin_channel is None:
164 self._stdin_channel = self.stdin_channel_class(
168 self._stdin_channel = self.stdin_channel_class(
165 self.context, self.session, self._make_url('stdin')
169 self.context, self.session, self._make_url('stdin')
166 )
170 )
167 return self._stdin_channel
171 return self._stdin_channel
168
172
169 @property
173 @property
170 def hb_channel(self):
174 def hb_channel(self):
171 """Get the hb channel object for this kernel."""
175 """Get the hb channel object for this kernel."""
172 if self._hb_channel is None:
176 if self._hb_channel is None:
173 self._hb_channel = self.hb_channel_class(
177 self._hb_channel = self.hb_channel_class(
174 self.context, self.session, self._make_url('hb')
178 self.context, self.session, self._make_url('hb')
175 )
179 )
176 return self._hb_channel
180 return self._hb_channel
177
181
178 def is_alive(self):
182 def is_alive(self):
179 """Is the kernel process still running?"""
183 """Is the kernel process still running?"""
180 if self._hb_channel is not None:
184 if self._hb_channel is not None:
181 # We didn't start the kernel with this KernelManager so we
185 # We didn't start the kernel with this KernelManager so we
182 # use the heartbeat.
186 # use the heartbeat.
183 return self._hb_channel.is_beating()
187 return self._hb_channel.is_beating()
184 else:
188 else:
185 # no heartbeat and not local, we can't tell if it's running,
189 # no heartbeat and not local, we can't tell if it's running,
186 # so naively return True
190 # so naively return True
187 return True
191 return True
188
192
189
193
190 #-----------------------------------------------------------------------------
194 #-----------------------------------------------------------------------------
191 # ABC Registration
195 # ABC Registration
192 #-----------------------------------------------------------------------------
196 #-----------------------------------------------------------------------------
193
197
194 KernelClientABC.register(KernelClient)
198 KernelClientABC.register(KernelClient)
General Comments 0
You need to be logged in to leave comments. Login now