I have some Python code that converts a notebook to some other format. That code is one async
function because I want to use a library that exposes async
functions.
I then declared an entrypoint in my package’s setup.py
to tell nbconvert about my new exporter. In the from_notebook_node()
of my exporter class I call my async conversion function like this:
with tempfile.NamedTemporaryFile() as f:
loop.run_until_complete(
asyncly_convert_notebooknotebook, f.name)
)
b = f.read()
return (b, resources)
This works. I can run jupyter-nbconvert --to=myformat notebook.ipynb
and get a converted notebook.
To make my new exporter available in the “Download as…” menu of the notebook UI I then add export_from_notebook = "MyFormat"
to my exporter class. The exporter shows up, but if you try and use it things break.
I’ve lost the exact error but I think it was RuntimeError: Cannot run the event loop while another loop is running
. The problem being that the notebook server is a tornado application, so the asyncio eventloop is already running. I can’t get a new one and tell it to run_until_complete
. This all makes sense.
I have two questions:
- in general is there a way to schedule a
asyncly_convert_notebook
coroutine to be executed in a running event loop (of tornado) and wait for the result while in a sync function (in this casefrom_notebook_node
)? - what do people do who have
async
functions that they need to call while converting a notebook and want their extension to be available as a bundler extension and in nbconvert? - is there an entrypoint I can declare in my
setup.py
to get my bundler extension enabled automagically? Right now I need to runjupyter bundlerextension enbable ...
to register a bundler extension. Is there something likenbconvert.exporters
which allows me to declare a new nbconvert exporter in my packagessetup.py
I have no idea how to do (1), but this is more a Python asyncio aficionado topic than Jupyter related.
For (2) I’ve now gone with not declaring export_from_notebook
on my exporter class and instead adding a explicit _jupyter_bundlerextension_paths()
to my module.
I am crossing my freshly washed fingers that someone has an idea