Skip to content

Commit

Permalink
Merge pull request #375 from afshin/open-browser
Browse files Browse the repository at this point in the history
Handle open_browser trait in ServerApp and ExtensionApp differently
  • Loading branch information
Zsailer authored Jan 6, 2021
2 parents 72ee66b + ebbcbb7 commit ec6217e
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 5 deletions.
20 changes: 17 additions & 3 deletions jupyter_server/extension/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
Unicode,
List,
Dict,
Bool,
default
)
from traitlets.config import Config
Expand Down Expand Up @@ -147,9 +148,20 @@ class method. This method can be set as a entry_point in
# A useful class property that subclasses can override to
# configure the underlying Jupyter Server when this extension
# is launched directly (using its `launch_instance` method).
serverapp_config = {
"open_browser": True
}
serverapp_config = {}

# Some subclasses will likely ovrride this trait to flip
# the default value to True if they offer a browser
# based frontend.
open_browser = Bool(
False,
help="""Whether to open in a browser after starting.
The specific browser used is platform dependent and
determined by the python standard library `webbrowser`
module, unless it is overridden using the --browser
(ServerApp.browser) configuration option.
"""
).tag(config=True)

# The extension name used to name the jupyter config
# file, jupyter_{name}_config.
Expand Down Expand Up @@ -365,6 +377,8 @@ def initialize_server(cls, argv=[], load_other_extensions=True, **kwargs):
config = Config(cls._jupyter_server_config())
serverapp = ServerApp.instance(**kwargs, argv=[], config=config)
serverapp.initialize(argv=argv, find_extensions=load_other_extensions)
# Inform the serverapp that this extension app started the app.
serverapp._starter_app_name = cls.name
return serverapp

def initialize(self):
Expand Down
51 changes: 49 additions & 2 deletions jupyter_server/serverapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,28 @@ def _default_allow_remote(self):
"""
)

# The name of the app that started this server (if not started directly).
# It is sometimes important to know if + which another app (say a server extension)
# started the serverapp to properly configure some traits.
# This trait should not be configured by users. It will likely be set by ExtensionApp.
_starter_app_name = Unicode(None, allow_none=True)

@validate('_starter_app_name')
def _validate_starter_app(self, proposal):
# Check that a previous server extension isn't named yet
value = proposal["value"]
if self._starter_app_name != None:
raise TraitError("Another extension was already named as the starter_server_extension.")
return value

@property
def starter_app(self):
"""Get the Extension that started this server."""
name = self._starter_app_name
if name is None:
return
return self.extension_manager.extension_points.get(name, None).app

open_browser = Bool(False, config=True,
help="""Whether to open in a browser after starting.
The specific browser used is platform dependent and
Expand All @@ -911,6 +933,31 @@ def _default_allow_remote(self):
(ServerApp.browser) configuration option.
""")


def _handle_browser_opening(self):
"""This method handles whether a browser should be opened.
By default, Jupyter Server doesn't try to open an browser. However,
it's many server extensions might want to open the browser by default.
This essentially toggles the default value for open_browser.
From a UX perspective, this needs to be surfaced to the user. The default
behavior of Jupyter Server switches, which can be confusing.
"""
# If the server was started by another application, use that applications
# trait for the open_browser trait. If that trait is not given, ignore
if self.starter_app:
try:
if self.starter_app.open_browser:
self.launch_browser()
# If the starter_app doesn't have an open_browser trait, ignore
# move on and don't start a browser.
except AttributeError:
pass
else:
if self.open_browser:
self.launch_browser()


browser = Unicode(u'', config=True,
help="""Specify what command to use to invoke a web
browser when starting the server. If not specified, the
Expand Down Expand Up @@ -1832,8 +1879,8 @@ def start_app(self):
self.write_server_info_file()
self.write_browser_open_file()

if self.open_browser:
self.launch_browser()
# Handle the browser opening.
self._handle_browser_opening()

if self.token and self._token_generated:
# log full URL with generated token, so there's a copy/pasteable link
Expand Down

0 comments on commit ec6217e

Please sign in to comment.