U
    Zf#A                     @   sn  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
mZ d dlmZ zrd dlmZ d dlmZmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ d dlZd dlZed
dZdZW n$ e k
r   dZdZdd ZY nX ed Z!e"dddZ#e$dd dd dd fddZ%i Z&i Z'dd Z(dd Z)d"ddZ*G d d! d!Z+e+ Z,dS )#    N)Literal)make_server)get_ipython)IFramedisplay
Javascript)HTML)FormattedTB)retry)CommZdash)Ztarget_nameTFc                   C   s   d S N r   r   r   1/tmp/pip-unpacked-wheel-47crqvv_/dash/_jupyter.py<lambda>!       r   )inlineexternal
jupyterlabtab_noneerrorc                 C   sF   ddl m} | j}d}|jd k	rB|d7 }|j}|jj|jkr|S q|S )Nr   )_invoke_callback   )Zdash._callbackr   __traceback__tb_nexttb_framef_code__code__)r   r   tbskipr   r   r   	_get_skip&   s    
r!   c                 C   s   d|  S )N*r   namer   r   r   r   <   r   c                 C   s   d|  S )Nz**r   r#   r   r   r   r   =   r   c                 C   s   dt |  S )N=)repr)valuer   r   r   r   >   r   c                 C   s   |||fdd}g }	t t| D ]}
|	|| |
  q |rV|	|||||   |rt|	|||||   dd|	 d }t|dk r|S dd|	 d	 S )
z_Copied from inspect.formatargvalues, modified to place function
    arguments on separate linesc                 S   s   || |||   S r   r   )r$   locals	formatargformatvaluer   r   r   convertE   s    z(_custom_formatargvalues.<locals>.convert(z, )(   z(
    z,
    z
))rangelenappendjoin)argsvarargsvarkwr(   r)   formatvarargsformatvarkwr*   r+   specsiresultr   r   r   _custom_formatargvalues6   s    r;   c                   C   s4   t  d k	r0tjd k	r0tj td< tddi d S )NparenttypeZbase_url_request)r   
_dash_commkernel
get_parent_callersendr   r   r   r   !_send_jupyter_config_comm_request_   s    

rC   c                   C   s   t tS r   )bool_jupyter_configr   r   r   r   _jupyter_comm_response_receivedh   s    rF      c           	         s   t jd krd S t  t }|j}g   fdd}||jd< | jd7  _t }t | | krhtdt rpqt	
|jrt	 }t| ||  qP|  qP|j|jd< tj  tj   D ]$\}}}||| |||| qd S )Nc                    s     | ||f d S r   )r1   )streamidentr<   Zcaptured_eventsr   r   capture_event{   s    z._request_jupyter_config.<locals>.capture_eventexecute_requestr   zvUnable to communicate with the jupyter_dash notebook or JupyterLab 
extension required to infer Jupyter configuration.)r>   r?   rC   r   Zshell_handlersZexecution_counttimeEnvironmentErrorrF   asyncioiscoroutinefunctionZdo_one_iterationZget_event_loopnest_asyncioapplyZrun_until_completerL   sysstdoutflushstderr
set_parent)	timeoutshellr?   rK   t0ZlooprH   rI   r<   r   rJ   r   _request_jupyter_configl   s6    





r[   c                   @   s   e Zd ZU dZdZeed< ee	 Z
dZeed< i Zdd Zdd	 ZdedddZedd Zedd Zedd Zdd Zedd Zd
S )JupyterDashz;
    Interact with dash apps inside jupyter notebooks.
    r   default_modeTinline_exceptionsc                 C   s   | j r| jrdS t  dS )ar  
        Infer the current Jupyter server configuration. This will detect
        the proper request_pathname_prefix and server_url values to use when
        displaying Dash apps.Dash requests will be routed through the proxy.

        Requirements:

        In the classic notebook, this method requires the `dash` nbextension
        which should be installed automatically with the installation of the
        jupyter-dash Python package. You can see what notebook extensions are installed
        by running the following command:
            $ jupyter nbextension list

        In JupyterLab, this method requires the `@plotly/dash-jupyterlab` labextension. This
        extension should be installed automatically with the installation of the
        jupyter-dash Python package, but JupyterLab must be allowed to rebuild before
        the extension is activated (JupyterLab should automatically detect the
        extension and produce a popup dialog asking for permission to rebuild). You can
        see what JupyterLab extensions are installed by running the following command:
            $ jupyter labextension list
        N)
in_ipythonin_colabr[   )selfr   r   r   infer_jupyter_proxy_config   s    z&JupyterDash.infer_jupyter_proxy_configc                 C   s8   t  d k	| _dtjk| _tr4| jr4tr4tjdd }d S )Nzgoogle.colabc                 S   sl   t d}|r:|tj kr:tj|d d g| t d= | dd}|dd }|dkrht| d S )Nr<   headersessioncontentdatar=   Zbase_url_response)rA   getr>   r?   r@   rW   rE   update)msgZprev_parentZmsg_datamsg_typer   r   r   _receive_message   s    
 z.JupyterDash.__init__.<locals>._receive_message)r   r_   rS   modulesr`   _dep_installedr>   Zon_msg)ra   rk   r   r   r   __init__   s
    zJupyterDash.__init__N100%  	127.0.0.1r  )modec              
      s  | j rddg}ndddddg}|dkr.| j}nLt|tsVtdt| dt| n$| }||krztd	| d
| | j	f}	|	r|	
  | jf= dtkrtd dd }
n|j	dd}
|
dk	r|
jd}
nd}
t|jd|
 |dkrJdtkrtd d}n.tj	dd}|r8d| }nd d }n
|d}| |
 }zddl}W n tk
r   Y nX t t|jdddtdtj tddddfdd}tj|d}d|_ |!  | jf< d d d t"j# fd!d" tdd#dd fd$d%}z8|  | j r^t"$|||| nt"%|||| W nJ t&k
r } z*t|}|'d&rt(t)| n|W 5 d}~X Y nX dS )'a  
        :type app: dash.Dash
        :param mode: How to display the app on the notebook. One Of:
            ``"external"``: The URL of the app will be displayed in the notebook
                output cell. Clicking this URL will open the app in the default
                web browser.
            ``"inline"``: The app will be displayed inline in the notebook output cell
                in an iframe.
            ``"jupyterlab"``: The app will be displayed in a dedicate tab in the
                JupyterLab interface. Requires JupyterLab and the `jupyterlab-dash`
                extension.
        :param width: Width of app when displayed using mode="inline"
        :param height: Height of app when displayed using mode="inline"
        :param host: Host of the server
        :param port: Port used by the server
        :param server_url: Use if a custom url is required to display the app.
        r   r   r   r   r   Nz>The mode argument must be a string
    Received value of type z: zInvalid display argument z
    Valid arguments: Zbase_subpath/z/proxy/{port}/requests_pathname_prefix)port
server_urlZDASH_DOMAIN_BASEzhttps://http://:r   T)ZthreadedZ	processesZwerkzeug   d   i  )stop_max_attempt_numberwait_exponential_multiplierwait_exponential_maxc               
      sT   z   W nB tk
r    Y n0 tk
rN }  z |  | W 5 d } ~ X Y nX d S r   )serve_forever
SystemExit	Exceptionputr   )err_qserverr   r   runO  s    
z JupyterDash.run_app.<locals>.run)targetz/_alive_c                     s0   z   } | r| W n tjk
r*   Y nX d S r   )
get_nowaitqueueEmpty)err)r   r   r   
_get_errorf  s    z'JupyterDash.run_app.<locals>._get_error
   c               
      s      zRt } | j }| jdkr.t||dkrVd d }td| dW n. t jk
r } z   |W 5 d }~X Y nX d S )N   Aliverx   ry   z	Address 'zA' already in use.
    Try passing a different port to run_server.)requestsrg   re   decodestatus_coder   OSErrorConnectionError)reqresurlr   )r   	alive_urlhostrv   r   r   wait_for_appo  s    



z)JupyterDash.run_app.<locals>.wait_for_appz<!)*r`   r]   
isinstancestr
ValueErrorr=   r&   lower_serversrg   shutdownrE   rstripconfigformatdict__setitem__osenvironorjsonImportErrorr   Queuer   r   logging	getLoggersetLevelERRORr
   	threadingThreaddaemonstartr\   alive_token_display_in_colab_display_in_jupyterr   
startswithr   r   )ra   apprs   widthheightr   rv   rw   Zvalid_display_valuesZ
old_serverru   Zdomain_basedashboard_urlr   r   threadr   Zfinal_errorri   r   )r   r   r   r   rv   r   r   run_app   s    

  



		    zJupyterDash.run_appc                 C   sH   ddl m} |dkr&|j|||d n|dkrDtd |j|| d d S )Nr   )outputr   )r   r   r   zDash app running on:)Zanchor_text)Zgoogle.colabr   Zserve_kernel_port_as_iframeprintZserve_kernel_port_as_window)r   rv   rs   r   r   r   r   r   r   r     s    zJupyterDash._display_in_colabc                 C   sl   |dkrt t| || nN|dkrNtd|   |dkrht td|  d n|dkrhtd|| d	 d S )
Nr   )r   r   zDash app running on r   zwindow.open('z')r   show)r=   rv   r   )r   r   r   r   r>   rB   )r   rv   rs   r   r   r   r   r   r     s    zJupyterDash._display_in_jupyterc                   C   s   dS )Nr   r   r   r   r   r   serve_alive  s    zJupyterDash.serve_alivec                    s   |j t fdd}dS )z(Install traceback handling for callbacksc                    sh    rt | nd}tj}tt_z$t }t|ddd|d}|  W 5 |t_X | }jr`t	| |dfS )Nr   VerboseZNoColorT)Z	tb_offsetrs   Zcolor_schemeZinclude_varsostreami  )
r!   inspectformatargvaluesr;   ioStringIOr	   getvaluer^   r   )r   r    Zoriginal_formatargvaluesr   ZipytbZ
stacktracedev_tools_prune_errorsra   r   r   _wrap_errors  s$    
zGJupyterDash.configure_callback_exception_handling.<locals>._wrap_errorsN)r   Zerrorhandlerr   )ra   r   r   r   r   r   r   %configure_callback_exception_handling  s    
z1JupyterDash.configure_callback_exception_handlingc                 C   s    dt jk}to| o| jp| jS )NZDATABRICKS_RUNTIME_VERSION)r   r   rm   r_   r`   )ra   Z_inside_dbxr   r   r   active  s    
zJupyterDash.active)Nro   rp   rq   rr   N)__name__
__module____qualname____doc__r]   JupyterDisplayMode__annotations__r   uuidZuuid4r   r^   rD   r   rb   rn   r   staticmethodr   r   r   r   propertyr   r   r   r   r   r\      s4   
       3


"r\   )rG   )-rO   r   r   r   r   r   r   rS   r   rM   Ztyping_extensionsr   Zwerkzeug.servingr   ZIPythonr   ZIPython.displayr   r   r   ZIPython.core.displayr   ZIPython.core.ultratbr	   retryingr
   Zipykernel.commr   rQ   r   r>   rm   r   r   r   r!   r   r;   rE   rA   rC   rF   r[   r\   Zjupyter_dashr   r   r   r   <module>   sT   

$	
<  =