File: app.py

package info (click to toggle)
jupyter-console 6.6.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 328 kB
  • sloc: python: 1,136; makefile: 168
file content (156 lines) | stat: -rw-r--r-- 5,054 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
""" A minimal application using the ZMQ-based terminal IPython frontend.

This is not a complete console app, as subprocess will not be able to receive
input, there is no real readline support, among other limitations.
"""

# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.

from __future__ import print_function

import signal
import sys

from traitlets import (
    Dict, Any
)
from traitlets.config import catch_config_error, boolean_flag

from jupyter_core.application import JupyterApp, base_aliases, base_flags
from jupyter_client.consoleapp import (
        JupyterConsoleApp, app_aliases, app_flags,
    )

from jupyter_console.ptshell import ZMQTerminalInteractiveShell
from jupyter_console import __version__

#-----------------------------------------------------------------------------
# Globals
#-----------------------------------------------------------------------------

_examples = """
jupyter console # start the ZMQ-based console
jupyter console --existing # connect to an existing ipython session
"""

#-----------------------------------------------------------------------------
# Flags and Aliases
#-----------------------------------------------------------------------------

# copy flags from mixin:
flags = dict(base_flags)
# start with mixin frontend flags:
# update full dict with frontend flags:
flags.update(app_flags)
flags.update(boolean_flag(
    'simple-prompt', 'ZMQTerminalInteractiveShell.simple_prompt',
    "Force simple minimal prompt using `raw_input`",
    "Use a rich interactive prompt with prompt_toolkit"
))

# copy flags from mixin
aliases = dict(base_aliases)

aliases.update(app_aliases)

frontend_aliases = set(app_aliases.keys())
frontend_flags = set(app_flags.keys())


#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------


class ZMQTerminalIPythonApp(JupyterApp, JupyterConsoleApp):  # type:ignore[misc]
    name = "jupyter-console"
    version = __version__
    """Start a terminal frontend to the IPython zmq kernel."""

    description = """
        The Jupyter terminal-based Console.

        This launches a Console application inside a terminal.

        The Console supports various extra features beyond the traditional
        single-process Terminal IPython shell, such as connecting to an
        existing ipython session, via:

            jupyter console --existing

        where the previous session could have been created by another ipython
        console, an ipython qtconsole, or by opening an ipython notebook.

    """
    examples = _examples

    classes = [ZMQTerminalInteractiveShell] + JupyterConsoleApp.classes  # type:ignore[operator]
    flags = Dict(flags)  # type:ignore[assignment]
    aliases = Dict(aliases)  # type:ignore[assignment]
    frontend_aliases = Any(frontend_aliases)
    frontend_flags = Any(frontend_flags)

    subcommands = Dict()

    force_interact = True

    def parse_command_line(self, argv=None):
        super(ZMQTerminalIPythonApp, self).parse_command_line(argv)
        self.build_kernel_argv(self.extra_args)

    def init_shell(self):
        JupyterConsoleApp.initialize(self)
        # relay sigint to kernel
        signal.signal(signal.SIGINT, self.handle_sigint)
        self.shell = ZMQTerminalInteractiveShell.instance(parent=self,
                        manager=self.kernel_manager,
                        client=self.kernel_client,
                        confirm_exit=self.confirm_exit,
        )
        self.shell.own_kernel = not self.existing

    def init_gui_pylab(self):
        # no-op, because we don't want to import matplotlib in the frontend.
        pass

    def handle_sigint(self, *args):
        if self.shell._executing:
            if self.kernel_manager:
                self.kernel_manager.interrupt_kernel()
            else:
                print("ERROR: Cannot interrupt kernels we didn't start.",
                      file = sys.stderr)
        else:
            # raise the KeyboardInterrupt if we aren't waiting for execution,
            # so that the interact loop advances, and prompt is redrawn, etc.
            raise KeyboardInterrupt

    @catch_config_error
    def initialize(self, argv=None):
        """Do actions after construct, but before starting the app."""
        super(ZMQTerminalIPythonApp, self).initialize(argv)
        if self._dispatching:
            return
        # create the shell
        self.init_shell()
        # and draw the banner
        self.init_banner()

    def init_banner(self):
        """optionally display the banner"""
        self.shell.show_banner()

    def start(self):
        # JupyterApp.start dispatches on NoStart
        super(ZMQTerminalIPythonApp, self).start()
        self.log.debug("Starting the jupyter console mainloop...")
        self.shell.mainloop()


main = launch_new_instance = ZMQTerminalIPythonApp.launch_instance


if __name__ == '__main__':
    main()