##// 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 flags = dict(ipkernel_flags)
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 app_flags = {
70 app_flags = {
67 'existing' : ({'IPythonMixinConsoleApp' : {'existing' : 'kernel*.json'}},
71 'existing' : ({'IPythonMixinConsoleApp' : {'existing' : 'kernel*.json'}},
68 "Connect to an existing kernel. If no argument specified, guess most recent"),
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 app_flags.update(boolean_flag(
74 app_flags.update(boolean_flag(
75 'confirm-exit', 'IPythonMixinConsoleApp.confirm_exit',
75 'confirm-exit', 'IPythonMixinConsoleApp.confirm_exit',
@@ -84,6 +84,7 b' flags.update(app_flags)'
84
84
85 aliases = dict(ipkernel_aliases)
85 aliases = dict(ipkernel_aliases)
86
86
87 # also scrub aliases from the frontend
87 app_aliases = dict(
88 app_aliases = dict(
88 hb = 'IPythonMixinConsoleApp.hb_port',
89 hb = 'IPythonMixinConsoleApp.hb_port',
89 shell = 'IPythonMixinConsoleApp.shell_port',
90 shell = 'IPythonMixinConsoleApp.shell_port',
@@ -135,6 +136,8 b' class IPythonMixinConsoleApp(Configurable):'
135
136
136 kernel_argv = List(Unicode)
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 # create requested profiles by default, if they don't exist:
141 # create requested profiles by default, if they don't exist:
139 auto_create = CBool(True)
142 auto_create = CBool(True)
140 # connection info:
143 # connection info:
@@ -176,13 +179,16 b' class IPythonMixinConsoleApp(Configurable):'
176 Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
179 Set to display confirmation dialog on exit. You can always use 'exit' or 'quit',
177 to force a direct exit without any confirmation.""",
180 to force a direct exit without any confirmation.""",
178 )
181 )
179
182
180
183
181 def parse_command_line(self, argv=None):
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 # make this stuff after this a function, in case the super stuff goes
186 # make this stuff after this a function, in case the super stuff goes
184 # away. Also, Min notes that this functionality should be moved to a
187 # away. Also, Min notes that this functionality should be moved to a
185 # generic library of kernel stuff
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 if argv is None:
192 if argv is None:
187 argv = sys.argv[1:]
193 argv = sys.argv[1:]
188 self.kernel_argv = list(argv) # copy
194 self.kernel_argv = list(argv) # copy
@@ -205,15 +211,15 b' class IPythonMixinConsoleApp(Configurable):'
205 if a.startswith('-'):
211 if a.startswith('-'):
206 split = a.lstrip('-').split('=')
212 split = a.lstrip('-').split('=')
207 alias = split[0]
213 alias = split[0]
208 if alias in qt_aliases:
214 if alias in aliases:
209 self.kernel_argv.remove(a)
215 self.kernel_argv.remove(a)
210 if len(split) == 1:
216 if len(split) == 1:
211 # alias passed with arg via space
217 # alias passed with arg via space
212 swallow_next = True
218 swallow_next = True
213 # could have been a flag that matches an alias, e.g. `existing`
219 # could have been a flag that matches an alias, e.g. `existing`
214 # in which case, we might not swallow the next arg
220 # in which case, we might not swallow the next arg
215 was_flag = alias in qt_flags
221 was_flag = alias in flags
216 elif alias in qt_flags:
222 elif alias in flags:
217 # strip flag, but don't swallow next, as flags don't take args
223 # strip flag, but don't swallow next, as flags don't take args
218 self.kernel_argv.remove(a)
224 self.kernel_argv.remove(a)
219
225
@@ -347,20 +353,12 b' class IPythonMixinConsoleApp(Configurable):'
347
353
348
354
349 def initialize(self, argv=None):
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 self.init_connection_file()
360 self.init_connection_file()
352 default_secure(self.config)
361 default_secure(self.config)
353 self.init_ssh()
362 self.init_ssh()
354 self.init_kernel_manager()
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 from IPython.zmq.ipkernel import IPKernelApp
48 from IPython.zmq.ipkernel import IPKernelApp
49 from IPython.zmq.session import Session, default_secure
49 from IPython.zmq.session import Session, default_secure
50 from IPython.zmq.zmqshell import ZMQInteractiveShell
50 from IPython.zmq.zmqshell import ZMQInteractiveShell
51
51 from IPython.frontend.kernelmixinapp import (
52 from IPython.frontend.kernelmixinapp import (
52 IPythonMixinConsoleApp, app_aliases, app_flags
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 # Aliases and Flags
72 # Aliases and Flags
72 #-----------------------------------------------------------------------------
73 #-----------------------------------------------------------------------------
73
74
75 # XXX: the app_flags should really be flags from the mixin
74 flags = dict(app_flags)
76 flags = dict(app_flags)
75 qt_flags = {
77 qt_flags = {
76 #'existing' : ({'IPythonQtConsoleApp' : {'existing' : 'kernel*.json'}},
77 # "Connect to an existing kernel. If no argument specified, guess most recent"),
78 'pure' : ({'IPythonQtConsoleApp' : {'pure' : True}},
78 'pure' : ({'IPythonQtConsoleApp' : {'pure' : True}},
79 "Use a pure Python kernel instead of an IPython kernel."),
79 "Use a pure Python kernel instead of an IPython kernel."),
80 'plain' : ({'ConsoleWidget' : {'kind' : 'plain'}},
80 'plain' : ({'ConsoleWidget' : {'kind' : 'plain'}},
@@ -90,8 +90,6 b' flags.update(qt_flags)'
90 aliases = dict(app_aliases)
90 aliases = dict(app_aliases)
91
91
92 qt_aliases = dict(
92 qt_aliases = dict(
93 existing = 'IPythonQtConsoleApp.existing',
94 f = 'IPythonQtConsoleApp.connection_file',
95
93
96 style = 'IPythonWidget.syntax_style',
94 style = 'IPythonWidget.syntax_style',
97 stylesheet = 'IPythonQtConsoleApp.stylesheet',
95 stylesheet = 'IPythonQtConsoleApp.stylesheet',
@@ -113,7 +111,6 b' aliases.update(qt_aliases)'
113
111
114 class IPythonQtConsoleApp(BaseIPythonApplication, IPythonMixinConsoleApp):
112 class IPythonQtConsoleApp(BaseIPythonApplication, IPythonMixinConsoleApp):
115 name = 'ipython-qtconsole'
113 name = 'ipython-qtconsole'
116 default_config_file_name='ipython_config.py'
117
114
118 description = """
115 description = """
119 The IPython QtConsole.
116 The IPython QtConsole.
@@ -140,8 +137,6 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonMixinConsoleApp):'
140 stylesheet = Unicode('', config=True,
137 stylesheet = Unicode('', config=True,
141 help="path to a custom CSS stylesheet")
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 plain = CBool(False, config=True,
140 plain = CBool(False, config=True,
146 help="Use a plaintext widget instead of rich text (plain can't print/save).")
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 _plain_changed = _pure_changed
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 # the factory for creating a widget
155 # the factory for creating a widget
167 widget_factory = Any(RichIPythonWidget)
156 widget_factory = Any(RichIPythonWidget)
168
157
169 def parse_command_line(self, argv=None):
158 def parse_command_line(self, argv=None):
170 super(IPythonQtConsoleApp, self).parse_command_line(argv)
159 super(IPythonQtConsoleApp, self).parse_command_line(argv)
171 if argv is None:
160 IPythonMixinConsoleApp.parse_command_line(self,argv)
172 argv = sys.argv[1:]
161 self.swallow_args(qt_aliases,qt_flags,argv=argv)
173 self.kernel_argv = list(argv) # copy
162
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)
204
163
205
164
206
165
@@ -342,10 +301,7 b' class IPythonQtConsoleApp(BaseIPythonApplication, IPythonMixinConsoleApp):'
342 @catch_config_error
301 @catch_config_error
343 def initialize(self, argv=None):
302 def initialize(self, argv=None):
344 super(IPythonQtConsoleApp, self).initialize(argv)
303 super(IPythonQtConsoleApp, self).initialize(argv)
345 self.init_connection_file()
304 IPythonMixinConsoleApp.initialize(self,argv)
346 default_secure(self.config)
347 self.init_ssh()
348 self.init_kernel_manager()
349 self.init_qt_elements()
305 self.init_qt_elements()
350 self.init_colors()
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 import signal
16 import signal
4 import sys
17 import sys
5 import time
18 import time
@@ -9,144 +22,71 b' from IPython.frontend.terminal.ipapp import TerminalIPythonApp'
9 from IPython.utils.traitlets import (
22 from IPython.utils.traitlets import (
10 Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any
23 Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any
11 )
24 )
12 from IPython.zmq.ipkernel import (
25 from IPython.zmq.ipkernel import IPKernelApp
13 flags as ipkernel_flags,
26 from IPython.zmq.session import Session, default_secure
14 aliases as ipkernel_aliases,
15 IPKernelApp
16 )
17 from IPython.zmq.session import Session
18 from IPython.zmq.zmqshell import ZMQInteractiveShell
27 from IPython.zmq.zmqshell import ZMQInteractiveShell
19 from IPython.zmq.blockingkernelmanager import BlockingKernelManager
28 from IPython.frontend.kernelmixinapp import (
20 from IPython.zmq.ipkernel import (
29 IPythonMixinConsoleApp, app_aliases, app_flags
21 flags as ipkernel_flags,
30 )
22 aliases as ipkernel_aliases,
31
23 IPKernelApp
24 )
25 from IPython.frontend.zmqterminal.interactiveshell import ZMQTerminalInteractiveShell
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 # Flags and Aliases
44 # Flags and Aliases
35 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
36
46
37
47 # XXX: the app_flags should really be flags from the mixin
38 flags = dict(ipkernel_flags)
48 flags = dict(app_flags)
39 frontend_flags = {
49 frontend_flags = { }
40 'existing' : ({'ZMQTerminalIPythonApp' : {'existing' : True}},
41 "Connect to an existing kernel."),
42 }
43 flags.update(frontend_flags)
50 flags.update(frontend_flags)
44 # the flags that are specific to the frontend
51
45 # these must be scrubbed before being passed to the kernel,
46 # or it will raise an error on unrecognized flags
47 frontend_flags = frontend_flags.keys()
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 aliases.update(frontend_aliases)
58 aliases.update(frontend_aliases)
59 # also scrub aliases from the frontend
60 frontend_flags.extend(frontend_aliases.keys())
61
59
62 #-----------------------------------------------------------------------------
60 #-----------------------------------------------------------------------------
63 # Classes
61 # Classes
64 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
65
63
66
64
67 class ZMQTerminalIPythonApp(TerminalIPythonApp):
65 class ZMQTerminalIPythonApp(TerminalIPythonApp, IPythonMixinConsoleApp):
68 """Start a terminal frontend to the IPython zmq kernel."""
66 """Start a terminal frontend to the IPython zmq kernel."""
69
67
70 kernel_argv = List(Unicode)
68 classes = List([IPKernelApp, ZMQTerminalInteractiveShell])
71 flags = Dict(flags)
69 flags = Dict(flags)
72 aliases = Dict(aliases)
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 def parse_command_line(self, argv=None):
71 def parse_command_line(self, argv=None):
97 super(ZMQTerminalIPythonApp, self).parse_command_line(argv)
72 super(ZMQTerminalIPythonApp, self).parse_command_line(argv)
98 if argv is None:
73 IPythonMixinConsoleApp.parse_command_line(self,argv)
99 argv = sys.argv[1:]
74 self.swallow_args(frontend_aliases,frontend_flags,argv=argv)
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)
135
75
136 def init_shell(self):
76 def init_shell(self):
137 self.init_kernel_manager()
77 IPythonMixinConsoleApp.initialize(self)
78 #self.init_kernel_manager()
138 self.shell = ZMQTerminalInteractiveShell.instance(config=self.config,
79 self.shell = ZMQTerminalInteractiveShell.instance(config=self.config,
139 display_banner=False, profile_dir=self.profile_dir,
80 display_banner=False, profile_dir=self.profile_dir,
140 ipython_dir=self.ipython_dir, kernel_manager=self.kernel_manager)
81 ipython_dir=self.ipython_dir, kernel_manager=self.kernel_manager)
141
82
142 def handle_sigint(self, *args):
83 def handle_sigint(self, *args):
143 self.shell.write('KeyboardInterrupt\n')
84 self.shell.write('KeyboardInterrupt\n')
144 self.kernel_manager.interrupt_kernel()
85 self.kernel_manager.interrupt_kernel()
145
86
146 def init_code(self):
87 def init_code(self):
147 # no-op in the frontend, code gets run in the backend
88 # no-op in the frontend, code gets run in the backend
148 pass
89 pass
149
150
90
151 def launch_new_instance():
91 def launch_new_instance():
152 """Create and run a full blown IPython instance"""
92 """Create and run a full blown IPython instance"""
General Comments 0
You need to be logged in to leave comments. Login now