##// END OF EJS Templates
remove unused imports
Paul Ivanov -
Show More
@@ -1,395 +1,393 b''
1 """ A minimal application base mixin for all ZMQ based IPython frontends.
1 """ A minimal application base mixin for all ZMQ based IPython frontends.
2
2
3 This is not a complete console app, as subprocess will not be able to receive
3 This is not a complete console app, as subprocess will not be able to receive
4 input, there is no real readline support, among other limitations. This is a
4 input, there is no real readline support, among other limitations. This is a
5 refactoring of what used to be the IPython/qt/console/qtconsoleapp.py
5 refactoring of what used to be the IPython/qt/console/qtconsoleapp.py
6
6
7 Authors:
7 Authors:
8
8
9 * Evan Patterson
9 * Evan Patterson
10 * Min RK
10 * Min RK
11 * Erik Tollerud
11 * Erik Tollerud
12 * Fernando Perez
12 * Fernando Perez
13 * Bussonnier Matthias
13 * Bussonnier Matthias
14 * Thomas Kluyver
14 * Thomas Kluyver
15 * Paul Ivanov
15 * Paul Ivanov
16
16
17 """
17 """
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 # stdlib imports
23 # stdlib imports
24 import atexit
24 import atexit
25 import json
25 import json
26 import os
26 import os
27 import shutil
28 import signal
27 import signal
29 import sys
28 import sys
30 import uuid
29 import uuid
31
30
32
31
33 # Local imports
32 # Local imports
34 from IPython.config.application import boolean_flag
33 from IPython.config.application import boolean_flag
35 from IPython.config.configurable import Configurable
36 from IPython.core.profiledir import ProfileDir
34 from IPython.core.profiledir import ProfileDir
37 from IPython.kernel.blocking import BlockingKernelClient
35 from IPython.kernel.blocking import BlockingKernelClient
38 from IPython.kernel import KernelManager
36 from IPython.kernel import KernelManager
39 from IPython.kernel import tunnel_to_kernel, find_connection_file, swallow_argv
37 from IPython.kernel import tunnel_to_kernel, find_connection_file, swallow_argv
40 from IPython.utils.path import filefind
38 from IPython.utils.path import filefind
41 from IPython.utils.py3compat import str_to_bytes
39 from IPython.utils.py3compat import str_to_bytes
42 from IPython.utils.traitlets import (
40 from IPython.utils.traitlets import (
43 Dict, List, Unicode, CUnicode, Int, CBool, Any, CaselessStrEnum
41 Dict, List, Unicode, CUnicode, Int, CBool, Any
44 )
42 )
45 from IPython.kernel.zmq.kernelapp import (
43 from IPython.kernel.zmq.kernelapp import (
46 kernel_flags,
44 kernel_flags,
47 kernel_aliases,
45 kernel_aliases,
48 IPKernelApp
46 IPKernelApp
49 )
47 )
50 from IPython.kernel.zmq.session import Session, default_secure
48 from IPython.kernel.zmq.session import Session, default_secure
51 from IPython.kernel.zmq.zmqshell import ZMQInteractiveShell
49 from IPython.kernel.zmq.zmqshell import ZMQInteractiveShell
52 from IPython.kernel.connect import ConnectionFileMixin
50 from IPython.kernel.connect import ConnectionFileMixin
53
51
54 #-----------------------------------------------------------------------------
52 #-----------------------------------------------------------------------------
55 # Network Constants
53 # Network Constants
56 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
57
55
58 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
56 from IPython.utils.localinterfaces import LOCALHOST
59
57
60 #-----------------------------------------------------------------------------
58 #-----------------------------------------------------------------------------
61 # Globals
59 # Globals
62 #-----------------------------------------------------------------------------
60 #-----------------------------------------------------------------------------
63
61
64
62
65 #-----------------------------------------------------------------------------
63 #-----------------------------------------------------------------------------
66 # Aliases and Flags
64 # Aliases and Flags
67 #-----------------------------------------------------------------------------
65 #-----------------------------------------------------------------------------
68
66
69 flags = dict(kernel_flags)
67 flags = dict(kernel_flags)
70
68
71 # the flags that are specific to the frontend
69 # the flags that are specific to the frontend
72 # these must be scrubbed before being passed to the kernel,
70 # these must be scrubbed before being passed to the kernel,
73 # or it will raise an error on unrecognized flags
71 # or it will raise an error on unrecognized flags
74 app_flags = {
72 app_flags = {
75 'existing' : ({'IPythonConsoleApp' : {'existing' : 'kernel*.json'}},
73 'existing' : ({'IPythonConsoleApp' : {'existing' : 'kernel*.json'}},
76 "Connect to an existing kernel. If no argument specified, guess most recent"),
74 "Connect to an existing kernel. If no argument specified, guess most recent"),
77 }
75 }
78 app_flags.update(boolean_flag(
76 app_flags.update(boolean_flag(
79 'confirm-exit', 'IPythonConsoleApp.confirm_exit',
77 'confirm-exit', 'IPythonConsoleApp.confirm_exit',
80 """Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
78 """Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
81 to force a direct exit without any confirmation.
79 to force a direct exit without any confirmation.
82 """,
80 """,
83 """Don't prompt the user when exiting. This will terminate the kernel
81 """Don't prompt the user when exiting. This will terminate the kernel
84 if it is owned by the frontend, and leave it alive if it is external.
82 if it is owned by the frontend, and leave it alive if it is external.
85 """
83 """
86 ))
84 ))
87 flags.update(app_flags)
85 flags.update(app_flags)
88
86
89 aliases = dict(kernel_aliases)
87 aliases = dict(kernel_aliases)
90
88
91 # also scrub aliases from the frontend
89 # also scrub aliases from the frontend
92 app_aliases = dict(
90 app_aliases = dict(
93 ip = 'IPythonConsoleApp.ip',
91 ip = 'IPythonConsoleApp.ip',
94 transport = 'IPythonConsoleApp.transport',
92 transport = 'IPythonConsoleApp.transport',
95 hb = 'IPythonConsoleApp.hb_port',
93 hb = 'IPythonConsoleApp.hb_port',
96 shell = 'IPythonConsoleApp.shell_port',
94 shell = 'IPythonConsoleApp.shell_port',
97 iopub = 'IPythonConsoleApp.iopub_port',
95 iopub = 'IPythonConsoleApp.iopub_port',
98 stdin = 'IPythonConsoleApp.stdin_port',
96 stdin = 'IPythonConsoleApp.stdin_port',
99 existing = 'IPythonConsoleApp.existing',
97 existing = 'IPythonConsoleApp.existing',
100 f = 'IPythonConsoleApp.connection_file',
98 f = 'IPythonConsoleApp.connection_file',
101
99
102
100
103 ssh = 'IPythonConsoleApp.sshserver',
101 ssh = 'IPythonConsoleApp.sshserver',
104 )
102 )
105 aliases.update(app_aliases)
103 aliases.update(app_aliases)
106
104
107 #-----------------------------------------------------------------------------
105 #-----------------------------------------------------------------------------
108 # Classes
106 # Classes
109 #-----------------------------------------------------------------------------
107 #-----------------------------------------------------------------------------
110
108
111 #-----------------------------------------------------------------------------
109 #-----------------------------------------------------------------------------
112 # IPythonConsole
110 # IPythonConsole
113 #-----------------------------------------------------------------------------
111 #-----------------------------------------------------------------------------
114
112
115 classes = [IPKernelApp, ZMQInteractiveShell, KernelManager, ProfileDir, Session]
113 classes = [IPKernelApp, ZMQInteractiveShell, KernelManager, ProfileDir, Session]
116
114
117 try:
115 try:
118 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
116 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
119 except ImportError:
117 except ImportError:
120 pass
118 pass
121 else:
119 else:
122 classes.append(InlineBackend)
120 classes.append(InlineBackend)
123
121
124 class IPythonConsoleApp(ConnectionFileMixin):
122 class IPythonConsoleApp(ConnectionFileMixin):
125 name = 'ipython-console-mixin'
123 name = 'ipython-console-mixin'
126
124
127 description = """
125 description = """
128 The IPython Mixin Console.
126 The IPython Mixin Console.
129
127
130 This class contains the common portions of console client (QtConsole,
128 This class contains the common portions of console client (QtConsole,
131 ZMQ-based terminal console, etc). It is not a full console, in that
129 ZMQ-based terminal console, etc). It is not a full console, in that
132 launched terminal subprocesses will not be able to accept input.
130 launched terminal subprocesses will not be able to accept input.
133
131
134 The Console using this mixing supports various extra features beyond
132 The Console using this mixing supports various extra features beyond
135 the single-process Terminal IPython shell, such as connecting to
133 the single-process Terminal IPython shell, such as connecting to
136 existing kernel, via:
134 existing kernel, via:
137
135
138 ipython <appname> --existing
136 ipython <appname> --existing
139
137
140 as well as tunnel via SSH
138 as well as tunnel via SSH
141
139
142 """
140 """
143
141
144 classes = classes
142 classes = classes
145 flags = Dict(flags)
143 flags = Dict(flags)
146 aliases = Dict(aliases)
144 aliases = Dict(aliases)
147 kernel_manager_class = KernelManager
145 kernel_manager_class = KernelManager
148 kernel_client_class = BlockingKernelClient
146 kernel_client_class = BlockingKernelClient
149
147
150 kernel_argv = List(Unicode)
148 kernel_argv = List(Unicode)
151 # frontend flags&aliases to be stripped when building kernel_argv
149 # frontend flags&aliases to be stripped when building kernel_argv
152 frontend_flags = Any(app_flags)
150 frontend_flags = Any(app_flags)
153 frontend_aliases = Any(app_aliases)
151 frontend_aliases = Any(app_aliases)
154
152
155 # create requested profiles by default, if they don't exist:
153 # create requested profiles by default, if they don't exist:
156 auto_create = CBool(True)
154 auto_create = CBool(True)
157 # connection info:
155 # connection info:
158
156
159 sshserver = Unicode('', config=True,
157 sshserver = Unicode('', config=True,
160 help="""The SSH server to use to connect to the kernel.""")
158 help="""The SSH server to use to connect to the kernel.""")
161 sshkey = Unicode('', config=True,
159 sshkey = Unicode('', config=True,
162 help="""Path to the ssh key to use for logging in to the ssh server.""")
160 help="""Path to the ssh key to use for logging in to the ssh server.""")
163
161
164 hb_port = Int(0, config=True,
162 hb_port = Int(0, config=True,
165 help="set the heartbeat port [default: random]")
163 help="set the heartbeat port [default: random]")
166 shell_port = Int(0, config=True,
164 shell_port = Int(0, config=True,
167 help="set the shell (ROUTER) port [default: random]")
165 help="set the shell (ROUTER) port [default: random]")
168 iopub_port = Int(0, config=True,
166 iopub_port = Int(0, config=True,
169 help="set the iopub (PUB) port [default: random]")
167 help="set the iopub (PUB) port [default: random]")
170 stdin_port = Int(0, config=True,
168 stdin_port = Int(0, config=True,
171 help="set the stdin (DEALER) port [default: random]")
169 help="set the stdin (DEALER) port [default: random]")
172 connection_file = Unicode('', config=True,
170 connection_file = Unicode('', config=True,
173 help="""JSON file in which to store connection info [default: kernel-<pid>.json]
171 help="""JSON file in which to store connection info [default: kernel-<pid>.json]
174
172
175 This file will contain the IP, ports, and authentication key needed to connect
173 This file will contain the IP, ports, and authentication key needed to connect
176 clients to this kernel. By default, this file will be created in the security-dir
174 clients to this kernel. By default, this file will be created in the security-dir
177 of the current profile, but can be specified by absolute path.
175 of the current profile, but can be specified by absolute path.
178 """)
176 """)
179 def _connection_file_default(self):
177 def _connection_file_default(self):
180 return 'kernel-%i.json' % os.getpid()
178 return 'kernel-%i.json' % os.getpid()
181
179
182 existing = CUnicode('', config=True,
180 existing = CUnicode('', config=True,
183 help="""Connect to an already running kernel""")
181 help="""Connect to an already running kernel""")
184
182
185 confirm_exit = CBool(True, config=True,
183 confirm_exit = CBool(True, config=True,
186 help="""
184 help="""
187 Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
185 Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
188 to force a direct exit without any confirmation.""",
186 to force a direct exit without any confirmation.""",
189 )
187 )
190
188
191
189
192 def build_kernel_argv(self, argv=None):
190 def build_kernel_argv(self, argv=None):
193 """build argv to be passed to kernel subprocess"""
191 """build argv to be passed to kernel subprocess"""
194 if argv is None:
192 if argv is None:
195 argv = sys.argv[1:]
193 argv = sys.argv[1:]
196 self.kernel_argv = swallow_argv(argv, self.frontend_aliases, self.frontend_flags)
194 self.kernel_argv = swallow_argv(argv, self.frontend_aliases, self.frontend_flags)
197 # kernel should inherit default config file from frontend
195 # kernel should inherit default config file from frontend
198 self.kernel_argv.append("--IPKernelApp.parent_appname='%s'" % self.name)
196 self.kernel_argv.append("--IPKernelApp.parent_appname='%s'" % self.name)
199
197
200 def init_connection_file(self):
198 def init_connection_file(self):
201 """find the connection file, and load the info if found.
199 """find the connection file, and load the info if found.
202
200
203 The current working directory and the current profile's security
201 The current working directory and the current profile's security
204 directory will be searched for the file if it is not given by
202 directory will be searched for the file if it is not given by
205 absolute path.
203 absolute path.
206
204
207 When attempting to connect to an existing kernel and the `--existing`
205 When attempting to connect to an existing kernel and the `--existing`
208 argument does not match an existing file, it will be interpreted as a
206 argument does not match an existing file, it will be interpreted as a
209 fileglob, and the matching file in the current profile's security dir
207 fileglob, and the matching file in the current profile's security dir
210 with the latest access time will be used.
208 with the latest access time will be used.
211
209
212 After this method is called, self.connection_file contains the *full path*
210 After this method is called, self.connection_file contains the *full path*
213 to the connection file, never just its name.
211 to the connection file, never just its name.
214 """
212 """
215 if self.existing:
213 if self.existing:
216 try:
214 try:
217 cf = find_connection_file(self.existing)
215 cf = find_connection_file(self.existing)
218 except Exception:
216 except Exception:
219 self.log.critical("Could not find existing kernel connection file %s", self.existing)
217 self.log.critical("Could not find existing kernel connection file %s", self.existing)
220 self.exit(1)
218 self.exit(1)
221 self.log.info("Connecting to existing kernel: %s" % cf)
219 self.log.info("Connecting to existing kernel: %s" % cf)
222 self.connection_file = cf
220 self.connection_file = cf
223 else:
221 else:
224 # not existing, check if we are going to write the file
222 # not existing, check if we are going to write the file
225 # and ensure that self.connection_file is a full path, not just the shortname
223 # and ensure that self.connection_file is a full path, not just the shortname
226 try:
224 try:
227 cf = find_connection_file(self.connection_file)
225 cf = find_connection_file(self.connection_file)
228 except Exception:
226 except Exception:
229 # file might not exist
227 # file might not exist
230 if self.connection_file == os.path.basename(self.connection_file):
228 if self.connection_file == os.path.basename(self.connection_file):
231 # just shortname, put it in security dir
229 # just shortname, put it in security dir
232 cf = os.path.join(self.profile_dir.security_dir, self.connection_file)
230 cf = os.path.join(self.profile_dir.security_dir, self.connection_file)
233 else:
231 else:
234 cf = self.connection_file
232 cf = self.connection_file
235 self.connection_file = cf
233 self.connection_file = cf
236
234
237 # should load_connection_file only be used for existing?
235 # should load_connection_file only be used for existing?
238 # as it is now, this allows reusing ports if an existing
236 # as it is now, this allows reusing ports if an existing
239 # file is requested
237 # file is requested
240 try:
238 try:
241 self.load_connection_file()
239 self.load_connection_file()
242 except Exception:
240 except Exception:
243 self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True)
241 self.log.error("Failed to load connection file: %r", self.connection_file, exc_info=True)
244 self.exit(1)
242 self.exit(1)
245
243
246 def load_connection_file(self):
244 def load_connection_file(self):
247 """load ip/port/hmac config from JSON connection file"""
245 """load ip/port/hmac config from JSON connection file"""
248 # this is identical to IPKernelApp.load_connection_file
246 # this is identical to IPKernelApp.load_connection_file
249 # perhaps it can be centralized somewhere?
247 # perhaps it can be centralized somewhere?
250 try:
248 try:
251 fname = filefind(self.connection_file, ['.', self.profile_dir.security_dir])
249 fname = filefind(self.connection_file, ['.', self.profile_dir.security_dir])
252 except IOError:
250 except IOError:
253 self.log.debug("Connection File not found: %s", self.connection_file)
251 self.log.debug("Connection File not found: %s", self.connection_file)
254 return
252 return
255 self.log.debug(u"Loading connection file %s", fname)
253 self.log.debug(u"Loading connection file %s", fname)
256 with open(fname) as f:
254 with open(fname) as f:
257 cfg = json.load(f)
255 cfg = json.load(f)
258 self.transport = cfg.get('transport', 'tcp')
256 self.transport = cfg.get('transport', 'tcp')
259 self.ip = cfg.get('ip', LOCALHOST)
257 self.ip = cfg.get('ip', LOCALHOST)
260
258
261 for channel in ('hb', 'shell', 'iopub', 'stdin', 'control'):
259 for channel in ('hb', 'shell', 'iopub', 'stdin', 'control'):
262 name = channel + '_port'
260 name = channel + '_port'
263 if getattr(self, name) == 0 and name in cfg:
261 if getattr(self, name) == 0 and name in cfg:
264 # not overridden by config or cl_args
262 # not overridden by config or cl_args
265 setattr(self, name, cfg[name])
263 setattr(self, name, cfg[name])
266 if 'key' in cfg:
264 if 'key' in cfg:
267 self.config.Session.key = str_to_bytes(cfg['key'])
265 self.config.Session.key = str_to_bytes(cfg['key'])
268 if 'signature_scheme' in cfg:
266 if 'signature_scheme' in cfg:
269 self.config.Session.signature_scheme = cfg['signature_scheme']
267 self.config.Session.signature_scheme = cfg['signature_scheme']
270
268
271 def init_ssh(self):
269 def init_ssh(self):
272 """set up ssh tunnels, if needed."""
270 """set up ssh tunnels, if needed."""
273 if not self.existing or (not self.sshserver and not self.sshkey):
271 if not self.existing or (not self.sshserver and not self.sshkey):
274 return
272 return
275 self.load_connection_file()
273 self.load_connection_file()
276
274
277 transport = self.transport
275 transport = self.transport
278 ip = self.ip
276 ip = self.ip
279
277
280 if transport != 'tcp':
278 if transport != 'tcp':
281 self.log.error("Can only use ssh tunnels with TCP sockets, not %s", transport)
279 self.log.error("Can only use ssh tunnels with TCP sockets, not %s", transport)
282 sys.exit(-1)
280 sys.exit(-1)
283
281
284 if self.sshkey and not self.sshserver:
282 if self.sshkey and not self.sshserver:
285 # specifying just the key implies that we are connecting directly
283 # specifying just the key implies that we are connecting directly
286 self.sshserver = ip
284 self.sshserver = ip
287 ip = LOCALHOST
285 ip = LOCALHOST
288
286
289 # build connection dict for tunnels:
287 # build connection dict for tunnels:
290 info = dict(ip=ip,
288 info = dict(ip=ip,
291 shell_port=self.shell_port,
289 shell_port=self.shell_port,
292 iopub_port=self.iopub_port,
290 iopub_port=self.iopub_port,
293 stdin_port=self.stdin_port,
291 stdin_port=self.stdin_port,
294 hb_port=self.hb_port
292 hb_port=self.hb_port
295 )
293 )
296
294
297 self.log.info("Forwarding connections to %s via %s"%(ip, self.sshserver))
295 self.log.info("Forwarding connections to %s via %s"%(ip, self.sshserver))
298
296
299 # tunnels return a new set of ports, which will be on localhost:
297 # tunnels return a new set of ports, which will be on localhost:
300 self.ip = LOCALHOST
298 self.ip = LOCALHOST
301 try:
299 try:
302 newports = tunnel_to_kernel(info, self.sshserver, self.sshkey)
300 newports = tunnel_to_kernel(info, self.sshserver, self.sshkey)
303 except:
301 except:
304 # even catch KeyboardInterrupt
302 # even catch KeyboardInterrupt
305 self.log.error("Could not setup tunnels", exc_info=True)
303 self.log.error("Could not setup tunnels", exc_info=True)
306 self.exit(1)
304 self.exit(1)
307
305
308 self.shell_port, self.iopub_port, self.stdin_port, self.hb_port = newports
306 self.shell_port, self.iopub_port, self.stdin_port, self.hb_port = newports
309
307
310 cf = self.connection_file
308 cf = self.connection_file
311 base,ext = os.path.splitext(cf)
309 base,ext = os.path.splitext(cf)
312 base = os.path.basename(base)
310 base = os.path.basename(base)
313 self.connection_file = os.path.basename(base)+'-ssh'+ext
311 self.connection_file = os.path.basename(base)+'-ssh'+ext
314 self.log.critical("To connect another client via this tunnel, use:")
312 self.log.critical("To connect another client via this tunnel, use:")
315 self.log.critical("--existing %s" % self.connection_file)
313 self.log.critical("--existing %s" % self.connection_file)
316
314
317 def _new_connection_file(self):
315 def _new_connection_file(self):
318 cf = ''
316 cf = ''
319 while not cf:
317 while not cf:
320 # we don't need a 128b id to distinguish kernels, use more readable
318 # we don't need a 128b id to distinguish kernels, use more readable
321 # 48b node segment (12 hex chars). Users running more than 32k simultaneous
319 # 48b node segment (12 hex chars). Users running more than 32k simultaneous
322 # kernels can subclass.
320 # kernels can subclass.
323 ident = str(uuid.uuid4()).split('-')[-1]
321 ident = str(uuid.uuid4()).split('-')[-1]
324 cf = os.path.join(self.profile_dir.security_dir, 'kernel-%s.json' % ident)
322 cf = os.path.join(self.profile_dir.security_dir, 'kernel-%s.json' % ident)
325 # only keep if it's actually new. Protect against unlikely collision
323 # only keep if it's actually new. Protect against unlikely collision
326 # in 48b random search space
324 # in 48b random search space
327 cf = cf if not os.path.exists(cf) else ''
325 cf = cf if not os.path.exists(cf) else ''
328 return cf
326 return cf
329
327
330 def init_kernel_manager(self):
328 def init_kernel_manager(self):
331 # Don't let Qt or ZMQ swallow KeyboardInterupts.
329 # Don't let Qt or ZMQ swallow KeyboardInterupts.
332 if self.existing:
330 if self.existing:
333 self.kernel_manager = None
331 self.kernel_manager = None
334 return
332 return
335 signal.signal(signal.SIGINT, signal.SIG_DFL)
333 signal.signal(signal.SIGINT, signal.SIG_DFL)
336
334
337 # Create a KernelManager and start a kernel.
335 # Create a KernelManager and start a kernel.
338 self.kernel_manager = self.kernel_manager_class(
336 self.kernel_manager = self.kernel_manager_class(
339 ip=self.ip,
337 ip=self.ip,
340 transport=self.transport,
338 transport=self.transport,
341 shell_port=self.shell_port,
339 shell_port=self.shell_port,
342 iopub_port=self.iopub_port,
340 iopub_port=self.iopub_port,
343 stdin_port=self.stdin_port,
341 stdin_port=self.stdin_port,
344 hb_port=self.hb_port,
342 hb_port=self.hb_port,
345 connection_file=self.connection_file,
343 connection_file=self.connection_file,
346 parent=self,
344 parent=self,
347 )
345 )
348 self.kernel_manager.client_factory = self.kernel_client_class
346 self.kernel_manager.client_factory = self.kernel_client_class
349 self.kernel_manager.start_kernel(extra_arguments=self.kernel_argv)
347 self.kernel_manager.start_kernel(extra_arguments=self.kernel_argv)
350 atexit.register(self.kernel_manager.cleanup_ipc_files)
348 atexit.register(self.kernel_manager.cleanup_ipc_files)
351
349
352 if self.sshserver:
350 if self.sshserver:
353 # ssh, write new connection file
351 # ssh, write new connection file
354 self.kernel_manager.write_connection_file()
352 self.kernel_manager.write_connection_file()
355
353
356 # in case KM defaults / ssh writing changes things:
354 # in case KM defaults / ssh writing changes things:
357 km = self.kernel_manager
355 km = self.kernel_manager
358 self.shell_port=km.shell_port
356 self.shell_port=km.shell_port
359 self.iopub_port=km.iopub_port
357 self.iopub_port=km.iopub_port
360 self.stdin_port=km.stdin_port
358 self.stdin_port=km.stdin_port
361 self.hb_port=km.hb_port
359 self.hb_port=km.hb_port
362 self.connection_file = km.connection_file
360 self.connection_file = km.connection_file
363
361
364 atexit.register(self.kernel_manager.cleanup_connection_file)
362 atexit.register(self.kernel_manager.cleanup_connection_file)
365
363
366 def init_kernel_client(self):
364 def init_kernel_client(self):
367 if self.kernel_manager is not None:
365 if self.kernel_manager is not None:
368 self.kernel_client = self.kernel_manager.client()
366 self.kernel_client = self.kernel_manager.client()
369 else:
367 else:
370 self.kernel_client = self.kernel_client_class(
368 self.kernel_client = self.kernel_client_class(
371 ip=self.ip,
369 ip=self.ip,
372 transport=self.transport,
370 transport=self.transport,
373 shell_port=self.shell_port,
371 shell_port=self.shell_port,
374 iopub_port=self.iopub_port,
372 iopub_port=self.iopub_port,
375 stdin_port=self.stdin_port,
373 stdin_port=self.stdin_port,
376 hb_port=self.hb_port,
374 hb_port=self.hb_port,
377 connection_file=self.connection_file,
375 connection_file=self.connection_file,
378 parent=self,
376 parent=self,
379 )
377 )
380
378
381 self.kernel_client.start_channels()
379 self.kernel_client.start_channels()
382
380
383
381
384
382
385 def initialize(self, argv=None):
383 def initialize(self, argv=None):
386 """
384 """
387 Classes which mix this class in should call:
385 Classes which mix this class in should call:
388 IPythonConsoleApp.initialize(self,argv)
386 IPythonConsoleApp.initialize(self,argv)
389 """
387 """
390 self.init_connection_file()
388 self.init_connection_file()
391 default_secure(self.config)
389 default_secure(self.config)
392 self.init_ssh()
390 self.init_ssh()
393 self.init_kernel_manager()
391 self.init_kernel_manager()
394 self.init_kernel_client()
392 self.init_kernel_client()
395
393
General Comments 0
You need to be logged in to leave comments. Login now