Path: blob/main/Sage_framework/files/sage-notebook
242 views
#!/private/var/tmp/sage-__VERSION__-current/venv/bin/python3
# -*- coding: utf-8; mode: python -*-
import os
import sys
import ast
import argparse
import logging
import textwrap
logging.basicConfig()
logger = logging.getLogger()
from sage.misc.banner import banner
class NotebookJupyter():
def print_banner(self):
banner()
print('Please wait while the Sage Jupyter Notebook server starts...')
@classmethod
def print_help(cls):
cls(['help'])
def __init__(self, argv):
self.print_banner()
try:
from notebook.app import main
except ImportError:
import traceback
traceback.print_exc()
print("The Jupyter notebook is not installed "
"(at least not in this Sage installation).")
raise SystemExit(1)
main(argv)
class NotebookJupyterlab():
def print_banner(self):
banner()
print('Please wait while the Jupyterlab server starts...')
@classmethod
def print_help(cls):
cls(['help'])
def __init__(self, argv):
try:
from jupyterlab.labapp import main
except ImportError:
import traceback
traceback.print_exc()
print("Jupyterlab is not installed (at least not in this Sage installation).")
raise SystemExit(1)
self.print_banner()
main(argv)
class NotebookNbclassic():
def print_banner(self):
banner()
print('Please wait while the Jupyter server starts...')
@classmethod
def print_help(cls):
cls(['help'])
def __init__(self, argv):
try:
from nbclassic.notebookapp import main
except ImportError:
import traceback
traceback.print_exc()
print("Classic Notebook is not installed (at least not in this Sage installation).")
raise SystemExit(1)
self.print_banner()
main(argv)
class NotebookRetrolab():
def print_banner(self):
banner()
print('Please wait while the Jupyterlab server starts...')
@classmethod
def print_help(cls):
cls(['help'])
def __init__(self, argv):
try:
from retrolab.app import main
except ImportError:
import traceback
traceback.print_exc()
print("Retrolab is not installed (at least not in this Sage installation).")
raise SystemExit(1)
self.print_banner()
main(argv)
class SageNBExport(NotebookJupyter):
def print_banner(self):
banner()
print('Please wait while the SageNB export server starts...')
@classmethod
def print_help(cls):
cls(['--help'])
def __init__(self, argv):
if argv:
SAGENB_EXPORT = 'sagenb-export'
os.execvp(SAGENB_EXPORT, [SAGENB_EXPORT] + argv)
argv += [
"--NotebookApp.nbserver_extensions={'sagenb_export.nbextension':True}",
"--NotebookApp.default_url='/sagenb'",
]
super(SageNBExport, self).__init__(argv)
description = \
"""
The Sage notebook launcher is used to start the notebook, and allows
you to choose between different implementations. Any further command
line options are passed to the respective notebook.
"""
help_help = \
"""
show this help message and exit. Can be combined with
"--notebook=[...]" to see notebook-specific options
"""
epilog = \
"""
EXAMPLES:
* Run default notebook on port 1234.
sage -n default --port=1234
sage -n --port=1234 # equivalent
* Run Jupyter notebook in custom directory:
sage --notebook=jupyter --notebook-dir=/home/foo/bar
* List available legacy Sage notebooks:
sage --notebook=export --list
* Export a legacy Sage notebook as a Jupyter notebook:
sage --notebook=export --ipynb=Output.ipynb admin:10
"""
notebook_launcher = {
'default': NotebookJupyter, # change this to change the default
'ipython': NotebookJupyter,
'jupyter': NotebookJupyter,
'jupyterlab': NotebookJupyterlab,
'nbclassic': NotebookNbclassic,
'export': SageNBExport,
}
notebook_names = ', '.join(notebook_launcher.keys())
def make_parser():
"""
The main parser handling the selection of the notebook.
Any arguments that are not parsed here are supposed to be handled
by the notebook implementation.
"""
parser = argparse.ArgumentParser(
description=description, epilog=epilog,
formatter_class=argparse.RawDescriptionHelpFormatter,
add_help=False)
parser.add_argument('-h', '--help',
dest='option_help', action='store_true',
default=False,
help=help_help)
parser.add_argument('--log', dest='log', default=None,
help='one of [DEBUG, INFO, ERROR, WARNING, CRITICAL]')
default = None
for name, launcher in notebook_launcher.items():
if launcher == notebook_launcher['default'] and name != 'default':
default = name
if default is None:
raise RuntimeError('default launcher is defined but not known under a specific name')
parser.add_argument('--notebook', # long style
'-n', # short style
'-notebook', # wtf style, we can't decide (legacy support)
dest='notebook', type=str, nargs='?', const='default',
help='The notebook to run [one of: {0}]. Default is {1}'.format(
notebook_names, default))
return parser
def trac_23428_browser_workaround():
"""
Running 'sage -n" with the Jupyter notebook on Darwin fails to
open a browser automatically. See :trac:`23428`.
"""
if sys.platform != 'darwin':
return
if not os.environ.get('BROWSER', False):
os.environ['BROWSER'] = 'open'
if __name__ == '__main__':
parser = make_parser()
args, unknown = parser.parse_known_args(sys.argv[1:])
if unknown and unknown[0] == '--':
unknown = unknown[1:]
trac_23428_browser_workaround()
if args.log is not None:
import logging
level = getattr(logging, args.log.upper())
logger.setLevel(level=level)
logger.info('Main parser got arguments %s', args)
logger.info('Passing on to notebook implementation: %s', unknown)
if args.notebook == "sagenb":
logger.critical('cannot use the legacy notebook SageNB with Python 3')
print('The legacy notebook does not work under Python 3; '
'use the Jupyter notebook.')
print('See https://wiki.sagemath.org/Python3-Switch')
print('Use \"sage --notebook=export\" to export SageNB notebooks '
'to Jupyter')
sys.exit(1)
from sage.repl.ipython_kernel.install import SageKernelSpec
SageKernelSpec.check()
try:
launcher = notebook_launcher[args.notebook]
except KeyError:
logger.critical('unknown notebook: %s', args.notebook)
print('Error, notebook must be one of {0} but got {1}'.
format(notebook_names, args.notebook))
sys.exit(1)
if args.option_help:
if args.notebook == 'default':
parser.print_help()
else:
launcher.print_help()
sys.exit(0)
launcher(unknown)