99import re
1010import sys
1111import inspect
12+ import warnings
1213
1314from IPython import get_ipython
1415from IPython .display import IFrame , display
@@ -37,6 +38,7 @@ class JupyterDash(dash.Dash):
3738 )
3839 default_server_url = None
3940 _in_ipython = get_ipython () is not None
41+ _in_colab = "google.colab" in sys .modules
4042 _token = str (uuid .uuid4 ())
4143
4244 @classmethod
@@ -63,14 +65,31 @@ def infer_jupyter_proxy_config(cls):
6365 see what JupyterLab extensions are installed by running the following command:
6466 $ jupyter labextension list
6567 """
66- if not JupyterDash ._in_ipython :
67- # No op when not running in a Jupyter context
68+ if not JupyterDash ._in_ipython or JupyterDash . _in_colab :
69+ # No op when not running in a Jupyter context or when in Colab
6870 return
69-
70- _request_jupyter_config ()
71+ else :
72+ # Assume classic notebook or JupyterLab
73+ _request_jupyter_config ()
7174
7275 def __init__ (self , name = None , server_url = None , ** kwargs ):
7376 """"""
77+ # Strip unsupported properties and warn
78+ if JupyterDash ._in_colab :
79+ unsupported_colab_props = [
80+ 'requests_pathname_prefix' ,
81+ 'routes_pathname_prefix' ,
82+ 'url_base_pathname'
83+ ]
84+ for prop in unsupported_colab_props :
85+ if prop in kwargs :
86+ kwargs .pop (prop )
87+ warnings .warn (
88+ "The {prop} argument is ignored when running in Colab" .format (
89+ prop = prop
90+ )
91+ )
92+
7493 # Call superclass constructor
7594 super (JupyterDash , self ).__init__ (name = name , ** kwargs )
7695
@@ -105,6 +124,9 @@ def __init__(self, name=None, server_url=None, **kwargs):
105124 if domain_base :
106125 # Dash Enterprise set PLOTLY_DASH_DOMAIN_BASE environment variable
107126 server_url = 'https://' + domain_base
127+ elif JupyterDash ._in_colab :
128+ warnings .warn ("The server_url argument is ignored when running in Colab" )
129+ server_url = None
108130
109131 self .server_url = server_url
110132
@@ -126,7 +148,7 @@ def alive():
126148
127149 def run_server (
128150 self ,
129- mode = None , width = 800 , height = 650 , inline_exceptions = None ,
151+ mode = None , width = "100%" , height = 650 , inline_exceptions = None ,
130152 ** kwargs
131153 ):
132154 """
@@ -166,7 +188,10 @@ def run_server(
166188 kwargs ['port' ] = port
167189
168190 # Validate / infer display mode
169- valid_display_values = ["jupyterlab" , "inline" , "external" ]
191+ if JupyterDash ._in_colab :
192+ valid_display_values = ["inline" , "external" ]
193+ else :
194+ valid_display_values = ["jupyterlab" , "inline" , "external" ]
170195
171196 if mode is None :
172197 mode = JupyterDash .default_mode
@@ -293,6 +318,21 @@ def wait_for_app():
293318
294319 wait_for_app ()
295320
321+ if JupyterDash ._in_colab :
322+ self ._display_in_colab (dashboard_url , port , mode , width , height )
323+ else :
324+ self ._display_in_jupyter (dashboard_url , port , mode , width , height )
325+
326+ def _display_in_colab (self , dashboard_url , port , mode , width , height ):
327+ from google .colab import output
328+ if mode == 'inline' :
329+ output .serve_kernel_port_as_iframe (port , width = width , height = height )
330+ elif mode == 'external' :
331+ # Display a hyperlink that can be clicked to open Dashboard
332+ print ("Dash app running on:" )
333+ output .serve_kernel_port_as_window (port , anchor_text = dashboard_url )
334+
335+ def _display_in_jupyter (self , dashboard_url , port , mode , width , height ):
296336 if mode == 'inline' :
297337 display (IFrame (dashboard_url , width , height ))
298338 elif mode == 'external' :
0 commit comments