forked from jupyterlab/jupyterlab
/
extension.py
200 lines (160 loc) · 6.49 KB
/
extension.py
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# coding: utf-8
"""A tornado based Jupyter lab server."""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
# ----------------------------------------------------------------------------
# Module globals
# ----------------------------------------------------------------------------
import os
DEV_NOTE = """You're running JupyterLab from source.
If you're working on the TypeScript sources of JupyterLab, try running
jupyter lab --dev-mode --watch
to have the system incrementally watch and build JupyterLab for you, as you
make changes.
"""
CORE_NOTE = """
Running the core application with no additional extensions or settings
"""
def load_config(nbapp):
"""Load the JupyterLab configuration and defaults for a given application.
"""
from jupyterlab_server import LabConfig
from .commands import (
get_app_dir,
get_app_info,
get_workspaces_dir,
get_user_settings_dir,
pjoin
)
app_dir = getattr(nbapp, 'app_dir', get_app_dir())
info = get_app_info(app_dir)
public_url = info['publicUrl']
user_settings_dir = getattr(
nbapp, 'user_settings_dir', get_user_settings_dir()
)
workspaces_dir = getattr(nbapp, 'workspaces_dir', get_workspaces_dir())
config = LabConfig()
config.app_dir = app_dir
config.app_name = 'JupyterLab'
config.app_namespace = 'jupyterlab'
config.app_settings_dir = pjoin(app_dir, 'settings')
config.app_version = info['version']
config.cache_files = True
config.schemas_dir = pjoin(app_dir, 'schemas')
config.templates_dir = pjoin(app_dir, 'static')
config.themes_dir = pjoin(app_dir, 'themes')
config.user_settings_dir = user_settings_dir
config.workspaces_dir = workspaces_dir
if getattr(nbapp, 'override_static_url', ''):
public_url = nbapp.override_static_url
if getattr(nbapp, 'override_theme_url', ''):
config.themes_url = nbapp.override_theme_url
config.themes_dir = ''
if public_url:
config.public_url = public_url
else:
config.static_dir = pjoin(app_dir, 'static')
return config
def load_jupyter_server_extension(nbapp):
"""Load the JupyterLab server extension.
"""
# Delay imports to speed up jlpmapp
from json import dumps
from jupyterlab_server import add_handlers
from notebook.utils import url_path_join as ujoin, url_escape
from notebook._version import version_info
from tornado.ioloop import IOLoop
from markupsafe import Markup
from .build_handler import build_path, Builder, BuildHandler
from .extension_manager_handler import (
extensions_handler_path, ExtensionManager, ExtensionHandler
)
from .commands import (
DEV_DIR, HERE, ensure_core, ensure_dev, watch, watch_dev, get_app_dir
)
web_app = nbapp.web_app
logger = nbapp.log
# Handle the app_dir
app_dir = getattr(nbapp, 'app_dir', get_app_dir())
# Check for core mode.
core_mode = False
if getattr(nbapp, 'core_mode', False) or app_dir.startswith(HERE):
app_dir = HERE
core_mode = True
logger.info('Running JupyterLab in core mode')
# Check for dev mode.
dev_mode = False
if getattr(nbapp, 'dev_mode', False) or app_dir.startswith(DEV_DIR):
app_dir = DEV_DIR
dev_mode = True
logger.info('Running JupyterLab in dev mode')
# Set the value on nbapp so it will get picked up in load_config
nbapp.app_dir = app_dir
config = load_config(nbapp)
config.app_name = 'JupyterLab'
config.app_namespace = 'jupyterlab'
config.page_url = '/lab'
config.cache_files = True
# Check for watch.
watch_mode = getattr(nbapp, 'watch', False)
if watch_mode and core_mode:
logger.warn('Cannot watch in core mode, did you mean --dev-mode?')
watch_mode = False
if core_mode and dev_mode:
logger.warn('Conflicting modes, choosing dev_mode over core_mode')
core_mode = False
page_config = web_app.settings.setdefault('page_config_data', dict())
page_config['buildAvailable'] = not core_mode and not dev_mode
page_config['buildCheck'] = not core_mode and not dev_mode
page_config['token'] = nbapp.token
page_config['devMode'] = dev_mode
# Handle bundle url
bundle_url = config.public_url
if bundle_url.startswith(config.page_url):
bundle_url = ujoin(nbapp.base_url, bundle_url)
page_config['bundleUrl'] = bundle_url
# Export the version info tuple to a JSON array. This gets printed
# inside double quote marks, so we render it to a JSON string of the
# JSON data (so that we can call JSON.parse on the frontend on it).
# We also have to wrap it in `Markup` so that it isn't escaped
# by Jinja. Otherwise, if the version has string parts these will be
# escaped and then will have to be unescaped on the frontend.
page_config['notebookVersion'] = Markup(dumps(dumps(version_info))[1:-1])
if nbapp.file_to_run and type(nbapp).__name__ == "LabApp":
relpath = os.path.relpath(nbapp.file_to_run, nbapp.notebook_dir)
uri = url_escape(ujoin('/lab/tree', *relpath.split(os.sep)))
nbapp.default_url = uri
nbapp.file_to_run = ''
if core_mode:
logger.info(CORE_NOTE.strip())
ensure_core(logger)
elif dev_mode:
ensure_dev(logger)
if not watch_mode:
logger.info(DEV_NOTE)
# Print messages.
logger.info('JupyterLab extension loaded from %s' % HERE)
logger.info('JupyterLab application directory is %s' % app_dir)
if watch_mode:
logger.info('Starting JupyterLab watch mode...')
# Set the ioloop in case the watch fails.
nbapp.ioloop = IOLoop.current()
if dev_mode:
watch_dev(logger)
else:
watch(app_dir, logger)
page_config['buildAvailable'] = False
config.cache_files = False
base_url = web_app.settings['base_url']
build_url = ujoin(base_url, build_path)
builder = Builder(logger, core_mode, app_dir)
build_handler = (build_url, BuildHandler, {'builder': builder})
handlers = [build_handler]
if not core_mode:
ext_url = ujoin(base_url, extensions_handler_path)
ext_manager = ExtensionManager(logger, app_dir)
ext_handler = (ext_url, ExtensionHandler, {'manager': ext_manager})
handlers.append(ext_handler)
# Must add before the launcher handlers to avoid shadowing.
web_app.add_handlers('.*$', handlers)
add_handlers(web_app, config)