a
    ijl                     @   s   d Z ddlZddlZddlZddlZddlmZmZmZ ddl	m
Z
 ddl	mZ ddlZddlZedZeZedef Zedd	d
ZG dd dejZG dd deZG dd deZeedddZe edddZdS )zCommunication between Python and Javascript.

Could be released as a separate module once it also support non-colab notebooks.
    N)AnyCallableTypeVar)epath)epy_FnT.)returnc                   C   s
   dt jv S )z"Returns True if notebook is colab.zgoogle.colab)sysmodules r   r   ]/home/ghrups/robot-bench/.venv/lib/python3.9/site-packages/etils/ecolab/pyjs_com/py_js_com.py_is_notebook_colab)   s    r   c                   @   s:   e Zd ZdZejedddZejeddddZ	dS )	_NotebookBackendzBackend interface.)outc                 C   s   t dS )z Eventually wrap the Json output.NNotImplementedErrorselfr   r   r   r   wrap_output1   s    z_NotebookBackend.wrap_outputNfnr   c                 C   s   t dS )z1Register the function to be called in Javascript.Nr   )r   r   r   r   r   register_fn6   s    z_NotebookBackend.register_fn)
__name__
__module____qualname____doc__abcabstractmethod_Jsonr   _Fnr   r   r   r   r   r   .   s
   r   c                   @   s(   e Zd ZdZdd ZeddddZdS )_ColabzBackend for Colab.c                 C   s   t j|S N)IPythondisplayJSONr   r   r   r   r   ?   s    z_Colab.wrap_outputNr   c                 C   s   ddl m} ||j| d S )Nr   )output)Zgoogle.colabr%   Zregister_callbackr   )r   r   r%   r   r   r   r   B   s    z_Colab.register_fnr   r   r   r   r   r   r   r   r   r   r   r    <   s   r    c                   @   s(   e Zd ZdZdd ZeddddZdS )_JupyterzBackend for Jupyter notebooks.c                 C   s   |S r!   r   r   r   r   r   r   M   s    z_Jupyter.wrap_outputNr   c                    s*    fdd}t  }|jj j| d S )Nc                    s   ~ j  fdd}d S )Nc                    s0   | d d }|d i |d }  | d S )Ncontentdataargskwargs)send)msgr)   r   )commr   r   r   _recvT   s    z8_Jupyter.register_fn.<locals>.target_func.<locals>._recv)Zon_msg)r.   Zopen_msgr/   r   )r.   r   target_funcQ   s    z)_Jupyter.register_fn.<locals>.target_func)r"   get_ipythonZkernelZcomm_managerZregister_targetr   )r   r   r1   ipythonr   r0   r   r   P   s    	z_Jupyter.register_fnr&   r   r   r   r   r'   J   s   r'   r   c                    sF   t  sS t rt  nt  t fdd} | S )aV  Decorator to make a function callable from Javascript.

  Usage:

  In Python:

  ```python
  @register_js_fn
  def my_fn(*args, **kwargs):
    return {'x': 123}
  ```

  The function can then be called from Javascript:

  ```python
  # Currently has to be executed in the same cell to install the library
  IPython.display.display(IPython.display.HTML(ecolab.pyjs_import()))

  IPython.display.HTML(\"\"\"
  <script>
    async function main() {
      out = await call_python('my_fn', [1, 2], {z: 3});
      console.log(out['sum']);  // my_fn(1, 2, z=3)  == {'sum': 6}
    }
    main();
  </script>
  \"\"\")
  ```

  Note that Javascript require the `pyjs_com.js_import()` statement to be
  present in the HTML from the cell.

  Args:
    fn: The Python function, can return any json-like value or dict

  Returns:
    The Python function, unmodified
  c               
      sb   z,| i |}t |ts"d|i} |W S  ty\ } zt|  W Y d }~n
d }~0 0 d S )NZ__etils_pyjs__)
isinstancedictr   	Exception	tracebackprint_exception)r*   r+   r   ebackendr   r   r   	decorated   s    

z!register_js_fn.<locals>.decorated)r   Zis_notebookr   r    r'   	functoolswrapsr   )r   r<   r   r:   r   register_js_fn^   s    )
r?   c                  C   s   t dd } d|   dS )z1`<script></script>` to import to add in the HTML.etilszecolab/pyjs_com/py_js_com.jsz<script>z	</script>)r   resource_path	read_text)pathr   r   r   	js_import   s    rD   )r   r   r=   r	   r7   typingr   r   r   r@   r   r   r"   IPython.displayr   r   r   boolr   ABCr   r    r'   r?   	lru_cachestrrD   r   r   r   r   <module>   s&   I