forked from jupyterlab/jupyterlab
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextension.py
226 lines (180 loc) · 7.47 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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# 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,
AppOptions,
)
app_dir = getattr(nbapp, 'app_dir', get_app_dir())
info = get_app_info(app_options=AppOptions(app_dir=app_dir))
static_url = info['staticUrl']
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.listings_dir = pjoin(app_dir, 'listings')
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', ''):
static_url = nbapp.override_static_url
if getattr(nbapp, 'override_theme_url', ''):
config.themes_url = nbapp.override_theme_url
config.themes_dir = ''
if static_url:
config.static_url = static_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 .handlers.build_handler import build_path, Builder, BuildHandler
from .handlers.extension_manager_handler import (
extensions_handler_path, ExtensionManager, ExtensionHandler
)
from .handlers.error_handler import ErrorHandler
from .commands import (
DEV_DIR, HERE, ensure_app, ensure_core, ensure_dev, watch,
watch_dev, get_app_dir, AppOptions
)
web_app = nbapp.web_app
logger = nbapp.log
base_url = nbapp.base_url
# Handle the app_dir
app_dir = getattr(nbapp, 'app_dir', get_app_dir())
build_handler_options = AppOptions(logger=logger, app_dir=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.app_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.setdefault('buildAvailable', not core_mode and not dev_mode)
page_config.setdefault('buildCheck', not core_mode and not dev_mode)
page_config['devMode'] = dev_mode
page_config['token'] = nbapp.token
# Handle quit button with support for Notebook < 5.6
page_config['quitButton'] = getattr(nbapp, 'quit_button', False)
# Client-side code assumes notebookVersion is a JSON-encoded string
page_config['notebookVersion'] = dumps(version_info)
page_config['exposeAppInBrowser'] = getattr(nbapp, 'expose_app_in_browser', False)
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 = ''
# Print messages.
logger.info('JupyterLab extension loaded from %s' % HERE)
logger.info('JupyterLab application directory is %s' % app_dir)
build_url = ujoin(base_url, build_path)
builder = Builder(core_mode, app_options=build_handler_options)
build_handler = (build_url, BuildHandler, {'builder': builder})
handlers = [build_handler]
errored = False
if core_mode:
logger.info(CORE_NOTE.strip())
ensure_core(logger)
elif dev_mode:
if not watch_mode:
ensure_dev(logger)
logger.info(DEV_NOTE)
# Make sure the app dir exists.
elif not watch_mode:
msgs = ensure_app(app_dir)
if msgs:
[logger.error(msg) for msg in msgs]
handler = (ujoin(base_url, '/lab'), ErrorHandler, { 'messages': msgs })
handlers.append(handler)
errored = True
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_options=build_handler_options)
page_config['buildAvailable'] = False
config.cache_files = False
if not core_mode and not errored:
ext_url = ujoin(base_url, extensions_handler_path)
ext_manager = ExtensionManager(app_options=build_handler_options)
ext_handler = (ext_url, ExtensionHandler, {'manager': ext_manager})
handlers.append(ext_handler)
# Must add before the root server handlers to avoid shadowing.
web_app.add_handlers('.*$', handlers)
# If running under JupyterHub, add more metadata.
if hasattr(nbapp, 'hub_prefix'):
page_config['hubPrefix'] = nbapp.hub_prefix
page_config['hubHost'] = nbapp.hub_host
page_config['hubUser'] = nbapp.user
page_config['shareUrl'] = ujoin(nbapp.hub_prefix, 'user-redirect')
# Assume the server_name property indicates running JupyterHub 1.0.
if hasattr(nbapp, 'server_name'):
page_config['hubServerName'] = nbapp.server_name
api_token = os.getenv('JUPYTERHUB_API_TOKEN', '')
page_config['token'] = api_token
# Add the root handlers if we have not errored.
if not errored:
add_handlers(web_app, config)