Skip to content

Commit f6d4e3f

Browse files
committed
preparse for subcommands in an extensionapp
1 parent 0fad2c3 commit f6d4e3f

File tree

1 file changed

+50
-22
lines changed

1 file changed

+50
-22
lines changed

jupyter_server/extension/application.py

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import sys
2+
import re
23

34
from traitlets import (
45
Unicode,
@@ -24,7 +25,25 @@
2425
pass
2526

2627

27-
def _preparse_command_line(Application):
28+
def _preparse_for_subcommand(Application, argv):
29+
"""Preparse command line to look for subcommands.
30+
"""
31+
# Read in arguments from command line.
32+
if len(argv) == 0:
33+
return
34+
35+
# Find any subcommands.
36+
if Application.subcommands and len(argv) > 0:
37+
# we have subcommands, and one may have been specified
38+
subc, subargv = argv[0], argv[1:]
39+
if re.match(r'^\w(\-?\w)*$', subc) and subc in Application.subcommands:
40+
# it's a subcommand, and *not* a flag or class parameter
41+
app = Application()
42+
app.initialize_subcommand(subc, subargv)
43+
return app.subapp
44+
45+
46+
def _preparse_for_stopping_flags(Application, argv):
2847
"""Looks for 'help', 'version', and 'generate-config; commands
2948
in command line. If found, raises the help and version of
3049
current Application.
@@ -38,9 +57,9 @@ def _preparse_command_line(Application):
3857
# version), we want to only search the arguments up to the first
3958
# occurrence of '--', which we're calling interpreted_argv.
4059
try:
41-
interpreted_argv = sys.argv[:sys.argv.index('--')]
60+
interpreted_argv = argv[:argv.index('--')]
4261
except ValueError:
43-
interpreted_argv = sys.argv
62+
interpreted_argv = argv
4463

4564
# Catch any help calls.
4665
if any(x in interpreted_argv for x in ('-h', '--help-all', '--help')):
@@ -109,6 +128,8 @@ def _validate_extension_name(self):
109128
aliases = aliases
110129
flags = flags
111130

131+
subcommands = {}
132+
112133
@property
113134
def static_url_prefix(self):
114135
return "/static/{extension_name}/".format(
@@ -293,6 +314,7 @@ def start(self):
293314
294315
Server should be started after extension is initialized.
295316
"""
317+
super(ExtensionApp, self).start()
296318
# Override the browser open file to
297319
# Override the server's display url to show extension's display URL.
298320
self.serverapp.custom_display_url = self.custom_display_url
@@ -302,7 +324,7 @@ def start(self):
302324
# the extensions home page.
303325
self.serverapp._write_browser_open_file = self._write_browser_open_file
304326
# Start the server.
305-
self.serverapp.start()
327+
self.serverapp.start()
306328

307329
def stop(self):
308330
"""Stop the underlying Jupyter server.
@@ -320,34 +342,40 @@ def load_jupyter_server_extension(cls, serverapp, argv=[], **kwargs):
320342
extension.initialize(serverapp, argv=argv)
321343
return extension
322344

345+
323346
@classmethod
324347
def launch_instance(cls, argv=None, **kwargs):
325348
"""Launch the extension like an application. Initializes+configs a stock server
326349
and appends the extension to the server. Then starts the server and routes to
327350
extension's landing page.
328351
"""
329-
# Check for help, version, and generate-config arguments
330-
# before initializing server to make sure these
331-
# arguments trigger actions from the extension not the server.
332-
_preparse_command_line(cls)
333352
# Handle arguments.
334353
if argv is None:
335354
args = sys.argv[1:] # slice out extension config.
336355
else:
337356
args = []
338-
# Get a jupyter server instance.
339-
serverapp = cls.initialize_server(
340-
argv=args,
341-
load_other_extensions=cls.load_other_extensions
342-
)
343-
# Log if extension is blocking other extensions from loading.
344-
if not cls.load_other_extensions:
345-
serverapp.log.info(
346-
"{ext_name} is running without loading "
347-
"other extensions.".format(ext_name=cls.extension_name)
357+
# Check for subcommands
358+
subapp = _preparse_for_subcommand(cls, args)
359+
if subapp:
360+
subapp.start()
361+
else:
362+
# Check for help, version, and generate-config arguments
363+
# before initializing server to make sure these
364+
# arguments trigger actions from the extension not the server.
365+
_preparse_for_stopping_flags(cls, args)
366+
# Get a jupyter server instance.
367+
serverapp = cls.initialize_server(
368+
argv=args,
369+
load_other_extensions=cls.load_other_extensions
348370
)
349-
350-
extension = cls.load_jupyter_server_extension(serverapp, argv=args, **kwargs)
351-
# Start the ioloop.
352-
extension.start()
371+
# Log if extension is blocking other extensions from loading.
372+
if not cls.load_other_extensions:
373+
serverapp.log.info(
374+
"{ext_name} is running without loading "
375+
"other extensions.".format(ext_name=cls.extension_name)
376+
)
377+
378+
extension = cls.load_jupyter_server_extension(serverapp, argv=args, **kwargs)
379+
# Start the ioloop.
380+
extension.start()
353381

0 commit comments

Comments
 (0)