Show More
@@ -0,0 +1,315 b'' | |||
|
1 | """Utilities for connecting to kernels | |
|
2 | ||
|
3 | Authors: | |
|
4 | ||
|
5 | * Min Ragan-Kelley | |
|
6 | ||
|
7 | """ | |
|
8 | ||
|
9 | #----------------------------------------------------------------------------- | |
|
10 | # Copyright (C) 2011 The IPython Development Team | |
|
11 | # | |
|
12 | # Distributed under the terms of the BSD License. The full license is in | |
|
13 | # the file COPYING, distributed as part of this software. | |
|
14 | #----------------------------------------------------------------------------- | |
|
15 | ||
|
16 | #----------------------------------------------------------------------------- | |
|
17 | # Imports | |
|
18 | #----------------------------------------------------------------------------- | |
|
19 | ||
|
20 | import glob | |
|
21 | import json | |
|
22 | import os | |
|
23 | import sys | |
|
24 | from getpass import getpass | |
|
25 | from subprocess import Popen, PIPE | |
|
26 | ||
|
27 | # external imports | |
|
28 | from IPython.external.ssh import tunnel | |
|
29 | ||
|
30 | # IPython imports | |
|
31 | from IPython.core.profiledir import ProfileDir | |
|
32 | from IPython.utils.path import filefind, get_ipython_dir | |
|
33 | from IPython.utils.py3compat import str_to_bytes | |
|
34 | ||
|
35 | ||
|
36 | #----------------------------------------------------------------------------- | |
|
37 | # Functions | |
|
38 | #----------------------------------------------------------------------------- | |
|
39 | ||
|
40 | def get_connection_file(app=None): | |
|
41 | """Return the path to the connection file of an app | |
|
42 | ||
|
43 | Parameters | |
|
44 | ---------- | |
|
45 | app : KernelApp instance [optional] | |
|
46 | If unspecified, the currently running app will be used | |
|
47 | """ | |
|
48 | if app is None: | |
|
49 | from IPython.zmq.ipkernel import IPKernelApp | |
|
50 | if not IPKernelApp.initialized(): | |
|
51 | raise RuntimeError("app not specified, and not in a running Kernel") | |
|
52 | ||
|
53 | app = IPKernelApp.instance() | |
|
54 | return filefind(app.connection_file, ['.', app.profile_dir.security_dir]) | |
|
55 | ||
|
56 | def find_connection_file(filename, profile=None): | |
|
57 | """find a connection file, and return its absolute path. | |
|
58 | ||
|
59 | The current working directory and the profile's security | |
|
60 | directory will be searched for the file if it is not given by | |
|
61 | absolute path. | |
|
62 | ||
|
63 | If profile is unspecified, then the current running application's | |
|
64 | profile will be used, or 'default', if not run from IPython. | |
|
65 | ||
|
66 | If the argument does not match an existing file, it will be interpreted as a | |
|
67 | fileglob, and the matching file in the profile's security dir with | |
|
68 | the latest access time will be used. | |
|
69 | ||
|
70 | Parameters | |
|
71 | ---------- | |
|
72 | filename : str | |
|
73 | The connection file or fileglob to search for. | |
|
74 | profile : str [optional] | |
|
75 | The name of the profile to use when searching for the connection file, | |
|
76 | if different from the current IPython session or 'default'. | |
|
77 | ||
|
78 | Returns | |
|
79 | ------- | |
|
80 | str : The absolute path of the connection file. | |
|
81 | """ | |
|
82 | from IPython.core.application import BaseIPythonApplication as IPApp | |
|
83 | try: | |
|
84 | # quick check for absolute path, before going through logic | |
|
85 | return filefind(filename) | |
|
86 | except IOError: | |
|
87 | pass | |
|
88 | ||
|
89 | if profile is None: | |
|
90 | # profile unspecified, check if running from an IPython app | |
|
91 | if IPApp.initialized(): | |
|
92 | app = IPApp.instance() | |
|
93 | profile_dir = app.profile_dir | |
|
94 | else: | |
|
95 | # not running in IPython, use default profile | |
|
96 | profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), 'default') | |
|
97 | else: | |
|
98 | # find profiledir by profile name: | |
|
99 | profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile) | |
|
100 | security_dir = profile_dir.security_dir | |
|
101 | ||
|
102 | try: | |
|
103 | # first, try explicit name | |
|
104 | return filefind(filename, ['.', security_dir]) | |
|
105 | except IOError: | |
|
106 | pass | |
|
107 | ||
|
108 | # not found by full name | |
|
109 | ||
|
110 | if '*' in filename: | |
|
111 | # given as a glob already | |
|
112 | pat = filename | |
|
113 | else: | |
|
114 | # accept any substring match | |
|
115 | pat = '*%s*' % filename | |
|
116 | matches = glob.glob( os.path.join(security_dir, pat) ) | |
|
117 | if not matches: | |
|
118 | raise IOError("Could not find %r in %r" % (filename, security_dir)) | |
|
119 | elif len(matches) == 1: | |
|
120 | return matches[0] | |
|
121 | else: | |
|
122 | # get most recent match, by access time: | |
|
123 | return sorted(matches, key=lambda f: os.stat(f).st_atime)[-1] | |
|
124 | ||
|
125 | def get_connection_info(connection_file=None, unpack=False, profile=None): | |
|
126 | """Return the connection information for the current Kernel. | |
|
127 | ||
|
128 | Parameters | |
|
129 | ---------- | |
|
130 | connection_file : str [optional] | |
|
131 | The connection file to be used. Can be given by absolute path, or | |
|
132 | IPython will search in the security directory of a given profile. | |
|
133 | If run from IPython, | |
|
134 | ||
|
135 | If unspecified, the connection file for the currently running | |
|
136 | IPython Kernel will be used, which is only allowed from inside a kernel. | |
|
137 | unpack : bool [default: False] | |
|
138 | if True, return the unpacked dict, otherwise just the string contents | |
|
139 | of the file. | |
|
140 | profile : str [optional] | |
|
141 | The name of the profile to use when searching for the connection file, | |
|
142 | if different from the current IPython session or 'default'. | |
|
143 | ||
|
144 | ||
|
145 | Returns | |
|
146 | ------- | |
|
147 | The connection dictionary of the current kernel, as string or dict, | |
|
148 | depending on `unpack`. | |
|
149 | """ | |
|
150 | if connection_file is None: | |
|
151 | # get connection file from current kernel | |
|
152 | cf = get_connection_file() | |
|
153 | else: | |
|
154 | # connection file specified, allow shortnames: | |
|
155 | cf = find_connection_file(connection_file, profile=profile) | |
|
156 | ||
|
157 | with open(cf) as f: | |
|
158 | info = f.read() | |
|
159 | ||
|
160 | if unpack: | |
|
161 | info = json.loads(info) | |
|
162 | # ensure key is bytes: | |
|
163 | info['key'] = str_to_bytes(info.get('key', '')) | |
|
164 | return info | |
|
165 | ||
|
166 | def connect_qtconsole(connection_file=None, argv=None, profile=None): | |
|
167 | """Connect a qtconsole to the current kernel. | |
|
168 | ||
|
169 | This is useful for connecting a second qtconsole to a kernel, or to a | |
|
170 | local notebook. | |
|
171 | ||
|
172 | Parameters | |
|
173 | ---------- | |
|
174 | connection_file : str [optional] | |
|
175 | The connection file to be used. Can be given by absolute path, or | |
|
176 | IPython will search in the security directory of a given profile. | |
|
177 | If run from IPython, | |
|
178 | ||
|
179 | If unspecified, the connection file for the currently running | |
|
180 | IPython Kernel will be used, which is only allowed from inside a kernel. | |
|
181 | argv : list [optional] | |
|
182 | Any extra args to be passed to the console. | |
|
183 | profile : str [optional] | |
|
184 | The name of the profile to use when searching for the connection file, | |
|
185 | if different from the current IPython session or 'default'. | |
|
186 | ||
|
187 | ||
|
188 | Returns | |
|
189 | ------- | |
|
190 | subprocess.Popen instance running the qtconsole frontend | |
|
191 | """ | |
|
192 | argv = [] if argv is None else argv | |
|
193 | ||
|
194 | if connection_file is None: | |
|
195 | # get connection file from current kernel | |
|
196 | cf = get_connection_file() | |
|
197 | else: | |
|
198 | cf = find_connection_file(connection_file, profile=profile) | |
|
199 | ||
|
200 | cmd = ';'.join([ | |
|
201 | "from IPython.frontend.qt.console import qtconsoleapp", | |
|
202 | "qtconsoleapp.main()" | |
|
203 | ]) | |
|
204 | ||
|
205 | return Popen([sys.executable, '-c', cmd, '--existing', cf] + argv, stdout=PIPE, stderr=PIPE) | |
|
206 | ||
|
207 | def tunnel_to_kernel(connection_info, sshserver, sshkey=None): | |
|
208 | """tunnel connections to a kernel via ssh | |
|
209 | ||
|
210 | This will open four SSH tunnels from localhost on this machine to the | |
|
211 | ports associated with the kernel. They can be either direct | |
|
212 | localhost-localhost tunnels, or if an intermediate server is necessary, | |
|
213 | the kernel must be listening on a public IP. | |
|
214 | ||
|
215 | Parameters | |
|
216 | ---------- | |
|
217 | connection_info : dict or str (path) | |
|
218 | Either a connection dict, or the path to a JSON connection file | |
|
219 | sshserver : str | |
|
220 | The ssh sever to use to tunnel to the kernel. Can be a full | |
|
221 | `user@server:port` string. ssh config aliases are respected. | |
|
222 | sshkey : str [optional] | |
|
223 | Path to file containing ssh key to use for authentication. | |
|
224 | Only necessary if your ssh config does not already associate | |
|
225 | a keyfile with the host. | |
|
226 | ||
|
227 | Returns | |
|
228 | ------- | |
|
229 | ||
|
230 | (shell, iopub, stdin, hb) : ints | |
|
231 | The four ports on localhost that have been forwarded to the kernel. | |
|
232 | """ | |
|
233 | if isinstance(connection_info, basestring): | |
|
234 | # it's a path, unpack it | |
|
235 | with open(connection_info) as f: | |
|
236 | connection_info = json.loads(f.read()) | |
|
237 | ||
|
238 | cf = connection_info | |
|
239 | ||
|
240 | lports = tunnel.select_random_ports(4) | |
|
241 | rports = cf['shell_port'], cf['iopub_port'], cf['stdin_port'], cf['hb_port'] | |
|
242 | ||
|
243 | remote_ip = cf['ip'] | |
|
244 | ||
|
245 | if tunnel.try_passwordless_ssh(sshserver, sshkey): | |
|
246 | password=False | |
|
247 | else: | |
|
248 | password = getpass("SSH Password for %s: "%sshserver) | |
|
249 | ||
|
250 | for lp,rp in zip(lports, rports): | |
|
251 | tunnel.ssh_tunnel(lp, rp, sshserver, remote_ip, sshkey, password) | |
|
252 | ||
|
253 | return tuple(lports) | |
|
254 | ||
|
255 | ||
|
256 | def swallow_argv(argv, aliases=None, flags=None): | |
|
257 | """strip frontend-specific aliases and flags from an argument list | |
|
258 | ||
|
259 | For use primarily in frontend apps that want to pass a subset of command-line | |
|
260 | arguments through to a subprocess, where frontend-specific flags and aliases | |
|
261 | should be removed from the list. | |
|
262 | ||
|
263 | Parameters | |
|
264 | ---------- | |
|
265 | ||
|
266 | argv : list(str) | |
|
267 | The starting argv, to be filtered | |
|
268 | aliases : container of aliases (dict, list, set, etc.) | |
|
269 | The frontend-specific aliases to be removed | |
|
270 | flags : container of flags (dict, list, set, etc.) | |
|
271 | The frontend-specific flags to be removed | |
|
272 | ||
|
273 | Returns | |
|
274 | ------- | |
|
275 | ||
|
276 | argv : list(str) | |
|
277 | The argv list, excluding flags and aliases that have been stripped | |
|
278 | """ | |
|
279 | ||
|
280 | if aliases is None: | |
|
281 | aliases = set() | |
|
282 | if flags is None: | |
|
283 | flags = set() | |
|
284 | ||
|
285 | stripped = list(argv) # copy | |
|
286 | ||
|
287 | swallow_next = False | |
|
288 | was_flag = False | |
|
289 | for a in argv: | |
|
290 | if swallow_next: | |
|
291 | swallow_next = False | |
|
292 | # last arg was an alias, remove the next one | |
|
293 | # *unless* the last alias has a no-arg flag version, in which | |
|
294 | # case, don't swallow the next arg if it's also a flag: | |
|
295 | if not (was_flag and a.startswith('-')): | |
|
296 | stripped.remove(a) | |
|
297 | continue | |
|
298 | if a.startswith('-'): | |
|
299 | split = a.lstrip('-').split('=') | |
|
300 | alias = split[0] | |
|
301 | if alias in aliases: | |
|
302 | stripped.remove(a) | |
|
303 | if len(split) == 1: | |
|
304 | # alias passed with arg via space | |
|
305 | swallow_next = True | |
|
306 | # could have been a flag that matches an alias, e.g. `existing` | |
|
307 | # in which case, we might not swallow the next arg | |
|
308 | was_flag = alias in flags | |
|
309 | elif alias in flags and len(split) == 1: | |
|
310 | # strip flag, but don't swallow next, as flags don't take args | |
|
311 | stripped.remove(a) | |
|
312 | ||
|
313 | # return shortened list | |
|
314 | return stripped | |
|
315 |
@@ -34,9 +34,9 b' import uuid' | |||
|
34 | 34 | from IPython.config.application import boolean_flag |
|
35 | 35 | from IPython.config.configurable import Configurable |
|
36 | 36 | from IPython.core.profiledir import ProfileDir |
|
37 | from IPython.lib.kernel import tunnel_to_kernel, find_connection_file, swallow_argv | |
|
38 | 37 | from IPython.zmq.blockingkernelmanager import BlockingKernelManager |
|
39 | 38 | from IPython.zmq.kernelmanager import KernelManager |
|
39 | from IPython.utils.kernel import tunnel_to_kernel, find_connection_file, swallow_argv | |
|
40 | 40 | from IPython.utils.path import filefind |
|
41 | 41 | from IPython.utils.py3compat import str_to_bytes |
|
42 | 42 | from IPython.utils.traitlets import ( |
@@ -61,7 +61,6 b' from IPython.config.application import catch_config_error, boolean_flag' | |||
|
61 | 61 | from IPython.core.application import BaseIPythonApplication |
|
62 | 62 | from IPython.core.profiledir import ProfileDir |
|
63 | 63 | from IPython.frontend.consoleapp import IPythonConsoleApp |
|
64 | from IPython.lib.kernel import swallow_argv | |
|
65 | 64 | from IPython.zmq.session import Session, default_secure |
|
66 | 65 | from IPython.zmq.zmqshell import ZMQInteractiveShell |
|
67 | 66 | from IPython.zmq.ipkernel import ( |
@@ -71,6 +70,7 b' from IPython.zmq.ipkernel import (' | |||
|
71 | 70 | ) |
|
72 | 71 | from IPython.utils.importstring import import_item |
|
73 | 72 | from IPython.utils.localinterfaces import LOCALHOST |
|
73 | from IPython.utils.kernel import swallow_argv | |
|
74 | 74 | from IPython.utils.traitlets import ( |
|
75 | 75 | Dict, Unicode, Integer, List, Enum, Bool, |
|
76 | 76 | DottedObjectName |
@@ -59,13 +59,13 b' from IPython.external.qt import QtCore, QtGui' | |||
|
59 | 59 | from IPython.config.application import boolean_flag, catch_config_error |
|
60 | 60 | from IPython.core.application import BaseIPythonApplication |
|
61 | 61 | from IPython.core.profiledir import ProfileDir |
|
62 | from IPython.lib.kernel import tunnel_to_kernel, find_connection_file | |
|
63 | 62 | from IPython.frontend.qt.console.frontend_widget import FrontendWidget |
|
64 | 63 | from IPython.frontend.qt.console.ipython_widget import IPythonWidget |
|
65 | 64 | from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget |
|
66 | 65 | from IPython.frontend.qt.console import styles |
|
67 | 66 | from IPython.frontend.qt.console.mainwindow import MainWindow |
|
68 | 67 | from IPython.frontend.qt.kernelmanager import QtKernelManager |
|
68 | from IPython.utils.kernel import tunnel_to_kernel, find_connection_file | |
|
69 | 69 | from IPython.utils.path import filefind |
|
70 | 70 | from IPython.utils.py3compat import str_to_bytes |
|
71 | 71 | from IPython.utils.traitlets import ( |
@@ -1,315 +1,12 b'' | |||
|
1 | """Utilities for connecting to kernels | |
|
2 | ||
|
3 | Authors: | |
|
4 | ||
|
5 | * Min Ragan-Kelley | |
|
1 | """[DEPRECATED] Utilities for connecting to kernels | |
|
6 | 2 | |
|
3 | Moved to IPython.utils.kernel, where it always belonged. | |
|
7 | 4 | """ |
|
8 | 5 | |
|
9 | #----------------------------------------------------------------------------- | |
|
10 | # Copyright (C) 2011 The IPython Development Team | |
|
11 | # | |
|
12 | # Distributed under the terms of the BSD License. The full license is in | |
|
13 | # the file COPYING, distributed as part of this software. | |
|
14 | #----------------------------------------------------------------------------- | |
|
15 | ||
|
16 | #----------------------------------------------------------------------------- | |
|
17 | # Imports | |
|
18 | #----------------------------------------------------------------------------- | |
|
19 | ||
|
20 | import glob | |
|
21 | import json | |
|
22 | import os | |
|
23 | import sys | |
|
24 | from getpass import getpass | |
|
25 | from subprocess import Popen, PIPE | |
|
26 | ||
|
27 | # external imports | |
|
28 | from IPython.external.ssh import tunnel | |
|
29 | ||
|
30 | # IPython imports | |
|
31 | from IPython.core.profiledir import ProfileDir | |
|
32 | from IPython.utils.path import filefind, get_ipython_dir | |
|
33 | from IPython.utils.py3compat import str_to_bytes | |
|
34 | ||
|
35 | ||
|
36 | #----------------------------------------------------------------------------- | |
|
37 | # Functions | |
|
38 | #----------------------------------------------------------------------------- | |
|
39 | ||
|
40 | def get_connection_file(app=None): | |
|
41 | """Return the path to the connection file of an app | |
|
42 | ||
|
43 | Parameters | |
|
44 | ---------- | |
|
45 | app : KernelApp instance [optional] | |
|
46 | If unspecified, the currently running app will be used | |
|
47 | """ | |
|
48 | if app is None: | |
|
49 | from IPython.zmq.ipkernel import IPKernelApp | |
|
50 | if not IPKernelApp.initialized(): | |
|
51 | raise RuntimeError("app not specified, and not in a running Kernel") | |
|
52 | ||
|
53 | app = IPKernelApp.instance() | |
|
54 | return filefind(app.connection_file, ['.', app.profile_dir.security_dir]) | |
|
55 | ||
|
56 | def find_connection_file(filename, profile=None): | |
|
57 | """find a connection file, and return its absolute path. | |
|
58 | ||
|
59 | The current working directory and the profile's security | |
|
60 | directory will be searched for the file if it is not given by | |
|
61 | absolute path. | |
|
62 | ||
|
63 | If profile is unspecified, then the current running application's | |
|
64 | profile will be used, or 'default', if not run from IPython. | |
|
65 | ||
|
66 | If the argument does not match an existing file, it will be interpreted as a | |
|
67 | fileglob, and the matching file in the profile's security dir with | |
|
68 | the latest access time will be used. | |
|
69 | ||
|
70 | Parameters | |
|
71 | ---------- | |
|
72 | filename : str | |
|
73 | The connection file or fileglob to search for. | |
|
74 | profile : str [optional] | |
|
75 | The name of the profile to use when searching for the connection file, | |
|
76 | if different from the current IPython session or 'default'. | |
|
77 | ||
|
78 | Returns | |
|
79 | ------- | |
|
80 | str : The absolute path of the connection file. | |
|
81 | """ | |
|
82 | from IPython.core.application import BaseIPythonApplication as IPApp | |
|
83 | try: | |
|
84 | # quick check for absolute path, before going through logic | |
|
85 | return filefind(filename) | |
|
86 | except IOError: | |
|
87 | pass | |
|
88 | ||
|
89 | if profile is None: | |
|
90 | # profile unspecified, check if running from an IPython app | |
|
91 | if IPApp.initialized(): | |
|
92 | app = IPApp.instance() | |
|
93 | profile_dir = app.profile_dir | |
|
94 | else: | |
|
95 | # not running in IPython, use default profile | |
|
96 | profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), 'default') | |
|
97 | else: | |
|
98 | # find profiledir by profile name: | |
|
99 | profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile) | |
|
100 | security_dir = profile_dir.security_dir | |
|
101 | ||
|
102 | try: | |
|
103 | # first, try explicit name | |
|
104 | return filefind(filename, ['.', security_dir]) | |
|
105 | except IOError: | |
|
106 | pass | |
|
107 | ||
|
108 | # not found by full name | |
|
109 | ||
|
110 | if '*' in filename: | |
|
111 | # given as a glob already | |
|
112 | pat = filename | |
|
113 | else: | |
|
114 | # accept any substring match | |
|
115 | pat = '*%s*' % filename | |
|
116 | matches = glob.glob( os.path.join(security_dir, pat) ) | |
|
117 | if not matches: | |
|
118 | raise IOError("Could not find %r in %r" % (filename, security_dir)) | |
|
119 | elif len(matches) == 1: | |
|
120 | return matches[0] | |
|
121 | else: | |
|
122 | # get most recent match, by access time: | |
|
123 | return sorted(matches, key=lambda f: os.stat(f).st_atime)[-1] | |
|
124 | ||
|
125 | def get_connection_info(connection_file=None, unpack=False, profile=None): | |
|
126 | """Return the connection information for the current Kernel. | |
|
127 | ||
|
128 | Parameters | |
|
129 | ---------- | |
|
130 | connection_file : str [optional] | |
|
131 | The connection file to be used. Can be given by absolute path, or | |
|
132 | IPython will search in the security directory of a given profile. | |
|
133 | If run from IPython, | |
|
134 | ||
|
135 | If unspecified, the connection file for the currently running | |
|
136 | IPython Kernel will be used, which is only allowed from inside a kernel. | |
|
137 | unpack : bool [default: False] | |
|
138 | if True, return the unpacked dict, otherwise just the string contents | |
|
139 | of the file. | |
|
140 | profile : str [optional] | |
|
141 | The name of the profile to use when searching for the connection file, | |
|
142 | if different from the current IPython session or 'default'. | |
|
143 | ||
|
144 | ||
|
145 | Returns | |
|
146 | ------- | |
|
147 | The connection dictionary of the current kernel, as string or dict, | |
|
148 | depending on `unpack`. | |
|
149 | """ | |
|
150 | if connection_file is None: | |
|
151 | # get connection file from current kernel | |
|
152 | cf = get_connection_file() | |
|
153 | else: | |
|
154 | # connection file specified, allow shortnames: | |
|
155 | cf = find_connection_file(connection_file, profile=profile) | |
|
156 | ||
|
157 | with open(cf) as f: | |
|
158 | info = f.read() | |
|
159 | ||
|
160 | if unpack: | |
|
161 | info = json.loads(info) | |
|
162 | # ensure key is bytes: | |
|
163 | info['key'] = str_to_bytes(info.get('key', '')) | |
|
164 | return info | |
|
165 | ||
|
166 | def connect_qtconsole(connection_file=None, argv=None, profile=None): | |
|
167 | """Connect a qtconsole to the current kernel. | |
|
168 | ||
|
169 | This is useful for connecting a second qtconsole to a kernel, or to a | |
|
170 | local notebook. | |
|
171 | ||
|
172 | Parameters | |
|
173 | ---------- | |
|
174 | connection_file : str [optional] | |
|
175 | The connection file to be used. Can be given by absolute path, or | |
|
176 | IPython will search in the security directory of a given profile. | |
|
177 | If run from IPython, | |
|
178 | ||
|
179 | If unspecified, the connection file for the currently running | |
|
180 | IPython Kernel will be used, which is only allowed from inside a kernel. | |
|
181 | argv : list [optional] | |
|
182 | Any extra args to be passed to the console. | |
|
183 | profile : str [optional] | |
|
184 | The name of the profile to use when searching for the connection file, | |
|
185 | if different from the current IPython session or 'default'. | |
|
186 | ||
|
187 | ||
|
188 | Returns | |
|
189 | ------- | |
|
190 | subprocess.Popen instance running the qtconsole frontend | |
|
191 | """ | |
|
192 | argv = [] if argv is None else argv | |
|
193 | ||
|
194 | if connection_file is None: | |
|
195 | # get connection file from current kernel | |
|
196 | cf = get_connection_file() | |
|
197 | else: | |
|
198 | cf = find_connection_file(connection_file, profile=profile) | |
|
199 | ||
|
200 | cmd = ';'.join([ | |
|
201 | "from IPython.frontend.qt.console import qtconsoleapp", | |
|
202 | "qtconsoleapp.main()" | |
|
203 | ]) | |
|
204 | ||
|
205 | return Popen([sys.executable, '-c', cmd, '--existing', cf] + argv, stdout=PIPE, stderr=PIPE) | |
|
206 | ||
|
207 | def tunnel_to_kernel(connection_info, sshserver, sshkey=None): | |
|
208 | """tunnel connections to a kernel via ssh | |
|
209 | ||
|
210 | This will open four SSH tunnels from localhost on this machine to the | |
|
211 | ports associated with the kernel. They can be either direct | |
|
212 | localhost-localhost tunnels, or if an intermediate server is necessary, | |
|
213 | the kernel must be listening on a public IP. | |
|
214 | ||
|
215 | Parameters | |
|
216 | ---------- | |
|
217 | connection_info : dict or str (path) | |
|
218 | Either a connection dict, or the path to a JSON connection file | |
|
219 | sshserver : str | |
|
220 | The ssh sever to use to tunnel to the kernel. Can be a full | |
|
221 | `user@server:port` string. ssh config aliases are respected. | |
|
222 | sshkey : str [optional] | |
|
223 | Path to file containing ssh key to use for authentication. | |
|
224 | Only necessary if your ssh config does not already associate | |
|
225 | a keyfile with the host. | |
|
226 | ||
|
227 | Returns | |
|
228 | ------- | |
|
229 | ||
|
230 | (shell, iopub, stdin, hb) : ints | |
|
231 | The four ports on localhost that have been forwarded to the kernel. | |
|
232 | """ | |
|
233 | if isinstance(connection_info, basestring): | |
|
234 | # it's a path, unpack it | |
|
235 | with open(connection_info) as f: | |
|
236 | connection_info = json.loads(f.read()) | |
|
237 | ||
|
238 | cf = connection_info | |
|
239 | ||
|
240 | lports = tunnel.select_random_ports(4) | |
|
241 | rports = cf['shell_port'], cf['iopub_port'], cf['stdin_port'], cf['hb_port'] | |
|
242 | ||
|
243 | remote_ip = cf['ip'] | |
|
244 | ||
|
245 | if tunnel.try_passwordless_ssh(sshserver, sshkey): | |
|
246 | password=False | |
|
247 | else: | |
|
248 | password = getpass("SSH Password for %s: "%sshserver) | |
|
249 | ||
|
250 | for lp,rp in zip(lports, rports): | |
|
251 | tunnel.ssh_tunnel(lp, rp, sshserver, remote_ip, sshkey, password) | |
|
252 | ||
|
253 | return tuple(lports) | |
|
254 | ||
|
6 | import warnings | |
|
7 | warnings.warn("IPython.lib.kernel moved to IPython.utils.kernel in IPython 0.14", | |
|
8 | DeprecationWarning | |
|
9 | ) | |
|
255 | 10 | |
|
256 | def swallow_argv(argv, aliases=None, flags=None): | |
|
257 | """strip frontend-specific aliases and flags from an argument list | |
|
258 | ||
|
259 | For use primarily in frontend apps that want to pass a subset of command-line | |
|
260 | arguments through to a subprocess, where frontend-specific flags and aliases | |
|
261 | should be removed from the list. | |
|
262 | ||
|
263 | Parameters | |
|
264 | ---------- | |
|
265 | ||
|
266 | argv : list(str) | |
|
267 | The starting argv, to be filtered | |
|
268 | aliases : container of aliases (dict, list, set, etc.) | |
|
269 | The frontend-specific aliases to be removed | |
|
270 | flags : container of flags (dict, list, set, etc.) | |
|
271 | The frontend-specific flags to be removed | |
|
272 | ||
|
273 | Returns | |
|
274 | ------- | |
|
275 | ||
|
276 | argv : list(str) | |
|
277 | The argv list, excluding flags and aliases that have been stripped | |
|
278 | """ | |
|
279 | ||
|
280 | if aliases is None: | |
|
281 | aliases = set() | |
|
282 | if flags is None: | |
|
283 | flags = set() | |
|
284 | ||
|
285 | stripped = list(argv) # copy | |
|
286 | ||
|
287 | swallow_next = False | |
|
288 | was_flag = False | |
|
289 | for a in argv: | |
|
290 | if swallow_next: | |
|
291 | swallow_next = False | |
|
292 | # last arg was an alias, remove the next one | |
|
293 | # *unless* the last alias has a no-arg flag version, in which | |
|
294 | # case, don't swallow the next arg if it's also a flag: | |
|
295 | if not (was_flag and a.startswith('-')): | |
|
296 | stripped.remove(a) | |
|
297 | continue | |
|
298 | if a.startswith('-'): | |
|
299 | split = a.lstrip('-').split('=') | |
|
300 | alias = split[0] | |
|
301 | if alias in aliases: | |
|
302 | stripped.remove(a) | |
|
303 | if len(split) == 1: | |
|
304 | # alias passed with arg via space | |
|
305 | swallow_next = True | |
|
306 | # could have been a flag that matches an alias, e.g. `existing` | |
|
307 | # in which case, we might not swallow the next arg | |
|
308 | was_flag = alias in flags | |
|
309 | elif alias in flags and len(split) == 1: | |
|
310 | # strip flag, but don't swallow next, as flags don't take args | |
|
311 | stripped.remove(a) | |
|
312 | ||
|
313 | # return shortened list | |
|
314 | return stripped | |
|
11 | from IPython.utils.kernel import * | |
|
315 | 12 |
@@ -24,7 +24,7 b' import nose.tools as nt' | |||
|
24 | 24 | |
|
25 | 25 | # Our own imports |
|
26 | 26 | from IPython.testing import decorators as dec |
|
27 |
from IPython. |
|
|
27 | from IPython.utils import kernel | |
|
28 | 28 | |
|
29 | 29 | #----------------------------------------------------------------------------- |
|
30 | 30 | # Classes and functions |
@@ -35,7 +35,7 b' from IPython.core.magics import MacroToEdit, CodeMagics' | |||
|
35 | 35 | from IPython.core.magic import magics_class, line_magic, Magics |
|
36 | 36 | from IPython.core.payloadpage import install_payload_page |
|
37 | 37 | from IPython.inprocess.socket import SocketABC |
|
38 |
from IPython. |
|
|
38 | from IPython.utils.kernel import ( | |
|
39 | 39 | get_connection_file, get_connection_info, connect_qtconsole |
|
40 | 40 | ) |
|
41 | 41 | from IPython.testing.skipdoctest import skip_doctest |
General Comments 0
You need to be logged in to leave comments.
Login now