##// 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:
@@ -179,10 +182,13 b' class IPythonMixinConsoleApp(Configurable):'
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,132 +22,60 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,
22 aliases as ipkernel_aliases,
23 IPKernelApp
24 )
30 )
31
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)
@@ -147,7 +88,6 b' class ZMQTerminalIPythonApp(TerminalIPythonApp):'
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
90
150
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"""
153 app = ZMQTerminalIPythonApp.instance()
93 app = ZMQTerminalIPythonApp.instance()
General Comments 0
You need to be logged in to leave comments. Login now