Skip to content

Commit d53357d

Browse files
authored
Added support for fullStaticUrl and fix handling of base_url (#120)
* strip trailing slash from static url * bump jupyter_server requirement * use url_pattern in labhandler
1 parent 265fd93 commit d53357d

File tree

2 files changed

+43
-48
lines changed

2 files changed

+43
-48
lines changed

jupyterlab_server/handlers.py

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class LabHandler(ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandl
6363
def initialize(self, name, lab_config={}):
6464
super().initialize(name)
6565
self.lab_config = lab_config
66-
66+
6767
@web.authenticated
6868
@web.removeslash
6969
def get(self, mode = None, workspace = None, tree = None):
@@ -82,8 +82,12 @@ def get(self, mode = None, workspace = None, tree = None):
8282
server_root = server_root.replace(os.sep, '/')
8383
base_url = self.settings.get('base_url')
8484

85+
# Remove the trailing slash for compatibiity with html-webpack-plugin.
86+
full_static_url = self.static_url_prefix.rstrip('/')
87+
page_config.setdefault('fullStaticUrl', full_static_url)
88+
8589
page_config.setdefault('terminalsAvailable', terminals)
86-
page_config.setdefault('ignorePlugins', [])
90+
page_config.setdefault('ignorePlugins', [])
8791
page_config.setdefault('serverRoot', server_root)
8892
page_config['store_id'] = self.application.store_id
8993
self.application.store_id += 1
@@ -97,13 +101,13 @@ def get(self, mode = None, workspace = None, tree = None):
97101
page_config.setdefault('fullMathjaxUrl', mathjax_url)
98102

99103
# Add parameters parsed from the URL
100-
if mode == 'doc':
104+
if mode == 'doc':
101105
page_config['mode'] = 'single-document'
102106
else:
103107
page_config['mode'] = 'multiple-document'
104108
page_config['workspace'] = workspace
105109
page_config['treePath'] = tree_path
106-
110+
107111
# Put all our config in page_config
108112
for name in config.trait_names():
109113
page_config[_camelCase(name)] = getattr(app, name)
@@ -159,9 +163,6 @@ class LabConfig(HasTraits):
159163
'If given, a static file handler will be '
160164
'added.'))
161165

162-
static_url = Unicode(help=('The url path for static application '
163-
'assets. This can be a CDN if desired.'))
164-
165166

166167
labextensions_url = Unicode('', help='The url for dynamic JupyterLab extensions')
167168

@@ -193,7 +194,7 @@ class LabConfig(HasTraits):
193194
'for themes.'))
194195

195196
translations_api_url = Unicode(help='The url path of the translations handler.')
196-
197+
197198
tree_url = Unicode(help='The url path of the tree handler.')
198199

199200
cache_files = Bool(True,
@@ -204,10 +205,6 @@ class LabConfig(HasTraits):
204205
def _default_template_dir(self):
205206
return DEFAULT_TEMPLATE_PATH
206207

207-
@default('static_url')
208-
def _default_static_url(self):
209-
return ujoin('static/', self.app_namespace)
210-
211208
@default('labextensions_url')
212209
def _default_labextensions_url(self):
213210
return ujoin(self.app_url, "extensions/")
@@ -239,7 +236,7 @@ def _default_themes_url(self):
239236
@default('tree_url')
240237
def _default_tree_url(self):
241238
return ujoin(self.app_url, 'tree/')
242-
239+
243240
@default('translations_api_url')
244241
def _default_translations_api_url(self):
245242
return ujoin(self.app_url, 'api', 'translations/')
@@ -257,83 +254,82 @@ def render_template(self, name, **ns):
257254
return super().render_template(name, **ns)
258255

259256

260-
def add_handlers(handlers, app):
257+
def add_handlers(handlers, extension_app):
261258
"""Add the appropriate handlers to the web app.
262259
"""
263260
# Normalize directories.
264261
for name in LabConfig.class_trait_names():
265262
if not name.endswith('_dir'):
266263
continue
267-
value = getattr(app, name)
268-
setattr(app, name, value.replace(os.sep, '/'))
264+
value = getattr(extension_app, name)
265+
setattr(extension_app, name, value.replace(os.sep, '/'))
269266

270267
# Normalize urls
271268
# Local urls should have a leading slash but no trailing slash
272269
for name in LabConfig.class_trait_names():
273270
if not name.endswith('_url'):
274271
continue
275-
value = getattr(app, name)
272+
value = getattr(extension_app, name)
276273
if is_url(value):
277274
continue
278275
if not value.startswith('/'):
279276
value = '/' + value
280277
if value.endswith('/'):
281278
value = value[:-1]
282-
setattr(app, name, value)
279+
setattr(extension_app, name, value)
283280

284-
url_pattern = MASTER_URL_PATTERN.format(app.app_url.replace('/', ''))
285-
lab_path = ujoin(app.settings.get('base_url'), url_pattern)
286-
handlers.append((lab_path, LabHandler, {'lab_config': app}))
281+
url_pattern = MASTER_URL_PATTERN.format(extension_app.app_url.replace('/', ''))
282+
handlers.append((url_pattern, LabHandler, {'lab_config': extension_app}))
287283

288284
# Cache all or none of the files depending on the `cache_files` setting.
289-
no_cache_paths = [] if app.cache_files else ['/']
285+
no_cache_paths = [] if extension_app.cache_files else ['/']
290286

291287
# Handle dynamic lab extensions.
292-
labextensions_path = app.extra_labextensions_path + app.labextensions_path
293-
labextensions_url = ujoin(app.labextensions_url, "(.*)")
288+
labextensions_path = extension_app.extra_labextensions_path + extension_app.labextensions_path
289+
labextensions_url = ujoin(extension_app.labextensions_url, "(.*)")
294290
handlers.append(
295291
(labextensions_url, FileFindHandler, {
296292
'path': labextensions_path,
297293
'no_cache_paths': ['/'], # don't cache anything in labextensions
298294
}))
299295

300296
# Handle local settings.
301-
if app.schemas_dir:
297+
if extension_app.schemas_dir:
302298
settings_config = {
303-
'app_settings_dir': app.app_settings_dir,
304-
'schemas_dir': app.schemas_dir,
305-
'settings_dir': app.user_settings_dir,
299+
'app_settings_dir': extension_app.app_settings_dir,
300+
'schemas_dir': extension_app.schemas_dir,
301+
'settings_dir': extension_app.user_settings_dir,
306302
'labextensions_path': labextensions_path
307303
}
308304

309305
# Handle requests for the list of settings. Make slash optional.
310-
settings_path = ujoin(app.settings_url, '?')
306+
settings_path = ujoin(extension_app.settings_url, '?')
311307
handlers.append((settings_path, SettingsHandler, settings_config))
312308

313309
# Handle requests for an individual set of settings.
314-
setting_path = ujoin(app.settings_url, '(?P<schema_name>.+)')
310+
setting_path = ujoin(extension_app.settings_url, '(?P<schema_name>.+)')
315311
handlers.append((setting_path, SettingsHandler, settings_config))
316312

317313
# Handle saved workspaces.
318-
if app.workspaces_dir:
314+
if extension_app.workspaces_dir:
319315

320316
workspaces_config = {
321-
'path': app.workspaces_dir
317+
'path': extension_app.workspaces_dir
322318
}
323319

324320
# Handle requests for the list of workspaces. Make slash optional.
325-
workspaces_api_path = ujoin(app.workspaces_api_url, '?')
321+
workspaces_api_path = ujoin(extension_app.workspaces_api_url, '?')
326322
handlers.append((
327323
workspaces_api_path, WorkspacesHandler, workspaces_config))
328324

329325
# Handle requests for an individually named workspace.
330-
workspace_api_path = ujoin(app.workspaces_api_url, '(?P<space_name>.+)')
326+
workspace_api_path = ujoin(extension_app.workspaces_api_url, '(?P<space_name>.+)')
331327
handlers.append((
332328
workspace_api_path, WorkspacesHandler, workspaces_config))
333329

334330
# Handle local listings.
335331

336-
settings_config = app.settings.get('config', {}).get('LabServerApp', {})
332+
settings_config = extension_app.settings.get('config', {}).get('LabServerApp', {})
337333
blocked_extensions_uris = settings_config.get('blocked_extensions_uris', '')
338334
allowed_extensions_uris = settings_config.get('allowed_extensions_uris', '')
339335

@@ -344,8 +340,7 @@ def add_handlers(handlers, app):
344340

345341
ListingsHandler.listings_refresh_seconds = settings_config.get('listings_refresh_seconds', 60 * 60)
346342
ListingsHandler.listings_request_opts = settings_config.get('listings_request_options', {})
347-
base_url = app.settings.get('base_url')
348-
listings_url = ujoin(base_url, app.listings_url)
343+
listings_url = ujoin(extension_app.listings_url)
349344
listings_path = ujoin(listings_url, '(.*)')
350345

351346
if blocked_extensions_uris:
@@ -367,34 +362,34 @@ def add_handlers(handlers, app):
367362
handlers.append((listings_path, ListingsHandler, {}))
368363

369364
# Handle local themes.
370-
if app.themes_dir:
371-
themes_url = app.themes_url
365+
if extension_app.themes_dir:
366+
themes_url = extension_app.themes_url
372367
themes_path = ujoin(themes_url, '(.*)')
373368
handlers.append((
374369
themes_path,
375370
ThemesHandler,
376371
{
377372
'themes_url': themes_url,
378-
'path': app.themes_dir,
373+
'path': extension_app.themes_dir,
379374
'labextensions_path': labextensions_path,
380375
'no_cache_paths': no_cache_paths
381376
}
382377
))
383378

384379
# Handle translations.
385-
if app.translations_api_url:
380+
if extension_app.translations_api_url:
386381
# Handle requests for the list of language packs available.
387382
# Make slash optional.
388-
translations_path = ujoin(base_url, app.translations_api_url, '?')
389-
handlers.append((translations_path, TranslationsHandler, {'lab_config': app}))
383+
translations_path = ujoin(extension_app.translations_api_url, '?')
384+
handlers.append((translations_path, TranslationsHandler, {'lab_config': extension_app}))
390385

391386
# Handle requests for an individual language pack.
392387
translations_lang_path = ujoin(
393-
base_url, app.translations_api_url, '(?P<locale>.*)')
394-
handlers.append((translations_lang_path, TranslationsHandler, {'lab_config': app}))
388+
extension_app.translations_api_url, '(?P<locale>.*)')
389+
handlers.append((translations_lang_path, TranslationsHandler, {'lab_config': extension_app}))
395390

396391
# Let the lab handler act as the fallthrough option instead of a 404.
397-
fallthrough_url = ujoin(app.app_url, r'.*')
392+
fallthrough_url = ujoin(extension_app.app_url, r'.*')
398393
handlers.append((fallthrough_url, NotFoundHandler))
399394

400395

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
'ipykernel',
4646
'pytest==5.3.2',
4747
'pytest-cov',
48-
'pytest-tornasync',
48+
'pytest-tornasync',
4949
'pytest-console-scripts',
5050
'strict-rfc3339',
5151
'wheel',
@@ -58,7 +58,7 @@
5858
'jsonschema>=3.0.1',
5959
'packaging',
6060
'requests',
61-
'jupyter_server~=1.0.0rc5',
61+
'jupyter_server~=1.0.0rc8',
6262
],
6363
setup_args['entry_points'] = {
6464
'pytest11': [

0 commit comments

Comments
 (0)