@@ -903,6 +903,28 @@ def _default_allow_remote(self):
903903 """
904904 )
905905
906+ # The name of the app that started this server (if not started directly).
907+ # It is sometimes important to know if + which another app (say a server extension)
908+ # started the serverapp to properly configure some traits.
909+ # This trait should not be configured by users. It will likely be set by ExtensionApp.
910+ _starter_app_name = Unicode (None , allow_none = True )
911+
912+ @validate ('_starter_app_name' )
913+ def _validate_starter_app (self , proposal ):
914+ # Check that a previous server extension isn't named yet
915+ value = proposal ["value" ]
916+ if self ._starter_app_name != None :
917+ raise TraitError ("Another extension was already named as the starter_server_extension." )
918+ return value
919+
920+ @property
921+ def starter_app (self ):
922+ """Get the Extension that started this server."""
923+ name = self ._starter_app_name
924+ if name is None :
925+ return
926+ return self .extension_manager .extension_points .get (name , None ).app
927+
906928 open_browser = Bool (False , config = True ,
907929 help = """Whether to open in a browser after starting.
908930 The specific browser used is platform dependent and
@@ -911,6 +933,31 @@ def _default_allow_remote(self):
911933 (ServerApp.browser) configuration option.
912934 """ )
913935
936+
937+ def _handle_browser_opening (self ):
938+ """This method handles whether a browser should be opened.
939+ By default, Jupyter Server doesn't try to open an browser. However,
940+ it's many server extensions might want to open the browser by default.
941+ This essentially toggles the default value for open_browser.
942+
943+ From a UX perspective, this needs to be surfaced to the user. The default
944+ behavior of Jupyter Server switches, which can be confusing.
945+ """
946+ # If the server was started by another application, use that applications
947+ # trait for the open_browser trait. If that trait is not given, ignore
948+ if self .starter_app :
949+ try :
950+ if self .starter_app .open_browser :
951+ self .launch_browser ()
952+ # If the starter_app doesn't have an open_browser trait, ignore
953+ # move on and don't start a browser.
954+ except AttributeError :
955+ pass
956+ else :
957+ if self .open_browser :
958+ self .launch_browser ()
959+
960+
914961 browser = Unicode (u'' , config = True ,
915962 help = """Specify what command to use to invoke a web
916963 browser when starting the server. If not specified, the
@@ -1832,8 +1879,8 @@ def start_app(self):
18321879 self .write_server_info_file ()
18331880 self .write_browser_open_file ()
18341881
1835- if self . open_browser :
1836- self .launch_browser ()
1882+ # Handle the browser opening.
1883+ self ._handle_browser_opening ()
18371884
18381885 if self .token and self ._token_generated :
18391886 # log full URL with generated token, so there's a copy/pasteable link
0 commit comments