##// END OF EJS Templates
zmqterminal now uses the zmq mixin app
Paul Ivanov -
Show More
@@ -63,13 +63,13 b' from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS'
63 63 #-----------------------------------------------------------------------------
64 64
65 65 flags = dict(ipkernel_flags)
66
67 # the flags that are specific to the frontend
68 # these must be scrubbed before being passed to the kernel,
69 # or it will raise an error on unrecognized flags
66 70 app_flags = {
67 71 'existing' : ({'IPythonMixinConsoleApp' : {'existing' : 'kernel*.json'}},
68 72 "Connect to an existing kernel. If no argument specified, guess most recent"),
69 'pure' : ({'IPythonMixinConsoleApp' : {'pure' : True}},
70 "Use a pure Python kernel instead of an IPython kernel."),
71 'plain' : ({'ConsoleWidget' : {'kind' : 'plain'}},
72 "Disable rich text support."),
73 73 }
74 74 app_flags.update(boolean_flag(
75 75 'confirm-exit', 'IPythonMixinConsoleApp.confirm_exit',
@@ -84,6 +84,7 b' flags.update(app_flags)'
84 84
85 85 aliases = dict(ipkernel_aliases)
86 86
87 # also scrub aliases from the frontend
87 88 app_aliases = dict(
88 89 hb = 'IPythonMixinConsoleApp.hb_port',
89 90 shell = 'IPythonMixinConsoleApp.shell_port',
@@ -135,6 +136,8 b' class IPythonMixinConsoleApp(Configurable):'
135 136
136 137 kernel_argv = List(Unicode)
137 138
139 pure = CBool(False, config=True,
140 help="Use a pure Python kernel instead of an IPython kernel.")
138 141 # create requested profiles by default, if they don't exist:
139 142 auto_create = CBool(True)
140 143 # connection info:
@@ -176,13 +179,16 b' class IPythonMixinConsoleApp(Configurable):'
176 179 Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
177 180 to force a direct exit without any confirmation.""",
178 181 )
179
182
180 183
181 184 def parse_command_line(self, argv=None):
182 super(PythonBaseConsoleApp, self).parse_command_line(argv)
185 #super(PythonBaseConsoleApp, self).parse_command_line(argv)
183 186 # make this stuff after this a function, in case the super stuff goes
184 187 # away. Also, Min notes that this functionality should be moved to a
185 188 # generic library of kernel stuff
189 self.swallow_args(app_aliases,app_flags,argv=argv)
190
191 def swallow_args(self, aliases,flags, argv=None):
186 192 if argv is None:
187 193 argv = sys.argv[1:]
188 194 self.kernel_argv = list(argv) # copy
@@ -205,15 +211,15 b' class IPythonMixinConsoleApp(Configurable):'
205 211 if a.startswith('-'):
206 212 split = a.lstrip('-').split('=')
207 213 alias = split[0]
208 if alias in qt_aliases:
214 if alias in aliases:
209 215 self.kernel_argv.remove(a)
210 216 if len(split) == 1:
211 217 # alias passed with arg via space
212 218 swallow_next = True
213 219 # could have been a flag that matches an alias, e.g. `existing`
214 220 # in which case, we might not swallow the next arg
215 was_flag = alias in qt_flags
216 elif alias in qt_flags:
221 was_flag = alias in flags
222 elif alias in flags:
217 223 # strip flag, but don't swallow next, as flags don't take args
218 224 self.kernel_argv.remove(a)
219 225
@@ -347,20 +353,12 b' class IPythonMixinConsoleApp(Configurable):'
347 353
348 354
349 355 def initialize(self, argv=None):
350 super(IPythonMixinConsoleApp, self).initialize(argv)
356 """
357 Classes which mix this class in should call:
358 IPythonMixinConsoleApp.initialize(self,argv)
359 """
351 360 self.init_connection_file()
352 361 default_secure(self.config)
353 362 self.init_ssh()
354 363 self.init_kernel_manager()
355 self.init_colors()
356
357 #-----------------------------------------------------------------------------
358 # Main entry point
359 #-----------------------------------------------------------------------------
360
361 def main():
362 raise NotImplementedError
363
364 364
365 if __name__ == '__main__':
366 main()
@@ -48,6 +48,7 b' from IPython.utils.traitlets import ('
48 48 from IPython.zmq.ipkernel import IPKernelApp
49 49 from IPython.zmq.session import Session, default_secure
50 50 from IPython.zmq.zmqshell import ZMQInteractiveShell
51
51 52 from IPython.frontend.kernelmixinapp import (
52 53 IPythonMixinConsoleApp, app_aliases, app_flags
53 54 )
@@ -71,10 +72,9 b' ipython qtconsole --pylab=inline # start with pylab in inline plotting mode'
71 72 # Aliases and Flags
72 73 #-----------------------------------------------------------------------------
73 74
75 # XXX: the app_flags should really be flags from the mixin
74 76 flags = dict(app_flags)
75 77 qt_flags = {
76 #'existing' : ({'IPythonQtConsoleApp' : {'existing' : 'kernel*.json'}},
77 # "Connect to an existing kernel. If no argument specified, guess most recent"),
78 78 'pure' : ({'IPythonQtConsoleApp' : {'pure' : True}},
79 79 "Use a pure Python kernel instead of an IPython kernel."),
80 80 'plain' : ({'ConsoleWidget' : {'kind' : 'plain'}},
@@ -90,8 +90,6 b' flags.update(qt_flags)'
90 90 aliases = dict(app_aliases)
91 91
92 92 qt_aliases = dict(
93 existing = 'IPythonQtConsoleApp.existing',
94 f = 'IPythonQtConsoleApp.connection_file',
95 93
96 94 style = 'IPythonWidget.syntax_style',
97 95 stylesheet = 'IPythonQtConsoleApp.stylesheet',
@@ -113,7 +111,6 b' aliases.update(qt_aliases)'
113 111
114 112 class IPythonQtConsoleApp(BaseIPythonApplication, IPythonMixinConsoleApp):
115 113 name = 'ipython-qtconsole'
116 default_config_file_name='ipython_config.py'
117 114
118 115 description = """
119 116 The IPython QtConsole.
@@ -140,8 +137,6 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonMixinConsoleApp):'
140 137 stylesheet = Unicode('', config=True,
141 138 help="path to a custom CSS stylesheet")
142 139
143 pure = CBool(False, config=True,
144 help="Use a pure Python kernel instead of an IPython kernel.")
145 140 plain = CBool(False, config=True,
146 141 help="Use a plaintext widget instead of rich text (plain can't print/save).")
147 142
@@ -157,50 +152,14 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonMixinConsoleApp):'
157 152
158 153 _plain_changed = _pure_changed
159 154
160 confirm_exit = CBool(True, config=True,
161 help="""
162 Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
163 to force a direct exit without any confirmation.""",
164 )
165
166 155 # the factory for creating a widget
167 156 widget_factory = Any(RichIPythonWidget)
168 157
169 158 def parse_command_line(self, argv=None):
170 159 super(IPythonQtConsoleApp, self).parse_command_line(argv)
171 if argv is None:
172 argv = sys.argv[1:]
173 self.kernel_argv = list(argv) # copy
174 # kernel should inherit default config file from frontend
175 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
176 # Scrub frontend-specific flags
177 swallow_next = False
178 was_flag = False
179 # copy again, in case some aliases have the same name as a flag
180 # argv = list(self.kernel_argv)
181 for a in argv:
182 if swallow_next:
183 swallow_next = False
184 # last arg was an alias, remove the next one
185 # *unless* the last alias has a no-arg flag version, in which
186 # case, don't swallow the next arg if it's also a flag:
187 if not (was_flag and a.startswith('-')):
188 self.kernel_argv.remove(a)
189 continue
190 if a.startswith('-'):
191 split = a.lstrip('-').split('=')
192 alias = split[0]
193 if alias in qt_aliases:
194 self.kernel_argv.remove(a)
195 if len(split) == 1:
196 # alias passed with arg via space
197 swallow_next = True
198 # could have been a flag that matches an alias, e.g. `existing`
199 # in which case, we might not swallow the next arg
200 was_flag = alias in qt_flags
201 elif alias in qt_flags:
202 # strip flag, but don't swallow next, as flags don't take args
203 self.kernel_argv.remove(a)
160 IPythonMixinConsoleApp.parse_command_line(self,argv)
161 self.swallow_args(qt_aliases,qt_flags,argv=argv)
162
204 163
205 164
206 165
@@ -342,10 +301,7 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonMixinConsoleApp):'
342 301 @catch_config_error
343 302 def initialize(self, argv=None):
344 303 super(IPythonQtConsoleApp, self).initialize(argv)
345 self.init_connection_file()
346 default_secure(self.config)
347 self.init_ssh()
348 self.init_kernel_manager()
304 IPythonMixinConsoleApp.initialize(self,argv)
349 305 self.init_qt_elements()
350 306 self.init_colors()
351 307
@@ -1,5 +1,18 b''
1 from __future__ import print_function
1 """ A minimal application using the ZMQ-based terminal IPython frontend.
2 2
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.
5
6 Authors:
7
8 * Min RK
9 * Paul Ivanov
10
11 """
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
3 16 import signal
4 17 import sys
5 18 import time
@@ -9,144 +22,71 b' from IPython.frontend.terminal.ipapp import TerminalIPythonApp'
9 22 from IPython.utils.traitlets import (
10 23 Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any
11 24 )
12 from IPython.zmq.ipkernel import (
13 flags as ipkernel_flags,
14 aliases as ipkernel_aliases,
15 IPKernelApp
16 )
17 from IPython.zmq.session import Session
25 from IPython.zmq.ipkernel import IPKernelApp
26 from IPython.zmq.session import Session, default_secure
18 27 from IPython.zmq.zmqshell import ZMQInteractiveShell
19 from IPython.zmq.blockingkernelmanager import BlockingKernelManager
20 from IPython.zmq.ipkernel import (
21 flags as ipkernel_flags,
22 aliases as ipkernel_aliases,
23 IPKernelApp
24 )
28 from IPython.frontend.kernelmixinapp import (
29 IPythonMixinConsoleApp, app_aliases, app_flags
30 )
31
25 32 from IPython.frontend.zmqterminal.interactiveshell import ZMQTerminalInteractiveShell
26 33
27 34 #-----------------------------------------------------------------------------
28 # Network Constants
35 # Globals
29 36 #-----------------------------------------------------------------------------
30 37
31 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
38 _examples = """
39 ipython console # start the ZMQ-based console
40 ipython console --pylab # start with pylab plotting mode
41 """
32 42
33 43 #-----------------------------------------------------------------------------
34 44 # Flags and Aliases
35 45 #-----------------------------------------------------------------------------
36 46
37
38 flags = dict(ipkernel_flags)
39 frontend_flags = {
40 'existing' : ({'ZMQTerminalIPythonApp' : {'existing' : True}},
41 "Connect to an existing kernel."),
42 }
47 # XXX: the app_flags should really be flags from the mixin
48 flags = dict(app_flags)
49 frontend_flags = { }
43 50 flags.update(frontend_flags)
44 # the flags that are specific to the frontend
45 # these must be scrubbed before being passed to the kernel,
46 # or it will raise an error on unrecognized flags
51
47 52 frontend_flags = frontend_flags.keys()
48 53
49 aliases = dict(ipkernel_aliases)
54 aliases = dict(app_aliases)
55
56 frontend_aliases = dict()
50 57
51 frontend_aliases = dict(
52 hb = 'ZMQTerminalIPythonApp.hb_port',
53 shell = 'ZMQTerminalIPythonApp.shell_port',
54 iopub = 'ZMQTerminalIPythonApp.iopub_port',
55 stdin = 'ZMQTerminalIPythonApp.stdin_port',
56 ip = 'ZMQTerminalIPythonApp.ip',
57 )
58 58 aliases.update(frontend_aliases)
59 # also scrub aliases from the frontend
60 frontend_flags.extend(frontend_aliases.keys())
61 59
62 60 #-----------------------------------------------------------------------------
63 61 # Classes
64 62 #-----------------------------------------------------------------------------
65 63
66 64
67 class ZMQTerminalIPythonApp(TerminalIPythonApp):
65 class ZMQTerminalIPythonApp(TerminalIPythonApp, IPythonMixinConsoleApp):
68 66 """Start a terminal frontend to the IPython zmq kernel."""
69 67
70 kernel_argv = List(Unicode)
68 classes = List([IPKernelApp, ZMQTerminalInteractiveShell])
71 69 flags = Dict(flags)
72 70 aliases = Dict(aliases)
73 classes = List([IPKernelApp, ZMQTerminalInteractiveShell])
74
75 # connection info:
76 ip = Unicode(LOCALHOST, config=True,
77 help="""Set the kernel\'s IP address [default localhost].
78 If the IP address is something other than localhost, then
79 Consoles on other machines will be able to connect
80 to the Kernel, so be careful!"""
81 )
82 pure = False
83 hb_port = Int(0, config=True,
84 help="set the heartbeat port [default: random]")
85 shell_port = Int(0, config=True,
86 help="set the shell (XREP) port [default: random]")
87 iopub_port = Int(0, config=True,
88 help="set the iopub (PUB) port [default: random]")
89 stdin_port = Int(0, config=True,
90 help="set the stdin (XREQ) port [default: random]")
91
92 existing = CBool(False, config=True,
93 help="Whether to connect to an already running Kernel.")
94
95 # from qtconsoleapp:
96 71 def parse_command_line(self, argv=None):
97 72 super(ZMQTerminalIPythonApp, self).parse_command_line(argv)
98 if argv is None:
99 argv = sys.argv[1:]
100
101 self.kernel_argv = list(argv) # copy
102 # kernel should inherit default config file from frontend
103 self.kernel_argv.append("--KernelApp.parent_appname='%s'"%self.name)
104 # scrub frontend-specific flags
105 for a in argv:
106
107 if a.startswith('-'):
108 key = a.lstrip('-').split('=')[0]
109 if key in frontend_flags:
110 self.kernel_argv.remove(a)
111
112 def init_kernel_manager(self):
113 """init kernel manager (from qtconsole)"""
114 # Don't let Qt or ZMQ swallow KeyboardInterupts.
115 # signal.signal(signal.SIGINT, signal.SIG_DFL)
116
117 # Create a KernelManager and start a kernel.
118 self.kernel_manager = BlockingKernelManager(
119 shell_address=(self.ip, self.shell_port),
120 sub_address=(self.ip, self.iopub_port),
121 stdin_address=(self.ip, self.stdin_port),
122 hb_address=(self.ip, self.hb_port),
123 config=self.config
124 )
125 # start the kernel
126 if not self.existing:
127 kwargs = dict(ip=self.ip, ipython=not self.pure)
128 kwargs['extra_arguments'] = self.kernel_argv
129 self.kernel_manager.start_kernel(**kwargs)
130 # wait for kernel to start
131 time.sleep(0.5)
132 self.kernel_manager.start_channels()
133 # relay sigint to kernel
134 signal.signal(signal.SIGINT, self.handle_sigint)
73 IPythonMixinConsoleApp.parse_command_line(self,argv)
74 self.swallow_args(frontend_aliases,frontend_flags,argv=argv)
135 75
136 76 def init_shell(self):
137 self.init_kernel_manager()
77 IPythonMixinConsoleApp.initialize(self)
78 #self.init_kernel_manager()
138 79 self.shell = ZMQTerminalInteractiveShell.instance(config=self.config,
139 80 display_banner=False, profile_dir=self.profile_dir,
140 81 ipython_dir=self.ipython_dir, kernel_manager=self.kernel_manager)
141
82
142 83 def handle_sigint(self, *args):
143 84 self.shell.write('KeyboardInterrupt\n')
144 85 self.kernel_manager.interrupt_kernel()
145
86
146 87 def init_code(self):
147 88 # no-op in the frontend, code gets run in the backend
148 89 pass
149
150 90
151 91 def launch_new_instance():
152 92 """Create and run a full blown IPython instance"""
General Comments 0
You need to be logged in to leave comments. Login now