# How to transform a jupyter notebook into a webapp?

**URL:** <https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758>\
**Category:** General\
**Created:** [April 10, 2019, 1:25pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758 "2019-04-10T13:25:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mario.pezzoni](https://avatars.discourse-cdn.com/v4/letter/m/ac8455/32.png) [@mario.pezzoni](https://discourse.jupyter.org/u/mario.pezzoni)\
**Post date:** [April 10, 2019, 1:25pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/1 "2019-04-10T13:25:11Z")

</div>

Hello,

I developed an handful of jupyter notebooks to solve a set of small problems. All have the same workflow: upload data, compute something, show a nice report with plots.  
I want to share these “tools” with non-technical people so I’d like to streamline a bit the interface (no editing, a nice “start button”, ecc).

What is the preferred way to achieve that? Do you have any advice?

Best regards,  
Mario.

---

<div class="post-metadata">

**Author:** ![fomightez](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/fomightez/32/495_2.png) [@fomightez](https://discourse.jupyter.org/u/fomightez)\
**Post date:** [April 10, 2019, 3:05pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/2 "2019-04-10T15:05:13Z")

</div>

Hi Mario,

The second two issues can be solved with appmode and ipywidgets. Or possibly even [Jupyter book](https://jupyter.org/jupyter-book/intro.html).

### Examples

> **[binder-examples/appmode](https://github.com/binder-examples/appmode)**
>
> Creating web applications with Jupyter and Binder. Contribute to binder-examples/appmode development by creating an account on GitHub.

  

> **[choldgraf/pisim](https://github.com/choldgraf/pisim)**
>
> A tiny notebook to simulate PI. Contribute to choldgraf/pisim development by creating an account on GitHub.

  
[https://hub.mybinder.org/user/gwastro-gwapps-37r8r8mg/apps/gw150914.ipynb](https://hub.mybinder.org/user/gwastro-gwapps-37r8r8mg/apps/gw150914.ipynb)

For example of features for Jupyter Book start [here](https://jupyter.org/jupyter-book/intro.html).

### The documentation on the underlying resources

> **[oschuett/appmode](https://github.com/oschuett/appmode)**
>
> A Jupyter extensions that turns notebooks into web applications. - oschuett/appmode

  
[https://ipywidgets.readthedocs.io/en/stable/index.html](https://ipywidgets.readthedocs.io/en/stable/index.html)  
[https://jupyter.org/jupyter-book/intro.html](https://jupyter.org/jupyter-book/intro.html)

I don’t yet know a good way to handle the first part because presumably you want them to be able to add their own data. Maybe you could have related example data already be there and have a link documenting how to upload and get back to appmode? Or if this is stuff that they can put into a cell and then you can trigger processing via Jupyter Book?

Wayne

---

<div class="post-metadata">

**Author:** ![betatim](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/betatim/32/10_2.png) [@betatim](https://discourse.jupyter.org/u/betatim)\
**Post date:** [April 10, 2019, 3:11pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/3 "2019-04-10T15:11:22Z")

</div>

> [@fomightez](#):
>
> I don’t yet know a good way to handle the first part because presumably you want them to be able to add their own data.

I think there are widgets/libraries that let you have a “Upload a file” button as part of your notebook. It has been a long time since I used any of them and neither really knocked my socks of when I did :-/

- [GitHub - peteut/ipython-file-upload: IPython file upload widget. Now obsolete, refer to widgets.https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html#File-Upload](https://github.com/peteut/ipython-file-upload)
- [A file selection class build for ipywidgets without any extra dependencies. · GitHub](https://gist.github.com/DrDub/6efba6e522302e43d055)

---

<div class="post-metadata">

**Author:** ![jtp](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jtp/32/19100_2.png) [@jtp](https://discourse.jupyter.org/u/jtp)\
**Post date:** [April 10, 2019, 10:06pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/4 "2019-04-10T22:06:37Z")

</div>

There is also a discussion about a FileUpload widget here: [https://github.com/jupyter-widgets/ipywidgets/issues/1542](https://github.com/jupyter-widgets/ipywidgets/issues/1542)  
And the `ipyupload` package which is already pip installable: [https://gitlab.com/oscar6echo/ipyupload](https://gitlab.com/oscar6echo/ipyupload)

---

<div class="post-metadata">

**Author:** ![mario.pezzoni](https://avatars.discourse-cdn.com/v4/letter/m/ac8455/32.png) [@mario.pezzoni](https://discourse.jupyter.org/u/mario.pezzoni)\
**Post date:** [April 11, 2019, 10:25am UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/5 "2019-04-11T10:25:28Z")

</div>

Thank you for you answers, I was not aware of those projects!

The data upload seems to be the main issue. Maybe I am trying to achieve something not really suited for jupyter? In the end I am giving up the Read-Eval-Print-Loop pattern. What if I am willing to rewrite my tools outside jupyter? Is there a way to keep using the same libraries (numpy, holoviews, bokeh, ecc) to create a usable application for non technical users?

---

<div class="post-metadata">

**Author:** ![fomightez](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/fomightez/32/495_2.png) [@fomightez](https://discourse.jupyter.org/u/fomightez)\
**Post date:** [April 11, 2019, 4:14pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/6 "2019-04-11T16:14:42Z")

</div>

There are definitely options outside of Jupyter if you are willing to give up the Read-Eval-Print-Loop pattern, as it sounds like you are.

You could just write a python script that people put alongside their data. You can generate a report other ways and that generation can be part of the script. The main way I have used in the past is via ReportLab because it can do everything and make composited PDFs. But you can go simpler by using Matplotlib and annotation or PIL to control placing the parts of your report.  
Or if you want you can make the output go to Plotly I believe. Where the ‘report’ could be a webpage with the resulting plots if that works. I have old example code with composting with ReportLab [here](https://github.com/fomightez/mini-pipelines/blob/8431f32b1960994c2320b84750968ff6e94d94a8/generate_reports_for_genome_and_all_chromosomes_various_samples.py).

Although it doesn’t have the report making aspect, the first part of this notebook I have [here](https://nbviewer.jupyter.org/github/fomightez/cl_sq_demo-binder/blob/master/notebooks/demo%20plot_expression_across_chromosomes.ipynb) sort of illustrates putting data alongside a script with sample data and then suggest user to add their data. The goal is just to really get users pointing the script `plot_expression_across_chromosomes.py` at their data and then they get a plot. The overarching script is stored in a different repo and obtained in the preparation steps. (However, that particular script I haven’t overhauled to my current, clearer coding style. So if you need a model, I’d suggest the one named ‘nucleotide\_difference\_imbalance\_plot\_stylized\_like\_Figure\_8\_of\_Morrill\_et\_al\_2016.py’ available [here](https://github.com/fomightez/sequencework/tree/master/plot_nt_imbalance); the blurb about it at that page tells you how you can run the [demo page](https://nbviewer.jupyter.org/github/fomightez/cl_sq_demo-binder/blob/master/notebooks/Demo%20of%20script%20to%20plot%20nt%20imbalance%20for%20sequence%20span.ipynb) via MyBinder.)

That type of combination can also be dockerized so they would just need to place their data in a directory that you then tell them how to attach to a Docker container and then trigger the processing with a single command. This example [here](https://angus.readthedocs.io/en/2016/week3/CTB_docker.html) builds to something like that while teaching about Docker. I say ‘something like that’ because the software triggered isn’t a Python script as far as I know but the idea is the same.

As for giving people a place to put their data with your code, you can go even fancier and make an actual Python-based web app using Django or Flask. Because it is Python, you can use thePython modules that you have mentioned. I have done this on PythonAnywhere with some really simple items before I discovered Jupyter and the MyBinder combination, for examples see [http://fomightez.pythonanywhere.com/ammonium\_screen/](http://fomightez.pythonanywhere.com/ammonium_screen/) or [http://fomightez.pythonanywhere.com/spartan\_fixer/](http://fomightez.pythonanywhere.com/spartan_fixer/) . However, that adds overhead of learning another ecosystem and adds hosting fees if you are allowing people to process a lot of data. Jupyter allows much more complex interaction between users and your code though without focusing on the overhead of web development. In fact I never quite got around to implementing the upload part and was just working with web forms at the time, as you’ll see if you look at my examples being served from PythonAnywhere.

---

<div class="post-metadata">

**Author:** ![hhuuggoo](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/hhuuggoo/32/242_2.png) [@hhuuggoo](https://discourse.jupyter.org/u/hhuuggoo)\
**Post date:** [April 13, 2019, 1:48pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/7 "2019-04-13T13:48:35Z")

</div>

Does app mode still require containerization for security? Put another way, does app mode allow for arbitrary code execution?

Thanks!

---

<div class="post-metadata">

**Author:** ![choldgraf](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/choldgraf/32/1264_2.png) [@choldgraf](https://discourse.jupyter.org/u/choldgraf)\
**Post date:** [April 13, 2019, 6:45pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/8 "2019-04-13T18:45:27Z")

</div>

We just had a moment to chat with the QuantStack team about a project they’re working on called Voila ([https://github.com/quantstack/voila](https://github.com/quantstack/voila)). It sounds like it’s a good solution for this use-case! @SylvainCorlay could explain more but this is definitely worth checking out.

---

<div class="post-metadata">

**Author:** ![jhermann](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/jhermann/32/257_2.png) [@jhermann](https://discourse.jupyter.org/u/jhermann)\
**Post date:** [April 13, 2019, 8:49pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/9 "2019-04-13T20:49:55Z")

</div>

Another option that just emerged: [https://github.com/bentoml/BentoML](https://github.com/bentoml/BentoML)

Use their webservice wrapping and put a shiny JavaScript webapp before that.

---

<div class="post-metadata">

**Author:** ![betatim](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/betatim/32/10_2.png) [@betatim](https://discourse.jupyter.org/u/betatim)\
**Post date:** [April 14, 2019, 5:57am UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/10 "2019-04-14T05:57:13Z")

</div>

> [@hhuuggoo](#):
>
> Does app mode still require containerization for security? Put another way, does app mode allow for arbitrary code execution?

[appmode](https://github.com/oschuett/appmode) is a notebook extension that changes what the UI looks like. This means there is still a full blown server (and kernel) connected to the notebook, which means users can continue to run their own code (if they can figure out how to switch to “edit mode” in appmode)

Something like [voila](https://github.com/QuantStack/voila) (mentioned by Chris) is better in this case as it actually disables/doesn’t implement some parts of the kernel communications protocol which means that users can’t send code to the kernel. Quick demo: [Binder](https://mybinder.org/v2/gh/QuantStack/voila/stable?urlpath=voila/tree/notebooks)

---

<div class="post-metadata">

**Author:** ![hhuuggoo](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/hhuuggoo/32/242_2.png) [@hhuuggoo](https://discourse.jupyter.org/u/hhuuggoo)\
**Post date:** [April 14, 2019, 5:55pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/11 "2019-04-14T17:55:10Z")

</div>

Voila looks great. Thanks!

---

<div class="post-metadata">

**Author:** ![tsekou](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/tsekou/32/1367_2.png) [@tsekou](https://discourse.jupyter.org/u/tsekou)\
**Post date:** [December 6, 2019, 6:43pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/12 "2019-12-06T18:43:39Z")

</div>

Hello, I am a newbie in data science and webapps, and i also, search for a way to transform a jupyter notebook into a webapp. I found appmode very interesting and easy but i really can not understand if with appmode i could have a real webapp or appmode runs only in local mode? Could you please help me understand what is the choice for me?

---

<div class="post-metadata">

**Author:** ![fomightez](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/fomightez/32/495_2.png) [@fomightez](https://discourse.jupyter.org/u/fomightez)\
**Post date:** [December 6, 2019, 6:52pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/13 "2019-12-06T18:52:01Z")

</div>

Via the Binder system you can share your appmode-creation publicly. You would need a repository that will work but that is the only limitation. The demo you get from pressing `launch binder` [https://github.com/binder-examples/appmode](https://github.com/binder-examples/appmode) is available via that service. So imagine using that as a template then replacing the pertinent code at [https://github.com/binder-examples/appmode](https://github.com/binder-examples/appmode) with your content and making sure links point at right place and you’d have a public app.

I’ll add that on Github, that can all be done in the browser interface of Github with no need to use git on local computer or ever clone to local. The `postBuild` file in that repository is only concerned with fetching data for the ipyvolume demo, and so it doesn’t need to be included/edited. Because `postBuild` is an executable file type, I’ve found you cannot edit it via the browser interface of Github or permissions get messed up in the resulting image build. If you did need to edit or include a `start` or `postBuild` file, you wouldn’t be able to only alter the repo contents via the Github web browser interface.

---

<div class="post-metadata">

**Author:** ![yonatan](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/yonatan/32/2871_2.png) [@yonatan](https://discourse.jupyter.org/u/yonatan)\
**Post date:** [October 12, 2020, 8:57am UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/14 "2020-10-12T08:57:40Z")

</div>

[Jupyter book updated their link](https://jupyterbook.org/intro.html)

---

<div class="post-metadata">

**Author:** ![fomightez](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/fomightez/32/495_2.png) [@fomightez](https://discourse.jupyter.org/u/fomightez)\
**Post date:** [October 12, 2020, 4:55pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/15 "2020-10-12T16:55:11Z")

</div>

Thanks, @yonatan. Unfortunately, I note that discourse doesn’t allow me to update that post anymore.

I will add, because I saw earlier in this thread that I had expressed not having an example to point to for having worked out file uploads beyond the one example in the Binder Gallery of [rendering an STL file](https://github.com/voila-gallery/render-stl), that now I did eventually figure out coding in general file uploading and subsequent use of that file for Voila. (Well at least single files.) Folks looking for more on that can see the links [here](https://discourse.jupyter.org/t/voila-usecase-when-waiting-on-user-input/4901/2).

---

<div class="post-metadata">

**Author:** ![pplonski](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/pplonski/32/5651_2.png) [@pplonski](https://discourse.jupyter.org/u/pplonski)\
**Post date:** [January 26, 2022, 3:39pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/16 "2022-01-26T15:39:32Z")

</div>

Hi @mario.pezzoni,

I’ve created an open-source framework called [Mercury](https://github.com/mljar/mercury) for easy sharing of Jupyter Notebooks.

With Mercury you can convert your notebook to web app by adding a YAML config in the first RAW cell. What is more, you can share many notebooks in it, because it has an app gallery built-in. You can also decide to show or hide your code.

Below screenshots from Mercury:

 ![mercury_share_multiple_notebooks](https://canada1.discourse-cdn.com/flex031/uploads/jupyter/original/2X/7/78c2bfcf7bd17e8d3351873d55c8d7264216880a.png)

 ![mercury_screenshot_1](https://canada1.discourse-cdn.com/flex031/uploads/jupyter/original/2X/f/f9df6c9306532d8e7cb3fcb7ad36d203ed6485d9.png)

 ![mercury_screenshot_2](https://canada1.discourse-cdn.com/flex031/uploads/jupyter/original/2X/8/8550b3aa5ab816f13fe3a7c4841845ef9cb26c1c.png)

Mercury is open-source with code at [GitHub - mljar/mercury: Mercury: easily convert Python notebook to web app and share with others](https://github.com/mljar/mercury)

If you have more questions or need help, please let me know! 🙂

---

<div class="post-metadata">

**Author:** ![bollwyvl](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/bollwyvl/32/904_2.png) [@bollwyvl](https://discourse.jupyter.org/u/bollwyvl)\
**Post date:** [January 26, 2022, 4:11pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/17 "2022-01-26T16:11:18Z")

</div>

> _Mercury is open-source_

I think every time you rep mercury as open source, it’s probably wise to point out

> _Mercury is either open source under the AGPL, or available as a commercial license on request_

I am neither a lawyer, nor anti-AGPL, but would like to point out the rest of the stack it sits upon (django, jupyter) are downstream-friendly BSD-3-Clause for the _express purpose_ that others _can_ build new stuff on it without having to worry about their work being bound. AGPL is _very_ sticky, and would almost certainly (again, IANAL) cover user content, which is not going to be very attractive to anybody to use in production, even for non-commerical interests.

---

<div class="post-metadata">

**Author:** ![pplonski](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/pplonski/32/5651_2.png) [@pplonski](https://discourse.jupyter.org/u/pplonski)\
**Post date:** [January 27, 2022, 3:43pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/18 "2022-01-27T15:43:48Z")

</div>

Thank you @bollwyvl. You are right, Mercury is dual licensed. It has AGPLv3 license and commercial license. I decided to go this path, to provide long support for the project.

---

<div class="post-metadata">

**Author:** ![krassowski](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/krassowski/32/1685_2.png) [@krassowski](https://discourse.jupyter.org/u/krassowski)\
**Post date:** [January 28, 2022, 12:10am UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/19 "2022-01-28T00:10:06Z")

</div>

Nice use of nbconvert. Will it render [jupyter widgets](https://github.com/jupyter-widgets/ipywidgets) like [voila](https://github.com/voila-dashboards/voila) does?

Taking a quick glance at [mercury/tasks.py at 70713b3ea37dcb31443b98e35c51c6e7d2f941c2 · mljar/mercury · GitHub](https://github.com/mljar/mercury/blob/70713b3ea37dcb31443b98e35c51c6e7d2f941c2/mercury/apps/notebooks/tasks.py#L39-L61) did you consider using `jupyter kernelspec list --json`? It could save you some parsing 🙂

---

<div class="post-metadata">

**Author:** ![pplonski](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/pplonski/32/5651_2.png) [@pplonski](https://discourse.jupyter.org/u/pplonski)\
**Post date:** [January 29, 2022, 6:56pm UTC](https://discourse.jupyter.org/t/how-to-transform-a-jupyter-notebook-into-a-webapp/758/20 "2022-01-29T18:56:43Z")

</div>

@krassowski thank you! It cant handle ipywidgets right now. It just collect the input and execute the notebook. The process of notebook transformation is simple as adding YAML config.

In the future I would like to support notebook scheduling and notebook as REST API conversion.

Thank you for a tip!
