Panel

Convert Jupyter Notebook to PDF File

Voila 不能正確 render Boken 所以應該很多 HoloViz Panel 的元件都沒辦法用 Voila 佈署。

下面這個 app 在 Jupyter 的環境下可以讓使用者上傳 notebook file 並編譯成 PDF,但因為檔案上傳的部份是用 Panel 寫的,Voila render 出來的版本就沒辦法用。用 Panel 寫檔案上傳下載比 ipywedgets 容易多了,但 Voila 無法 render

[1]:
from ipywidgets import Button, Output
from IPython.display import display
import subprocess
import panel as pn
pn.extension()

fileInput = pn.widgets.FileInput()
output = Output()
convertButton = Button(description='Convert')

def convert(b):
    with output:
        print('In convert')
        nbName = fileInput.filename
        pdfName = nbName.replace('ipynb', 'pdf')
        fileInput.save(nbName)
        subprocess.run(['jupyter', 'nbconvert', '--to', 'pdf', nbName])

convertButton.on_click(convert)


display(fileInput, convertButton, output)
[21]:
from notebook import notebookapp
from pprint import pprint
servers = list(notebookapp.list_running_servers())
pprint(servers)
[{'base_url': '/user/beginnersc-sandbox-stable-o84e6rsu/',
  'hostname': '0.0.0.0',
  'notebook_dir': '/home/jovyan',
  'password': False,
  'pid': 1,
  'port': 8888,
  'secure': False,
  'token': 'auxguyd5S9y7WWn4dIl4SA',
  'url': 'http://0.0.0.0:8888/user/beginnersc-sandbox-stable-o84e6rsu/'}]
[4]:
# from jupyter_dash import JupyterDash
# import dash_html_components as html

# JupyterDash.infer_jupyter_proxy_config()

# JupyterDash()
# JupyterDash.default_server_url

Minimum code to get server url

From JupyterDash source code. Below will work if JupyterDash is installed, but in Voila will still fail.

[1]:
import IPython
from ipykernel.comm import Comm
import time
import sys

_jupyter_config = {}
_dash_comm = Comm(target_name='jupyter_dash')

print(0)
0
[2]:
@_dash_comm.on_msg
def _receive_message(msg):
    msg_data = msg.get('content').get('data')
    msg_type = msg_data.get('type', None)
    if msg_type == 'base_url_response':
        _jupyter_config.update(msg_data)

_dash_comm.send({'type': 'base_url_request'})
print(0)
0
[2]:
# # Get shell and kernel
# shell = IPython.get_ipython()
# kernel = shell.kernel

# # Start capturing shell events to replay later
# captured_events = []

# def capture_event(stream, ident, parent):
#     captured_events.append((stream, ident, parent))

# kernel.shell_handlers['execute_request'] = capture_event

# # increment execution count to avoid collision error
# shell.execution_count += 1

# print(0)
# t0 = time.time()
# while True:
#     if (time.time() - t0) > 2:
#         # give up
#         raise EnvironmentError(
#             "Unable to communicate with the jupyter_dash notebook or JupyterLab \n"
#             "extension required to infer Jupyter configuration."
#         )
#     if bool(_jupyter_config):
#         break

#     kernel.do_one_iteration()

# print(0)
# _jupyter_config