<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Jupyter Blog - Sylvain Corlay</title><link href="https://jupyter.org/blog/" rel="alternate"/><link href="https://jupyter.org/blog/feeds/author-sylvain-corlay.atom.xml" rel="self"/><id>https://jupyter.org/blog/</id><updated>2026-02-19T12:26:00+00:00</updated><subtitle>The Project Jupyter blog: news, releases, and community stories, archived from blog.jupyter.org.</subtitle><entry><title>JupyterLite Officially Joins Project Jupyter!</title><link href="https://jupyter.org/blog/posts/2026/jupyterlite-officially-joins-project-jupyter/" rel="alternate"/><published>2026-02-12T16:14:00+00:00</published><updated>2026-02-19T12:26:00+00:00</updated><author><name>Jeremy Tuloup</name></author><id>tag:jupyter.org,2026-02-12:/blog/posts/2026/jupyterlite-officially-joins-project-jupyter/</id><summary type="html">&lt;p&gt;We are thrilled to announce that JupyterLite is now an official part of Project Jupyter. This milestone marks a significant step forward for interactive computing in the browser and strengthens JupyterLite’s role within the Jupyter ecosystem.&lt;/p&gt;</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2026/jupyterlite-officially-joins-project-jupyter/images/001-1_1mHVBUr6tB3TP0Z1ujvdjw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;We are thrilled to announce that JupyterLite is now an official part of Project Jupyter. This milestone marks a significant step forward for interactive computing in the browser and strengthens JupyterLite’s role within the Jupyter ecosystem.&lt;/p&gt;
&lt;h2 id="what-is-jupyterlite"&gt;What is JupyterLite?&lt;/h2&gt;
&lt;p&gt;JupyterLite is a JupyterLab distribution that runs entirely in your web browser. Kernels execute directly in the browser using WebAssembly, eliminating the need for an application server. This means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Instant access&lt;/strong&gt;: Start computing with a single click: no prior Python setup, environment configuration, or server management required.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: Host thousands of concurrent users from a static website (e.g., GitHub Pages) with zero per-user server costs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privacy and portability&lt;/strong&gt;: Code and data remain in the user’s browser, making it ideal for embedding in documentation, tutorials, and interactive demos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;JupyterLite greatly expands the options available in the Jupyter ecosystem for &lt;strong&gt;education&lt;/strong&gt;, &lt;strong&gt;documentation&lt;/strong&gt;, and &lt;strong&gt;demos&lt;/strong&gt;, where reducing friction is critical.&lt;/p&gt;
&lt;p&gt;As Brian Granger reminded us during his &lt;a href="https://youtu.be/IJO7_v7GEVc?si=8_0bMM39ci_QulYb&amp;amp;t=337"&gt;JupyterCon 2025 keynote&lt;/a&gt;, Jupyter’s mission is “to empower people of all backgrounds to think, collaborate, and share knowledge using computational storytelling.” From this perspective, JupyterLite is a logical and key next step to take, letting Jupyter take advantage of the impressive strides made in recent years by the WebAssembly/JavaScript ecosystem (in reach and capability) to advance this mission. JupyterLite is an excellent complement to other forms of accessing Jupyter (whether through a local Python installation or a hosted infrastructure service), that facilitates new use cases and lowers barriers in many others.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Screencast of JupyterLite in action, showing a live jupyter notebook with widgets and data visualisation." src="https://jupyter.org/blog/posts/2026/jupyterlite-officially-joins-project-jupyter/images/002-1_OEJksEVfQVZugt_d6EYXBQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Interactive computing in the browser with JupyterLite&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="the-journey-of-jupyterlite"&gt;The Journey of JupyterLite&lt;/h2&gt;
&lt;p&gt;JupyterLite’s development began in 2021, led by &lt;strong&gt;Jeremy Tuloup&lt;/strong&gt; at &lt;strong&gt;QuantStack&lt;/strong&gt;. Over the past four years, it has benefited from the dedication of several other team members, Martin Renou, Trung Le, and Ian Thomas — as well as invaluable contributions from &lt;strong&gt;community members&lt;/strong&gt; like Nick Bollweg and many others.&lt;/p&gt;
&lt;p&gt;Beyond the JupyterLite repository, the project includes &lt;strong&gt;comprehensive tooling&lt;/strong&gt; for creating in-browser language kernels based on &lt;strong&gt;xeus&lt;/strong&gt;. These kernels support languages like &lt;strong&gt;Python&lt;/strong&gt;, &lt;strong&gt;R&lt;/strong&gt;, &lt;strong&gt;C++&lt;/strong&gt;, &lt;strong&gt;GNU Octave&lt;/strong&gt;, &lt;strong&gt;Lua&lt;/strong&gt;, and &lt;strong&gt;SQLite&lt;/strong&gt;, sharing the same codebase as their backend counterparts, developed by Thorsten Beier, Isabel Paredes, Johan Mabille, and Antoine Prouvost. These kernels are built upon the &lt;strong&gt;emscripten-forge&lt;/strong&gt; software distribution for WebAssembly. The project also includes a Python kernel based on &lt;strong&gt;Pyodide&lt;/strong&gt;, and kernels for JavaScript and &lt;a href="https://p5js.org/"&gt;p5.js&lt;/a&gt;. This architecture means that the same language-agnostic model for kernels that Jupyter pioneered over a decade ago, carries over to the WebAssembly world.&lt;/p&gt;
&lt;p&gt;The JupyterLite GitHub organization also features the &lt;strong&gt;JupyterLite Terminal&lt;/strong&gt;, a terminal and shell emulator that runs entirely in the browser and was developed by Ian Thomas. It enables the use of basic Unix commands like &lt;strong&gt;grep&lt;/strong&gt;, &lt;strong&gt;sed&lt;/strong&gt;, &lt;strong&gt;cat&lt;/strong&gt;, &lt;strong&gt;touch&lt;/strong&gt;, and even &lt;strong&gt;vim&lt;/strong&gt; or &lt;strong&gt;nano&lt;/strong&gt;, all built to WebAssembly.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Screenshot of the JupyterLite terminal emulator, showing some basic Unix commands" src="https://jupyter.org/blog/posts/2026/jupyterlite-officially-joins-project-jupyter/images/003-1_8hPGoJK8chK2uEVlL9ig9Q.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterLite terminal emulator, with basic Unix commands&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;JupyterLite now powers the &lt;strong&gt;official Jupyter website&lt;/strong&gt; and is used by projects like &lt;strong&gt;numpy.org&lt;/strong&gt;, &lt;strong&gt;sympy.org&lt;/strong&gt;. It also underlies services such as &lt;a href="https://www.jupytereverywhere.org/"&gt;&lt;strong&gt;Jupyter Everywhere&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://notebook.link/"&gt;&lt;strong&gt;notebook.link&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="a-natural-fit-with-jupyterlab"&gt;A Natural Fit with JupyterLab&lt;/h2&gt;
&lt;p&gt;JupyterLite has always been closely tied to JupyterLab. It is increasingly becoming a set of JupyterLab extensions that replace core plugins to manage kernels, settings, and content in the browser. With contributors overlapping significantly with the Jupyter Frontends group, this integration formalizes what many in the community already recognized: JupyterLite is a core part of the Jupyter ecosystem.&lt;/p&gt;
&lt;p&gt;The proposal to transfer JupyterLite to the Jupyter governance received strong support from the Jupyter community and by the &lt;a href="https://github.com/jupyterlab/frontends-team-compass/issues/290"&gt;Jupyter Frontends council&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="better-integration-with-the-rest-of-jupyter"&gt;Better integration with the rest of Jupyter&lt;/h2&gt;
&lt;p&gt;With JupyterLite now being an official part of Jupyter, it will be easier to find areas for better integration with other aspects of our ecosystem: we can reduce duplication, smooth out the documentation and model for creating and using both “traditional” (server-hosted) and WebAssembly kernels, and make JupyterLite a natural instant-access component of &lt;a href="https://mystmd.org/guide/in-page-execution#jupyterlite"&gt;MyST/JupyterBook-based sites&lt;/a&gt;, and more.&lt;/p&gt;
&lt;p&gt;Mission-wise, JupyterLite is a natural next step for Jupyter, and having it be an official part of the project makes it much easier for the community to integrate its benefits throughout. We hope you’ll try it, use it and contribute to its growth!&lt;/p&gt;
&lt;h2 id="try-it-in-your-browser"&gt;Try it in your browser&lt;/h2&gt;
&lt;p&gt;If you would like to try JupyterLite in your browser, click on the following link:&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://jupyter.org/try-jupyter/"&gt;&lt;img src="https://jupyter.org/blog/posts/2026/jupyterlite-officially-joins-project-jupyter/images/004-1_EUSdzza6CGF6EA195jkzCA.webp" alt="Try lite now." loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="acknowledgments-and-team-credits"&gt;Acknowledgments and team credits&lt;/h2&gt;
&lt;p&gt;JupyterLite’s success is thanks to the support of &lt;strong&gt;individuals and organizations&lt;/strong&gt; who believed in its vision. This includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;, for their continued investment in the project since 2021 and the broader Jupyter ecosystem,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;, for funding improvements to JupyterLite by QuantStack since 2023,&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Gates Foundation&lt;/strong&gt;, for funding the development of the xeus-R kernel and its port to WebAssembly,&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Pyodide&lt;/strong&gt; project, whose pioneering work on Python in the browser via WebAssembly made JupyterLite possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Key developers to this stack include:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Jeremy Tuloup&lt;/strong&gt; (Director at QuantStack, creator of JupyterLite, and JupyterLab maintainer),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nicholas Bollweg&lt;/strong&gt; (JupyterLite maintainer and #2 all-time committer),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Martin Renou&lt;/strong&gt; (Director at QuantStack, JupyterLite maintainer, responsible for integrating xeus with emscripten-forge, and creator of JupyterLite-Sphinx),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Thorsten Beier&lt;/strong&gt; (Software developer at QuantStack, lead developer of emscripten-forge, and xeus-lite),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Isabel Paredes&lt;/strong&gt; (Software developer at QuantStack, led the packaging of R and GNU Octave in Emscripten-forge),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anutosh Bhat&lt;/strong&gt; (Software developer at QuantStack, C++ kernel in the browser),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ian Thomas&lt;/strong&gt; (Software developer at QuantStack, creator of the JupyterLite terminal, and the cockle shell emulator),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Johan Mabille&lt;/strong&gt; (Director at QuantStack, creator of xeus),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agriya Khetarpal&lt;/strong&gt; (Pyodide contributor, JupyterLite-Sphinx maintainer),&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Albert Steppi&lt;/strong&gt; (JupyterLite-Sphinx maintainer).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thank you for being part of this journey, we cannot wait to see what you build with JupyterLite!&lt;/p&gt;
</content><category term="education"/><category term="JupyterLite"/><category term="WebAssembly"/></entry><entry><title>ipydatagrid is now part of Project Jupyter</title><link href="https://jupyter.org/blog/posts/2024/ipydatagrid-is-now-part-of-project-jupyter/" rel="alternate"/><published>2024-08-22T15:01:00+00:00</published><updated>2024-08-22T15:01:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2024-08-22:/blog/posts/2024/ipydatagrid-is-now-part-of-project-jupyter/</id><summary type="html">&lt;p&gt;Today, we are proud to announce that the ipydatagrid open source project has been incorporated into Project Jupyter as part of the Jupyter Widgets subproject.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Today, we are proud to announce that the &lt;a href="https://github.com/jupyter-widgets/ipydatagrid"&gt;ipydatagrid&lt;/a&gt; open source project has been incorporated into Project Jupyter as part of the Jupyter Widgets subproject.&lt;/p&gt;
&lt;h2 id="what-is-ipydatagrid"&gt;What is ipydatagrid?&lt;/h2&gt;
&lt;p&gt;ipydatagrid is a fast data grid widget for Jupyter Notebooks and JupyterLab. Since its inception in 2019, it has been developed as an open source project in Bloomberg’s GitHub organization.&lt;/p&gt;
&lt;p&gt;It offers a high-performance fully-featured DataGrid interface, fully integrated with ipywidgets. Built upon the Lumino datagrid, which also powers the JupyterLab CSV viewer, ipydatagrid provides users with a robust and versatile tool for data visualization and manipulation.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2024/ipydatagrid-is-now-part-of-project-jupyter/images/001-0_9xQd6YxFsBDFPyxw.mp4" alt="Screencast of ipydatagrid in action, showcasing multiple cell renderers with conditional rendering, and filtering of data." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;h2 id="key-features"&gt;Key Features&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Users can customize the way data is represented in their grid using a variety of renderers.&lt;/strong&gt;&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2024/ipydatagrid-is-now-part-of-project-jupyter/images/002-0_bNrtqVrcwR1dpX9O.mp4" alt="Screencast of ipydatagrid showcasing advanced rendering capabilities." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ipydatagrid includes a sophisticated selection model with two-way data binding.&lt;/strong&gt;&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2024/ipydatagrid-is-now-part-of-project-jupyter/images/003-0_wKlCImr0LtGDpeDz.mp4" alt="Screencast of ipydatagrid showcasing the advanced selection model with bi-directional bindings." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It enables conditional formatting powered by &lt;a href="https://vega.github.io/vega/docs/expressions/"&gt;Vega Expressions&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2024/ipydatagrid-is-now-part-of-project-jupyter/images/004-0_U5H7uyoSLf0pZm6q.webp" alt="Screenshot of ipydatagrid showcasing the use of Vega expression for conditional formatting." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;h2 id="the-transfer-to-project-jupyter"&gt;The transfer to Project Jupyter&lt;/h2&gt;
&lt;p&gt;We would like to extend our gratitude to the developers and contributors who have significantly improved the ipydatagrid project over the years: Itay Dafna, Martin Renou, Mehmet Bektas, Kaia Young, Bernát Gábor, Vasilis Themelis, Supriya K., Greg Mooney, Ian Thomas, Olly Hensby, and John Gunstone. Special thanks to Chris Colbert, the creator of the Lumino Datagrid, which forms the foundation of ipydatagrid’s front-end.&lt;/p&gt;
&lt;h2 id="bloombergs-contribution-to-project-jupyter"&gt;Bloomberg’s contribution to Project Jupyter&lt;/h2&gt;
&lt;p&gt;The transfer of ipydatagrid to Project Jupyter is just one of many contributions that Bloomberg has made to Project Jupyter. As a long-standing sponsor, Bloomberg has been instrumental in the development and success of Jupyter. Home to core maintainers and a major funder of JupyterLab since its inception, Bloomberg has also sponsored all editions of JupyterCon. The sustained support by Bloomberg has been crucial to Jupyter’s growth and impact.&lt;/p&gt;
&lt;p&gt;We are excited about the future of ipydatagrid within Project Jupyter, and look forward to continued innovation and collaboration within the broader community.&lt;/p&gt;
&lt;p&gt;— on behalf of the Jupyter Widgets Council, Sylvain Corlay&lt;/p&gt;
</content><category term="visualization"/><category term="widgets"/></entry><entry><title>JupyterGIS</title><link href="https://jupyter.org/blog/posts/2024/jupytergis/" rel="alternate"/><published>2024-06-12T17:09:00+00:00</published><updated>2024-06-12T17:09:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2024-06-12:/blog/posts/2024/jupytergis/</id><summary type="html">&lt;p&gt;Pioneering Web-based, Collaborative, and Open-source GIS Tools&lt;/p&gt;
</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2024/jupytergis/images/001-1_IkYCf2cbk3SaxaROQ0eUsA.webp" alt="The logo of Project Jupyter next to a stylised terrestrial globe" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;We are thrilled to announce that the European Space Agency (ESA) is funding our proposal “&lt;em&gt;Real-time collaboration and collaborative editing for GIS workflows with Jupyter and QGIS&lt;/em&gt;.”&lt;/p&gt;
&lt;p&gt;The consortium spearheading this project comprises &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; and &lt;a href="https://www.simula.no/"&gt;Simula Research Lab&lt;/a&gt; (Simula), two organizations with a long history of contributions to the Jupyter project and the broader open-source scientific computing ecosystem.&lt;/p&gt;
&lt;p&gt;The goal of the project is to build solid foundations for a versatile web-based user interface for Geographic Information Systems (GIS) workflows. It will comprise several components, including a JupyterLab extension for collaboratively editing QGIS project files and the integration of these APIs in the Jupyter Notebook. We will then explore integration with platforms like the &lt;a href="https://dataspace.copernicus.eu/"&gt;Copernicus Data Space Ecosystem&lt;/a&gt; (CDSE) and the &lt;a href="https://eosc.eu/"&gt;European Open Science Cloud&lt;/a&gt; (EOSC).&lt;/p&gt;
&lt;h2 id="collaborative-workflows-in-geosciences"&gt;Collaborative workflows in geosciences&lt;/h2&gt;
&lt;p&gt;Collaborative editing of documents has become an integral part of our digital lives and has made us collectively more productive. Gone are the days of cumbersome email exchanges with documents shuttling back and forth.&lt;/p&gt;
&lt;p&gt;Looking ahead, the potential of co-editing extends far beyond text documents and will apply to all authoring UIs, from CAD to image processing. We think that the shift to collaborative editing will be even more transformative for larger and more complex projects, which are inherently social and require the concerted effort of large teams. Whether you are designing a stadium, a plane, or an ocean liner, you need to coordinate a diverse expertise to build a unified model. In geosciences, it may range from climate modeling to agriculture, ecology, urban planning, and many more areas of expertise. For such endeavors, we must embrace tools favoring collaboration, and this applies to the future web-based user interfaces for geoscience research.&lt;/p&gt;
&lt;p&gt;We have been working on collaborative editing in the core of JupyterLab for the past three years. Our approach is based on the &lt;a href="https://yjs.dev/"&gt;Yjs framework&lt;/a&gt;, an implementation of CRDT data structures (Conflict-free Replicated Data Type). We have learned that since it is so tied to the data model, retrofitting these features into an existing application is considerably more arduous than building the initial data model on the appropriate paradigm from inception. This is why JupyterGIS will be built from the ground up with collaborative editing in mind.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;JupyterGIS will be the first open-source GIS tool to provide collaborative editing features.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Importantly, JupyterGIS is part of a broader mission to enable collaborative workflows in open-source technical computing. The &lt;a href="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/"&gt;JupyterCAD&lt;/a&gt; project, a collaborative CAD modeler, is another example of this endeavor. By sharing knowledge and resources, both JupyterGIS and JupyterCAD will benefit from and contribute to each other’s progress, ultimately driving innovation and productivity in their respective fields.&lt;/p&gt;
&lt;h2 id="from-the-desktop-to-the-web"&gt;From the desktop to the web&lt;/h2&gt;
&lt;p&gt;Advanced authoring tools, including IDEs, CAD modelers, image processing software, and GIS applications, are essential for professionals who rely on them for extended periods. These users have high expectations and demand key features to optimize their productivity and workflow. Among these features are extensibility with plugins, configurable keyboard shortcuts, themability, internationalization, scriptability, a unified settings system, and the ability to operate across multiple browser windows and devices.&lt;/p&gt;
&lt;p&gt;Developing a new application from the ground up that meets all these requirements is a formidable challenge. This is where the JupyterLab application framework proves invaluable. By leveraging this framework, developers can build custom, feature-rich authoring tools that incorporate these essential features from the outset, making it an ideal solution for creating modern, user-centric applications.&lt;/p&gt;
&lt;p&gt;Beyond the pure authoring user interface, for which JupyterLab is a great tool, it is also the &lt;em&gt;perfect&lt;/em&gt; tool for integration with notebook-based workflows. As part of this project, we will develop an advanced Python API to manage JupyterGIS sessions, leveraging Jupyter’s robust display system to incorporate sophisticated GIS features inline in Jupyter notebooks and consoles. This integration will further enhance the capabilities and versatility of our application. This feature will follow the same architecture as that of JupyterCAD for the integration with the notebook user interface.&lt;/p&gt;
&lt;h2 id="real-world-applications"&gt;Real-world applications&lt;/h2&gt;
&lt;p&gt;JupyterGIS is meant to become a &lt;em&gt;general-purpose&lt;/em&gt; tool. However, we will work with teams of practitioners on &lt;em&gt;specific&lt;/em&gt; real-world applications to ensure that it addresses their needs.&lt;/p&gt;
&lt;p&gt;One such project concerns the use of digital and GIS solutions for emergency management. While practitioners involved in emergency management already have experience with such tools, we are convinced that web-based applications built with collaboration in mind from the start can foster improved coordination and collaboration, and therefore the effectiveness of the response.&lt;/p&gt;
&lt;p&gt;Response teams comprise different organizations, including the affected municipalities, police, emergency response organizations like the Red Cross, and advisers such as the U.S. Army Corps of Engineers (USACE) in the United States or the Norwegian Water Resources and Energy Directorate (NVE) in Norway. Even when using the same incident management system, miscommunications and misunderstandings can occur between these stakeholders, resulting in delays or improper use of resources. An improved integration of collaborative GIS software can improve upon the existing tooling.&lt;/p&gt;
&lt;h2 id="building-collaborations-in-europe-and-beyond"&gt;Building collaborations in Europe and beyond&lt;/h2&gt;
&lt;p&gt;We will partner with key practitioners and make sure JupyterGIS addresses their use cases. Integration in the &lt;a href="https://dataspace.copernicus.eu/"&gt;Copernicus Data Space Ecosystem&lt;/a&gt; (CDSE) and the &lt;a href="https://eosc.eu/"&gt;European Open Science Cloud&lt;/a&gt; (EOSC) will be key to the adoption of JupyterGIS and demonstrate its deployment in such environments.&lt;/p&gt;
&lt;p&gt;Beyond Europe, we are currently working on including this project into a broader scope. We are excited to be partnering with the “&lt;a href="https://www.live-env.org/"&gt;LIVE-Env&lt;/a&gt;” project, an open-source initiative spearheaded by Alyssa Goodman at Harvard University. Furthermore, we are establishing a key collaboration with the &lt;a href="https://bids.berkeley.edu/home"&gt;Berkeley Institute for Data Sciences&lt;/a&gt; (BIDS) and the &lt;a href="https://dse.berkeley.edu/"&gt;Schmidt Center for Data Science and Environment&lt;/a&gt; (DSE) at UC Berkeley and &lt;a href="https://2i2c.org/"&gt;2i2c&lt;/a&gt;, with a focus on Jupyter-based geosciences.&lt;/p&gt;
&lt;h2 id="affiliations"&gt;Affiliations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Sylvain Corlay: &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anne Fouilloux: &lt;a href="https://www.simula.no/"&gt;Simula&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Monika Weissschnur: &lt;a href="https://www.simula.no/"&gt;Simula&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><category term="collaboration"/><category term="geoscience"/><category term="JupyterGIS"/><category term="science"/></entry><entry><title>🎉 JupyterCon 2023 recordings now live on YouTube! 🎉</title><link href="https://jupyter.org/blog/posts/2023/jupytercon-2023-recordings-now-live-on-youtube/" rel="alternate"/><published>2023-07-22T21:14:00+00:00</published><updated>2023-07-22T21:16:00+00:00</updated><author><name>Gayle Ollington</name></author><id>tag:jupyter.org,2023-07-22:/blog/posts/2023/jupytercon-2023-recordings-now-live-on-youtube/</id><summary type="html">&lt;p&gt;Get ready to relive the magic of JupyterCon 2023, because the long-awaited moment is finally here! The JupyterCon YouTube channel has just dropped a treasure trove of content — all the talk and keynote recordings from the most epic conference of the year.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Get ready to relive the magic of JupyterCon 2023, because the long-awaited moment is finally here! The &lt;a href="https://www.youtube.com/jupytercon"&gt;JupyterCon YouTube channel&lt;/a&gt; has just dropped a treasure trove of content — all the talk and keynote recordings from the most epic conference of the year.&lt;/p&gt;
&lt;p&gt;Held at the Cité des Sciences in the city of Paris, from May 10 to 12, &lt;a href="https://www.jupytercon.com/"&gt;JupyterCon 2023&lt;/a&gt; was a celebration of all things Jupyter and beyond.&lt;/p&gt;
&lt;p&gt;You can now access all the knowledge-packed sessions online. Don’t miss this opportunity to be inspired by visionaries and experts from different fields who shared their insights on the future of Jupyter.&lt;/p&gt;
&lt;p&gt;We extend our heartfelt gratitude to the &lt;a href="https://www.jupytercon.com/sponsors"&gt;sponsors&lt;/a&gt;, speakers, attendees, and volunteers who contributed to the vibrant atmosphere and made JupyterCon 2023 a memorable experience. Together, we’ve created a platform for knowledge sharing, innovation, and collaboration, empowering data scientists, researchers, educators, and developers worldwide. Thank you for making this conference possible!&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://www.jupytercon.com/"&gt;&lt;img src="https://jupyter.org/blog/posts/2023/jupytercon-2023-recordings-now-live-on-youtube/images/001-1_j0Cai6fnoYoJ-axQzIvpaA.webp" alt="The JupyterCon 2023 logo" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;On behalf of the JupyterCon 2023 organization committee,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gayle Ollington — Jupyter Community Events Manager&lt;/li&gt;
&lt;li&gt;Sylvain Corlay — JupyterCon 2023 General Chair&lt;/li&gt;
&lt;/ul&gt;
</content><category term="events"/><category term="JupyterCon"/></entry><entry><title>Improving the accessibility of Jupyter</title><link href="https://jupyter.org/blog/posts/2023/improving-the-accessibility-of-jupyter/" rel="alternate"/><published>2023-02-24T11:11:00+00:00</published><updated>2023-02-24T11:11:00+00:00</updated><author><name>Nicolas Brichet</name></author><id>tag:jupyter.org,2023-02-24:/blog/posts/2023/improving-the-accessibility-of-jupyter/</id><summary type="html">&lt;p&gt;Towards a more accessible Jupyter notebook&lt;/p&gt;
</summary><content type="html">&lt;p&gt;The adoption of Jupyter has grown significantly in the past few years — especially in education contexts. The project has become a foundational component of our digital experience, from the first lines of code written by high-school students to the most advanced research and engineering use cases.&lt;/p&gt;
&lt;p&gt;In this context of global adoption, it is even more important to ensure that as many people as possible can use the project. It is estimated that 15% of the population has a disability that may impair their ability to use online services. If we don’t want them to be excluded from learning sciences, technology, and engineering, we must improve the tools to make them usable by everyone…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To address this issue, a Jupyter accessibility working group formed and has now become an &lt;a href="https://jupyter.org/governance/list_of_subprojects.html"&gt;official Jupyter Subproject&lt;/a&gt; and received &lt;a href="https://github.com/jupyter/accessibility/blob/main/docs/funding/czi-grant-roadmap.md"&gt;a grant from the Chan Zuckerberg Initiative&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Creating accessible user interfaces is a challenging task as it requires accommodating a broad range of disabilities, including vision, motor, and cognitive impairments. This article presents some of the recent accessibility improvements in the Jupyter Notebook codebase.&lt;/p&gt;
&lt;h2 id="codemirror-6-and-notebook-7"&gt;CodeMirror 6 and Notebook 7&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/jupyter/enhancement-proposals/pull/79"&gt;Jupyter Notebook 7&lt;/a&gt;, which is the next major release of the Jupyter Notebook frontend, has been rebuilt with modern JupyterLab components and extensions while maintaining the classic Jupyter Notebook user experience. Notebook 7 will be released shortly after JupyterLab 4 and will take advantage of JupyterLab improvements.&lt;/p&gt;
&lt;p&gt;Improving the accessibility of Jupyter had long been impeded by significant obstacles. The primary obstacle was that the text editor underlying the Jupyter Notebook (CodeMirror 5) had major accessibility issues.&lt;/p&gt;
&lt;p&gt;Fortunately, this accessibility bottleneck has been unblocked as JupyterLab has been upgraded to use &lt;a href="https://codemirror.net/6/"&gt;CodeMirror 6&lt;/a&gt;, a complete rewrite of the text editor with a strong focus on accessibility. Although this upgrade required extensive codebase modifications, the changes landed a few months ago and will be available with JupyterLab 4. Jupyter Notebook 7 will benefit from the CodeMirror 6 upgrade.&lt;/p&gt;
&lt;h2 id="initial-accessibility-audits"&gt;Initial accessibility audits&lt;/h2&gt;
&lt;p&gt;Shortly after the &lt;a href="https://github.com/jupyterlab/jupyterlab/issues/10370"&gt;CodeMirror 6 migration&lt;/a&gt; landed, we made an automated audit of the accessibility of Notebook 7 with these changes, and found that the number of warnings and errors reported by Axe Auditor went down from several hundreds to a few dozen, most of which seemed fixable. Encouraged by these results, we decided to work on bringing that count to zero!&lt;/p&gt;
&lt;p&gt;With a series of fixes ranging from simple changes to the DOM structure of components to fixing up base Lumino components (&lt;a href="https://github.com/jupyterlab/lumino"&gt;Lumino&lt;/a&gt; is a JavaScript framework that underlies a lot of the JupyterLab frontend architecture), we were able to make the Notebook 7 codebase pass the Axe Auditor tests with zero error or warning. While we have not reached that yet in JupyterLab, both JupyterLab and Jupyter Notebook benefit from these improvements made for Notebook 7 since they are built from the same components.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Screenshot of the output of the Axe accessibility audit tool on the classic Jupyter notebook user interface with a test notebook, showing a total of 242 errors, including 20 “critical” errors, 88 “serious” errors, and 134 errors of “moderate” severity." src="https://jupyter.org/blog/posts/2023/improving-the-accessibility-of-jupyter/images/001-0_-v-lL8LJ8DIqlgXb.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Axe Auditor output with the “classic” Notebook UI (v6) with a &lt;a href="https://nbviewer.org/github/waltherg/notebooks/blob/master/2013-12-03-Crank_Nicolson.ipynb"&gt;test notebook&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Screenshot of the output of the Axe accessibility audit tool on the new Jupyter notebook user interface with a same test notebook, showing zero detected errors." src="https://jupyter.org/blog/posts/2023/improving-the-accessibility-of-jupyter/images/002-0_7imwXY7uST5QSNfi.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Axe Auditor output with the “next” Notebook UI (v7 alpha 13) with the same &lt;a href="https://nbviewer.org/github/waltherg/notebooks/blob/master/2013-12-03-Crank_Nicolson.ipynb"&gt;test notebook&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Similar results were achieved with the file explorer and text editor tabs of the application.&lt;/p&gt;
&lt;h2 id="beyond-accessibility-audits"&gt;Beyond accessibility audits&lt;/h2&gt;
&lt;p&gt;Improving the accessibility of Jupyter requires more than just addressing issues flagged by automated audit tools and the &lt;a href="https://github.com/jupyter/accessibility"&gt;Jupyter Accessibility Subproject&lt;/a&gt; is working on improving accessibility across the board in Project Jupyter. These results with the Notebook 7 codebase are very encouraging, but working with end-users and getting their feedback will also be necessary to make the user interface truly accessible.&lt;/p&gt;
&lt;p&gt;To address the diversity of accessibility requirements, we will approach specific use cases separately (for example, users with screen readers, or users who can operate a keyboard but not a pointing device). While the resulting changes may improve usability for everyone, we need to learn from users who have specific needs to make meaningful improvements.&lt;/p&gt;
&lt;p&gt;Finally, many of the accessibility challenges in Jupyter stem from the &lt;em&gt;content&lt;/em&gt; of the notebooks, as notebook authors may not follow the best practices to make their content usable by everyone (such as adding alt text to images and figures, or properly using headings to communicate the organization of a notebook). To promote these best practices, Jupyter could provide linting tools that produce inline warnings and hints for notebooks that do not follow these guidelines.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;The work by Johan Mabille at &lt;a href="https://twitter.com/QuantStack"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt; on migrating JupyterLab to use CodeMirror 6 was funded by &lt;a href="https://www.twosigma.com/"&gt;&lt;strong&gt;Two Sigma&lt;/strong&gt;&lt;/a&gt;. This upgrade also enabled significant performance improvements in the rendering of Jupyter notebooks, as detailed in this &lt;a href="https://jupyter.org/blog/posts/2022/accelerating-jupyterlab/"&gt;earlier post&lt;/a&gt; by Frédéric Collonval.&lt;/p&gt;
&lt;p&gt;We are grateful to members of the Jupyter Accessibility Subproject who produced a thorough review of the Notebook 7 UI with a focus on keyboard navigation. This is an example of an issue that cannot be easily detected by auditing tools.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the Authors&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/NicolasBrichet_"&gt;&lt;strong&gt;Nicolas Brichet&lt;/strong&gt;&lt;/a&gt; is a scientific software developer at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; active in the Jupyter ecosystem. Among other things, Nicolas made significant contributions to the JupyterLab and Voilà projects, and worked on porting the &lt;a href="https://github.com/jupyter/nbgrader/"&gt;nbgrader&lt;/a&gt; package to JupyterLab. Nicolas worked on accessibility improvements in the JupyterLab and Lumino packages.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/JohanMabille"&gt;&lt;strong&gt;Johan Mabille&lt;/strong&gt;&lt;/a&gt; is a technical director at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;. He was honored with the Distinguished Contributors award in 2020 for his contributions to the Jupyter project. Among other things, he is one of the main authors of the JupyterLab visual debugger, and the creator of Xeus, a C++ implementation of the Jupyter kernel protocol at the basis of many Jupyter kernels. Johan was responsible for the migration of JupyterLab to CodeMirror 6.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/jtpio"&gt;&lt;strong&gt;Jeremy Tuloup&lt;/strong&gt;&lt;/a&gt; is a technical director at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;, and a Jupyter Distinguished Contributor. He is a core maintainer of JupyterLab and Voilà, and the creator of the JupyterLite project. Jeremy is the main initiator of the Notebook 7 project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Frédéric Collonval&lt;/strong&gt; is a technical director at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;, and a Jupyter Distinguished Contributor. He is a core maintainer of the JupyterLab project. Frédéric contributed to the CodeMirror 6 migration and helped numerous new contributors to get their enhancements accepted.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/SylvainCorlay"&gt;&lt;strong&gt;Sylvain Corlay&lt;/strong&gt;&lt;/a&gt; is the founder and CEO of &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;, and a Jupyter Distinguished Contributor. He has worked on many areas of the Jupyter project, from interactive widgets to language kernels and other core components.&lt;/p&gt;
</content><category term="accessibility"/></entry><entry><title>JupyterCon 2023 keynotes</title><link href="https://jupyter.org/blog/posts/2023/jupytercon-2023-keynotes/" rel="alternate"/><published>2023-01-18T20:39:00+00:00</published><updated>2023-01-18T20:39:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2023-01-18:/blog/posts/2023/jupytercon-2023-keynotes/</id><summary type="html">&lt;p&gt;We are excited to announce the keynote speakers for JupyterCon 2023!&lt;/p&gt;</summary><content type="html">&lt;figure&gt;
&lt;img alt="Headshots of JupterCon 2023 keynote speakers, Alyssa Goodman, Paul Romer, Cory Gwin, Craig Peters" src="https://jupyter.org/blog/posts/2023/jupytercon-2023-keynotes/images/001-1_kUq8eGVktgpE-YvYEpjxnA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Alyssa Goodman, Paul Romer, Cory Gwin, Craig Peters&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We are excited to announce the keynote speakers for JupyterCon 2023!&lt;/p&gt;
&lt;p&gt;First up, we have &lt;strong&gt;Alyssa Goodman&lt;/strong&gt; from Harvard University. Alyssa is a professor of astronomy at Harvard University, and was the founding director of the Harvard Initiative in Innovative Computing. She will be sharing her insights on how Jupyter, together with the glue project, opens up new opportunities for exploratory data exploration and visualization in the field of astronomy and beyond.&lt;/p&gt;
&lt;p&gt;Next, we have &lt;strong&gt;Paul Romer&lt;/strong&gt; from NYU. Paul is a Nobel laureate economist and former Chief Economist of the World Bank. He will describe the potential for Jupyter to revolutionize not just how scholars do their research but also how they communicate their results.&lt;/p&gt;
&lt;p&gt;Finally, we have a joint talk from &lt;strong&gt;Craig Peters&lt;/strong&gt; and &lt;strong&gt;Cory Gwin&lt;/strong&gt; from GitHub. They will be discussing the development and capabilities of GitHub Codespaces, and how Jupyter is integrated into this powerful tool for code collaboration and development.&lt;/p&gt;
&lt;p&gt;We are thrilled to have such an inspiring group of keynote speakers sharing their expertise at JupyterCon 2023. &lt;strong&gt;JupyterCon will be held at the Cité des Sciences in Paris on May 10–12, 2023&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Don’t miss out on this opportunity to hear from these inspiring speakers and get your tickets now at &lt;a href="https://www.jupytercon.com/"&gt;https://www.jupytercon.com/&lt;/a&gt;. We look forward to seeing you all there!&lt;/p&gt;
&lt;p&gt;— &lt;a href="https://medium.com/@SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt;, &lt;a href="https://www.jupytercon.com/"&gt;JupyterCon 2023 General Chair&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2023/jupytercon-2023-keynotes/images/002-1_GkEduEK9m-AkwMzHj7qBOg.webp" alt="JupyterCon logo" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
</content><category term="events"/><category term="JupyterCon"/></entry><entry><title>Jupyter Community Workshop: Jupyter for Education</title><link href="https://jupyter.org/blog/posts/2022/jupyter-community-workshop-jupyter-for-education/" rel="alternate"/><published>2022-12-05T23:37:00+00:00</published><updated>2022-12-19T11:40:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2022-12-05:/blog/posts/2022/jupyter-community-workshop-jupyter-for-education/</id><summary type="html">&lt;p&gt;We are excited to announce the next in-person Jupyter Community Workshop! It will focus on the use of Jupyter for Education.&lt;/p&gt;</summary><content type="html">&lt;p&gt;We are excited to announce the next in-person Jupyter Community Workshop! It will focus on the use of Jupyter for Education.&lt;/p&gt;
&lt;p&gt;The event will be held at the Conservatoire National des Arts et Métiers (CNAM) headquarters in &lt;strong&gt;Paris&lt;/strong&gt;, France, &lt;strong&gt;from January 24th to January 26th&lt;/strong&gt;, 2023. Funding for travel expenses is available for attendees from academia and those from groups which are not well-represented in the Jupyter and wider tech community!&lt;/p&gt;
&lt;p&gt;Jupyter Community Workshop are a series of community-organized events to tackle challenging development and design projects, growing the community of contributors, and strengthening collaborations.&lt;/p&gt;
&lt;p&gt;This workshop will focus on the use of Jupyter for education. The goal is to bring together contributors, and community members to further the development of Jupyter-based tools and practices for education. Given the broad variety of topics relevant to this workshop (pedagogical practices, automatic grading, deployment challenges), we will compose the program based on the attendance. We are also planning an installment of the &lt;a href="https://www.meetup.com/PyData-Paris/"&gt;PyData Paris meetup&lt;/a&gt; at CNAM on the 26th of January, with a focus on open-source tools for education.&lt;/p&gt;
&lt;p&gt;The workshop will last three days, with hands-on discussions, hacking sessions, and technical presentations. The goal of this event is to foster collaboration and the sharing of knowledge between Jupyter maintainers and downstream library authors and power users.&lt;/p&gt;
&lt;p&gt;Should you be interested in joining us for this workshop, please fill this &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLSdjoU93eHJvc7O9S-jUtjQviAP1ZOZ6XEA9QZFM-R4ZDK2eQg/viewform?usp=sf_link"&gt;&lt;strong&gt;form&lt;/strong&gt;&lt;/a&gt;. A limited number of spots are available for this event.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;We are grateful to &lt;a href="https://www.cnam.fr/"&gt;CNAM&lt;/a&gt; for hosting us and to &lt;a href="https://www.inria.fr/"&gt;INRIA&lt;/a&gt; for supporting this event. We are also grateful to the sponsors of the Jupyter Community Workshop series, Bloomberg and Amazon AWS.&lt;/em&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Avion III de Clément Ader, at the CNAM — photo by Roi Boshi for Wikimedia Commons" src="https://jupyter.org/blog/posts/2022/jupyter-community-workshop-jupyter-for-education/images/001-1_oqQfLSu5KKFN8rIr1w-PBw.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Avion III de Clément Ader, at the CNAM — photo by Roi Boshi for Wikimedia Commons&lt;/figcaption&gt;
&lt;/figure&gt;
</content><category term="community"/><category term="education"/><category term="events"/><category term="workshops"/></entry><entry><title>MyBinder @ OVHcloud</title><link href="https://jupyter.org/blog/posts/2022/mybinder-ovhcloud/" rel="alternate"/><published>2022-11-23T11:28:00+00:00</published><updated>2022-11-23T11:28:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2022-11-23:/blog/posts/2022/mybinder-ovhcloud/</id><summary type="html">&lt;p&gt;OVHcloud is a long-time supporter of the Jupyter project. In the past few years, they have provided computing resources to several Jupyter-related endeavors to support its sustainability.&lt;/p&gt;</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/mybinder-ovhcloud/images/001-1_Hb4_lgwkmAmw--MbWzaKLw.webp" alt="Logos of OVHCloud, MyBinder, and Jupyter, side by side." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;OVHcloud is a long-time supporter of the Jupyter project. In the past few years, they have provided computing resources to several Jupyter-related endeavors to support its sustainability.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In 2019, Project Jupyter and OVHcloud started collaborating on the hosting of the &lt;strong&gt;MyBinder&lt;/strong&gt; service. With tens of thousands of sessions daily, MyBinder was increasingly dependent on a single instance on a single cloud provider. The offer of OVHcloud triggered a community effort to make &lt;a href="https://mybinder.org/"&gt;MyBinder&lt;/a&gt; truly &lt;em&gt;multi-cloud&lt;/em&gt;. This is how the &lt;a href="https://jupyter.org/blog/posts/2019/the-international-binder-federation/"&gt;&lt;strong&gt;Binder Federation&lt;/strong&gt;&lt;/a&gt; was created, with OVHcloud as its first member. Since then, the Binder Federation has grown with new members gracefully hosting a portion of the traffic. OVHcloud also hosts the &lt;a href="https://nbviewer.org/"&gt;nbviewer.org&lt;/a&gt; service.&lt;/li&gt;
&lt;li&gt;When the global pandemic hit in 2020, the &lt;strong&gt;JupyterCon&lt;/strong&gt; organizers decided to pivot from an in-person event set to happen in Berlin to a &lt;a href="https://jupyter.org/blog/posts/2020/jupytercon-online-more-than-a-conference/"&gt;fully online experience&lt;/a&gt;. Lorena Barba, the general chair of the committee, envisioned an experience for talks and tutorials in which attendees could interact with the technology. OVHcloud stepped up as the &lt;a href="https://blog.ovhcloud.com/sponsorship-of-the-jupytercon-2020-sharing-values-and-supporting-with-infrastructure/"&gt;Platinum sponsor&lt;/a&gt;, gracefully providing the infrastructure for the various deployments of Jupyter required for the conference, including GPUs for the online tutorials requiring them.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="a-new-partnership-with-numfocus"&gt;A new partnership with NumFOCUS&lt;/h2&gt;
&lt;p&gt;Today, we are thrilled to announce that OVHcloud is partnering with NumFOCUS to provide infrastructure to affiliated projects.&lt;/p&gt;
&lt;p&gt;Two pilot projects will benefit from this new agreement: &lt;strong&gt;Pandas&lt;/strong&gt; and &lt;strong&gt;Jupyter&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;On the Jupyter side, these new resources will be used to increase the OVHcloud hosting of MyBinder, thereby helping the project’s sustainability in the long term, continuing to avoid dependency on a single cloud provider. A significant proportion of the traffic of the Binder federation will now be handled by the OVHcloud deployment.&lt;/p&gt;
&lt;h2 id="acknowledgement"&gt;Acknowledgement&lt;/h2&gt;
&lt;p&gt;We are grateful to &lt;a href="https://twitter.com/kevin_amil?lang=en"&gt;Kevin Amil&lt;/a&gt;, &lt;a href="https://twitter.com/Marie_06"&gt;Marie-Christine Ribeiro&lt;/a&gt;, Marie Hering, and Mael Le Gal from OVHcloud for facilitating this new partnership and helping with the migration to the new infrastructure.&lt;/p&gt;
&lt;p&gt;We are grateful to &lt;a href="https://twitter.com/OVHCloud"&gt;OVHcloud&lt;/a&gt; for their continued support to the Jupyter project and the NumFOCUS foundation.&lt;/p&gt;
</content><category term="Binder"/></entry><entry><title>Jupyter Community Workshop: JupyterLite</title><link href="https://jupyter.org/blog/posts/2022/community-workshop-jupyterlite/" rel="alternate"/><published>2022-11-10T15:45:00+00:00</published><updated>2022-11-10T15:45:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2022-11-10:/blog/posts/2022/community-workshop-jupyterlite/</id><summary type="html">&lt;p&gt;We are thrilled to announce the next in-person Jupyter Community Workshop, which will focus on the JupyterLite project!&lt;/p&gt;</summary><content type="html">&lt;p&gt;We are thrilled to announce the next in-person Jupyter Community Workshop, which will focus on the JupyterLite project!&lt;/p&gt;
&lt;p&gt;The event will be held at the &lt;a href="https://www.ovhcloud.com/"&gt;OVHCloud&lt;/a&gt; headquarters in &lt;strong&gt;Paris&lt;/strong&gt;, France, &lt;strong&gt;from December 7th to December 9th&lt;/strong&gt;, 2022. Funding for travel expenses is available for attendees from academia and those from groups which are not well-represented in the Jupyter and wider tech community!&lt;/p&gt;
&lt;p&gt;Jupyter Community Workshop are a series of community-organized events to tackle challenging development and design projects, growing the community of contributors, and strengthening collaborations.&lt;/p&gt;
&lt;p&gt;This specific workshop will focus on the JupyterLite project, a JupyterLab distribution that runs entirely in the browser built from the ground-up using JupyterLab components and extensions. JupyterLite allows for very scalable deployments, and already powers inline consoles and notebooks on the websites of major projects of our ecosystem, such as NumPy, SymPy, Pandas, and many more.&lt;/p&gt;
&lt;p&gt;The workshop will last three days, with hands-on discussions, hacking sessions, and technical presentations. The goal of this event is to foster collaboration and the sharing of knowledge between Jupyter maintainers and downstream library authors and power users.&lt;/p&gt;
&lt;p&gt;Should you be interested in joining us for this workshop, please fill this &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLSc7M_Bmj_u8kdEFrLwnhfj5-T3Y9r37KVb6mlvYVefXh2uSbw/viewform?usp=sf_link"&gt;&lt;strong&gt;form&lt;/strong&gt;&lt;/a&gt;. A limited number of spots are available for this event.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;We are grateful to &lt;a href="https://www.ovhcloud.com/"&gt;OVHCloud&lt;/a&gt; for hosting this event. We are also grateful to the sponsors of the Jupyter Community Workshop series, Bloomberg and Amazon AWS.&lt;/em&gt;&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/community-workshop-jupyterlite/images/001-1_Zayr-b0FjuEZGr-plrEl3Q.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
</content><category term="community"/><category term="events"/><category term="JupyterLite"/><category term="WebAssembly"/><category term="workshops"/></entry><entry><title>Jupyter Community 2021 Update</title><link href="https://jupyter.org/blog/posts/2021/jupyter-community-2021-update/" rel="alternate"/><published>2021-12-20T17:53:00+00:00</published><updated>2021-12-20T20:18:00+00:00</updated><author><name>Ana Ruvalcaba</name></author><id>tag:jupyter.org,2021-12-20:/blog/posts/2021/jupyter-community-2021-update/</id><summary type="html">&lt;p&gt;Project Jupyter is happy to share some exciting news in key efforts to connect the global Jupyter community.&lt;/p&gt;</summary><content type="html">&lt;figure&gt;
&lt;img alt="Attendees to the June 2019 Community Workshop on Dashboarding in Paris (Photo credit to Lindsey Heagy)" src="https://jupyter.org/blog/posts/2021/jupyter-community-2021-update/images/001-0_yTx05ysvB6B5NuZ0.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Attendees to the June 2019 Community Workshop on Dashboarding in Paris (Photo credit to Lindsey Heagy)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="new-committee-announcement"&gt;New committee announcement&lt;/h2&gt;
&lt;p&gt;Project Jupyter is happy to share some exciting news in key efforts to connect the global Jupyter community. First, we’d like to introduce a new committee that was created to act on behalf of the Project Jupyter Steering Council with the objective of growing, building, and connecting the global Jupyter community of users and contributors. You can learn more about the Jupyter Community Building committee &lt;a href="https://jupyter.org/governance/communitybuildingcommittee.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="were-hiring"&gt;We’re hiring!&lt;/h2&gt;
&lt;p&gt;We are hiring a Jupyter Community Events Manager to help manage Jupyter Community Workshops and the JupyterCon conference. Check out the blog post about the position at &lt;a href="https://numfocus.medium.com/were-hiring-jupyter-community-events-manager-2f31e5b869a8"&gt;NumFOCUS blog&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="jupyter-community-workshops"&gt;Jupyter Community Workshops&lt;/h2&gt;
&lt;p&gt;The Jupyter Community Workshop program has been an outstanding success in bringing together small groups of Jupyter community members and core contributors for high-impact strategic work and community engagement on focused topics. Community members have hosted 11 community workshops since 2018 exploring using Jupyter in specific disciplines (education, scientific facilities with supercomputers), promoting Jupyter around the world (Hawaii, South America, D.R. Congo), and developing core Jupyter projects and attracting new contributors (Jupyter server, Jupyter widgets, Jupyter kernels, nbgrader, Voilà).&lt;/p&gt;
&lt;p&gt;Many more workshops were in planning stages when the COVID-19 pandemic abruptly paused in-person gatherings globally in March, 2020. All workshops were put on hold until 2021, and organizers are currently working through how to best proceed in the still-uncertain environment around global in-person gatherings (for example, scheduling far into the future, or moving to a virtual gathering). Two upcoming workshops have been scheduled for 2022 (on accessibility in Jupyter and Jupyter in musculoskeletal research), and more workshops are in the planning stages. Stay tuned for more details.&lt;/p&gt;
&lt;h2 id="jupytercon"&gt;JupyterCon&lt;/h2&gt;
&lt;p&gt;In 2017 and 2018, our first two global user conferences were made possible through a grant from the Leona M and Harry B Helmsley Charitable Trust and a partnership with O’Reilly Media and NumFOCUS.&lt;/p&gt;
&lt;p&gt;Unlike in 2017 and 2018, JupyterCon 2020 was &lt;em&gt;entirely&lt;/em&gt; led by the community. Together with NumFOCUS, a team of community volunteers made the event possible, despite the enormous challenges from the COVID-19 pandemic. With over 170 tutorials, talks, and posters, and over 700 attendees, JupyterCon 2020 was a huge success. We are incredibly grateful to all the volunteers who worked on the conference and to all the participants for their contributions.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;Many thanks to our generous sponsors! These community building efforts, including the hiring of an Event Manager, is made possible through significant donations from our partners at &lt;a href="https://www.techatbloomberg.com/"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://aws.amazon.com/"&gt;&lt;strong&gt;AWS&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the Authors&lt;/h2&gt;
&lt;p&gt;This post was written by the &lt;a href="https://github.com/jupyter/governance/blob/6af915d24ca4216895c73f995d5cb9cbcae88ff4/communitybuildingcommittee.md"&gt;Jupyter Community Building Committee&lt;/a&gt;, currently composed of &lt;a href="https://twitter.com/Ruv7"&gt;Ana Ruvalcaba&lt;/a&gt;, &lt;a href="https://twitter.com/jason_grout"&gt;Jason Grout&lt;/a&gt;, and &lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt;.&lt;/p&gt;
</content><category term="community"/></entry><entry><title>Enabling the JupyterLab debugger with ipykernel</title><link href="https://jupyter.org/blog/posts/2021/enabling-the-jupyterlab-debugger-with-ipykernel/" rel="alternate"/><published>2021-05-13T11:45:00+00:00</published><updated>2021-06-02T14:59:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2021-05-13:/blog/posts/2021/enabling-the-jupyterlab-debugger-with-ipykernel/</id><summary type="html">&lt;p&gt;Support for the Jupyter Debugger Protocol just landed in ipykernel&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Support for the Jupyter Debugger Protocol just landed in ipykernel&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;JupyterLab 3.0 includes a visual debugger that allows to interactively set breakpoints, step into functions, and inspect variables with any Jupyter kernel that implements the Jupyter debugger protocol.&lt;/p&gt;
&lt;p&gt;The first two language kernels to implement the new protocol were &lt;a href="https://github.com/jupyter-xeus/xeus-python/"&gt;xeus-python&lt;/a&gt; (a Python kernel) and &lt;a href="https://github.com/jupyter-xeus/xeus-robot/"&gt;xeus-robot&lt;/a&gt; (a kernel for Robot Framework). Unfortunately, the reference Python kernel, &lt;a href="https://github.com/ipython/ipykernel"&gt;&lt;strong&gt;ipykernel&lt;/strong&gt;&lt;/a&gt;, did not support debugging yet, &lt;em&gt;until now&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;Today, we are pleased to announce that debugging support landed in ipykernel, and will be available in the next major release, ipykernel 6.0. Pre-releases including the ipykernel debugger are available.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Debugging with ipykernel" src="https://jupyter.org/blog/posts/2021/enabling-the-jupyterlab-debugger-with-ipykernel/images/001-1_jSQWLvCYoV-L-kp_lTkRKg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Debugging with ipykernel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="what-will-change-with-ipykernel-60"&gt;What will change with ipykernel 6.0?&lt;/h2&gt;
&lt;p&gt;Enabling support for debugging in ipykernel required important changes in the code base regarding the concurrency model of the kernel. The main change is that the processing of messages on the “control channel” now happens in a different thread, allowing for the processing to happen while user code is running.&lt;/p&gt;
&lt;p&gt;Ipykernel 6.0 includes several other updates. Tornado coroutines were dropped in favor of native coroutines. The Matplotlib inline backend was split into a separate package, and ipykernel depends on &lt;a href="https://github.com/microsoft/debugpy"&gt;debugpy&lt;/a&gt;, an implementation of the Debug Adapter Protocol for Python.&lt;/p&gt;
&lt;p&gt;If you are interested in testing out the new features, check out the beta release!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install ipykernel --pre
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="try-it-now"&gt;Try it now!&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;a href="https://mybinder.org/"&gt;MyBinder&lt;/a&gt;, you can also try it out without the need of installing anything on your computer. Just follow this link:&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://mybinder.org/v2/gist/SylvainCorlay/a6405bbdfa9d58a670a67f3a47741bd2/HEAD?urlpath=doc%2Ftree%2Fdebugger.ipynb"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/enabling-the-jupyterlab-debugger-with-ipykernel/images/002-0_rELNpt0w5qbk_GQn.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="what-about-the-future"&gt;What about the future?&lt;/h2&gt;
&lt;p&gt;A lot of new features are in the works with the JupyterLab debugger.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JupyterLab 3.1 will include several usability improvements to the debugger.&lt;/li&gt;
&lt;li&gt;It will also add the ability to submit code for execution when stopped at a breakpoint.&lt;/li&gt;
&lt;li&gt;We are working on a richer variable explorer, using Jupyter’s rich display system to enable the rich-rendering of variables in the explorer, to &lt;em&gt;e.g.&lt;/em&gt; render dataframes as tables.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, we also plan on adding debugging support to other language kernels.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;The work of Johan and Sylvain at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; on the debugger support in ipykernel was funded by &lt;a href="https://www.twosigma.com/"&gt;Two Sigma&lt;/a&gt;. We are grateful to Min Ragan Kelley and Matthias Bussonnier, who reviewed the pull requests on debugger support.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the authors&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/enabling-the-jupyterlab-debugger-with-ipykernel/images/003-1_8_HgQuq5_HXhLXSdfGnhrA.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/JohanMabille"&gt;Johan Mabille&lt;/a&gt; is a scientific software developer at QuantStack.&lt;/p&gt;
&lt;p&gt;Johan is very active in the Jupyter ecosystem, as the creator of &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;xeus&lt;/a&gt;, a C++ implementation of the Jupyter protocol, and several language kernels, such as &lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt;, &lt;a href="https://github.com/jupyter-xeus/xeus-cling"&gt;xeus-cling&lt;/a&gt;, and &lt;a href="https://github.com/jupyter-xeus/xeus-robot"&gt;xeus-robot&lt;/a&gt;. Johan also made contributions to the Jupyter widgets ecosystem and to JupyterLab.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/enabling-the-jupyterlab-debugger-with-ipykernel/images/004-1_LpuIpGQIDYMhv5IBthmwcA.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt; is the founder and CEO of QuantStack.&lt;/p&gt;
&lt;p&gt;As an open-source developer, Sylvain is very active in the Jupyter project with contributions in several components of the stack, including widgets, kernels, nbconvert, and others. He is also a steering committee member of the project.&lt;/p&gt;
&lt;p&gt;Sylvain also does volunteer work for the community, as member of board of directors of NumFOCUS, co-organizer of the &lt;a href="https://www.meetup.com/pyData-paris"&gt;PyData Paris Meetup&lt;/a&gt;, and vice-chair of JupyterCon 2020.&lt;/p&gt;
</content><category term="IPython"/><category term="JupyterLab"/><category term="kernels"/></entry><entry><title>A Curiously Recurring Widget Library</title><link href="https://jupyter.org/blog/posts/2021/a-curiously-recurring-widget-library/" rel="alternate"/><published>2021-01-27T14:22:00+00:00</published><updated>2021-01-27T21:41:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2021-01-27:/blog/posts/2021/a-curiously-recurring-widget-library/</id><summary type="html">&lt;p&gt;Diving into the implementation of xwidgets&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Interactive widgets allow Jupyter users to create user interfaces inline in their notebooks, and to turn them into standalone applications with tools such as &lt;a href="https://github.com/voila-dashboards/voila"&gt;Voilà&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Language backends for Jupyter interactive widgets exist in Python (with &lt;a href="https://github.com/jupyter-widgets/ipywidgets"&gt;ipywidgets&lt;/a&gt;), and C++ (with &lt;a href="https://github.com/jupyter-xeus/xwidgets"&gt;xwidgets&lt;/a&gt;, and the &lt;a href="https://github.com/jupyter-xeus/xeus-cling"&gt;xeus-cling&lt;/a&gt; C++ Jupyter kernel), reusing the same frontend implementation of the widgets in JavaScript.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Simple interactive widgets at play in JupyterLab with the xeus-cling C++ kernel" src="https://jupyter.org/blog/posts/2021/a-curiously-recurring-widget-library/images/001-1_b_2s5wfIzrqGapkhBytHSg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Simple interactive widgets at play in JupyterLab with the xeus-cling C++ kernel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In this article, we dive into some of the C++ techniques used in the implementation of the xwidgets library, including&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;discussions on &lt;strong&gt;value semantics&lt;/strong&gt; and &lt;strong&gt;RAII&lt;/strong&gt; (&lt;em&gt;Resource Acquisition Is Initialization&lt;/em&gt;),&lt;/li&gt;
&lt;li&gt;an original application of &lt;strong&gt;CRTP&lt;/strong&gt; (&lt;em&gt;Curiously Recurring Template Pattern&lt;/em&gt;),&lt;/li&gt;
&lt;li&gt;an original implementation of the &lt;strong&gt;observer&lt;/strong&gt; pattern, xproperty,&lt;/li&gt;
&lt;li&gt;a plea for allowing the &lt;strong&gt;overloading of the dot operator&lt;/strong&gt; in C++, to enable better proxy types.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;For readers interested in knowing more about &lt;strong&gt;interpreted C++&lt;/strong&gt;, we recommend the following posts:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jupyter.org/blog/posts/2017/interactive-workflows-for-c-with-jupyter/"&gt;Interactive workflows for C++ with Jupyter&lt;/a&gt; &lt;em&gt;(Jupyter blog), by Sylvain Corlay, Loic Gouarin, Johan Mabille, and Wolf Vollprecht&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.llvm.org/posts/2020-12-21-interactive-cpp-for-data-science/"&gt;Interactive C++ for Data Science&lt;/a&gt; &lt;em&gt;(LLVM blog), by Vassil Vassilev, David Lange, Simeon Ehrig, and Sylvain Corlay&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/"&gt;Interpreted C++ for GIS with Jupyter&lt;/a&gt; &lt;em&gt;(Jupyter blog), by Martin Renou&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="using-the-raii-pattern-for-a-widget-library"&gt;Using the RAII pattern for a widget library&lt;/h2&gt;
&lt;p&gt;Jupyter widgets are special objects that trigger the creation of a counterpart JavaScript model object in the Jupyter frontend upon creation. The state of the object in the backend is synchronized with the state of the JavaScript frontend object. Views of that widget model are instantiated upon display.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The MVC (Model View Controller) architecture of Jupyter widgets, and synchronization with the backend" src="https://jupyter.org/blog/posts/2021/a-curiously-recurring-widget-library/images/002-1_ThTvsqji0l85Pr__5hs9bQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The MVC (Model View Controller) architecture of Jupyter widgets, and synchronization with the backend&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This MVC (Model-View-Controller) architecture for Jupyter interactive widgets allowed us to reuse all of the frontend implementation, by simply providing an alternative backend in C++, implementing the same messaging protocol.&lt;/p&gt;
&lt;p&gt;In order to tie the lifetime of the kernel and frontend objects, we decided to use the &lt;a href="https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization"&gt;RAII (Resource Acquisition Is Initialization)&lt;/a&gt; pattern. RAII is a common programming idiom that consists of tying the lifetime of an object with the holding of a resource. Most typically, the resource is&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;acquired&lt;/strong&gt;&lt;/em&gt; in the &lt;em&gt;&lt;strong&gt;constructor&lt;/strong&gt;&lt;/em&gt; of the object,&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;released&lt;/strong&gt;&lt;/em&gt; in the &lt;em&gt;&lt;strong&gt;destructor&lt;/strong&gt;&lt;/em&gt; of the object.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The RAII pattern is not common in garbage-collected languages because unlike in C++, the time when objects are destroyed is not deterministic. The Python programming language mitigates that issue by introducing&lt;/em&gt; &lt;a href="https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"&gt;&lt;em&gt;context managers&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, often used to&lt;/em&gt; e.g. &lt;em&gt;open and close files.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A consequence of relying on object lifetime for resource management in C++ is to adopt the “&lt;em&gt;&lt;strong&gt;value semantics&lt;/strong&gt;&lt;/em&gt;” for widget instances, instead of “&lt;em&gt;&lt;strong&gt;reference semantics&lt;/strong&gt;&lt;/em&gt;” which is more typical for widget frameworks like Qt.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note: value semantics vs reference semantics&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you are not familiar with the concepts of&lt;/em&gt; &lt;strong&gt;value&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; &lt;strong&gt;reference&lt;/strong&gt; &lt;strong&gt;semantics&lt;/strong&gt; &lt;em&gt;in C++, I recommend reading the&lt;/em&gt; &lt;a href="https://isocpp.org/wiki/faq/value-vs-ref-semantics"&gt;&lt;em&gt;&lt;strong&gt;excellent FAQ&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; &lt;em&gt;of isocpp.org.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;To summarize:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;with &lt;strong&gt;value semantics&lt;/strong&gt;, objects hold actual values, and copying an object copies their attributes. With value semantics, one should provide implementations of &lt;strong&gt;copy, and move constructors&lt;/strong&gt;, as well as &lt;strong&gt;copy and move assignment operators&lt;/strong&gt;. Besides, values should not have virtual methods.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;with &lt;strong&gt;reference semantics&lt;/strong&gt;, objects are manipulated through references (or pointers) and never by value. Reference semantics is typically used for polymorphic programming with &lt;strong&gt;virtual methods&lt;/strong&gt;. With reference semantics, it is recommended to delete copy and move constructors, as well as copy and move assignment operators to avoid accidental copies when passing objects to functions taking arguments by values, causing object slicing. (They can also be made private). Explicit cloning of a reference semantics object is generally allowed via a call to a &lt;strong&gt;clone&lt;/strong&gt; virtual method.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;In a C++ codebase, the existence of public copy or move constructors alongside virtual methods in the same class is generally a sign of a bad design.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The use of value semantics for xwidgets provides clear lifetime management for associated resources. Careful use of the move semantics provides fine-grained control.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Illustration of the move semantics for xwidgets" src="https://jupyter.org/blog/posts/2021/a-curiously-recurring-widget-library/images/003-1_i1D4_PqaKhej-XRSKkoyBw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Illustration of the move semantics for xwidgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another advantage of using value semantics in xwidgets is that C++ &lt;strong&gt;beginners&lt;/strong&gt; who are typical users of the Jupyter notebook (often used by instructors) can easily manipulate “widgets as values” without having to deal with manual memory allocation etc.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;With value semantics, addressing the lifetime of objects becomes the responsibility of the framework author, in a carefull implementation of (copy and move) constructors, destructors, and (copy and move) assignment operators.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="static-polymorphism-and-the-crtp-pattern"&gt;Static polymorphism and the CRTP pattern&lt;/h2&gt;
&lt;p&gt;While the use of value semantics provides fine-grained control over the lifetime of widgets, it prevents the use of virtual methods in their implementation. Code reuse is achieved with static polymorphism techniques and specifically the CRTP pattern.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern"&gt;Curiously Recurring Template Pattern (CRTP)&lt;/a&gt; is the practice of making a class &lt;code&gt;X&lt;/code&gt; derive from a class template instantiation using &lt;code&gt;X&lt;/code&gt; itself as a template argument.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;X&lt;/span&gt; : &lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="nb"&gt;base&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;X&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;CRTP is commonly used by matrix or tensor algebra libraries making use of expression templates (such as &lt;a href="https://github.com/xtensor-stack/xtensor"&gt;xtensor&lt;/a&gt;, &lt;a href="http://eigen.tuxfamily.org/index.php?title=Main_Page"&gt;eigen&lt;/a&gt;, or &lt;a href="https://github.com/blitzpp/blitz"&gt;blitz&lt;/a&gt;) to prevent the overhead of virtual function dispatch for operations likely to be performed in a loop, such as element access.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Placing common code in a CRTP base allows code reuse without the overhead of virtual dispatch. However, the template base class is specialized for each final type increasing the resulting &lt;strong&gt;binary size&lt;/strong&gt;. This can be mitigated by factoring as much of the code in a base class that would not be templated by the derived type.&lt;/p&gt;
&lt;h2 id="crtp-in-xwidgets-closing-the-recursion"&gt;CRTP in xwidgets — closing the recursion&lt;/h2&gt;
&lt;p&gt;In order to allow for code reuse without virtual inheritance, xwidgets’ class hierarchy is entirely based on CRTP. Our naming scheme is that CRTP bases, which should not be instantiated directly are prefixed with the letter &lt;code&gt;x&lt;/code&gt; and final concrete widget types are not.&lt;/p&gt;
&lt;p&gt;Upon construction of &lt;em&gt;e.g.&lt;/em&gt; the &lt;strong&gt;&lt;code&gt;button&lt;/code&gt;&lt;/strong&gt; widget, constructors of base types are called in the order of inheritance, which is why we need to establish the connection with the frontend in the constructor of the most derived type, after all attributes have been initialized, and send a message to the frontend with all the values.&lt;/p&gt;
&lt;p&gt;The pattern for creating the most derived type being always the same, we defined the &lt;strong&gt;&lt;code&gt;xmaterialize&lt;/code&gt;&lt;/strong&gt; template class closing the CRTP hierarchy with&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;using button = xmaterialize&amp;lt;xbutton&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;strong&gt;&lt;code&gt;xmaterialize&lt;/code&gt;&lt;/strong&gt; template class is defined as &lt;strong&gt;final&lt;/strong&gt;, to prevent further inheritance. The constructors and assignment operators forward to those of the CRTP bases and implement the RAII pattern.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;...&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;public&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;self_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;base_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;self_type&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;base_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nx"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;//  RAII: create the frontend model.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;inline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;::~&lt;/span&gt;&lt;span class="nx"&gt;xmaterialize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;moved_from&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// RAII: delete the frontend model.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The full implementation of &lt;strong&gt;&lt;code&gt;xmaterialize&lt;/code&gt;&lt;/strong&gt; (as of xwidgets 0.25) is available &lt;a href="https://raw.githubusercontent.com/jupyter-xeus/xwidgets/0.25.0/include/xwidgets/xmaterialize.hpp"&gt;here&lt;/a&gt;. Beyond the logic described in this section, it also includes the handling of the move semantics and the method chaining API which is the subject of a later section.&lt;/p&gt;
&lt;h2 id="precompilation-and-binary-size-optimization"&gt;Precompilation and binary size optimization&lt;/h2&gt;
&lt;p&gt;Even though xwidgets is fully based on template types, we decided to precompile all final widget types for faster interactive use with the xeus-cling kernel. This is achieved with&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;an &lt;strong&gt;&lt;code&gt;extern&lt;/code&gt;&lt;/strong&gt; declaration in the header (here in &lt;code&gt;xbutton.hpp&lt;/code&gt;)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;extern template class xmaterialize&amp;lt;xbutton&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;and in the source file (here in &lt;code&gt;xbutton.cpp&lt;/code&gt;), an instruction for the precompilation&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;template class XWIDGETS_API xmaterialize&amp;lt;xbutton&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Doing this for all widget types of the library initially resulted in a large compiled binary size. Using the &lt;strong&gt;&lt;code&gt;button&lt;/code&gt;&lt;/strong&gt; widget as an example, we see that base types are templated by the final type in the class hierarchy &lt;strong&gt;&lt;code&gt;button -&amp;gt; xbutton&amp;lt;button&amp;gt; -&amp;gt; xwidgets&amp;lt;button&amp;gt; -&amp;gt; xobject&amp;lt;button&amp;gt;&lt;/code&gt;&lt;/strong&gt;, and therefore, their binary representation is duplicated for each final type.&lt;/p&gt;
&lt;p&gt;A strategy for reducing the binary size has been to factor out as much of the logic of &lt;strong&gt;&lt;code&gt;xobject&amp;lt;D&amp;gt;&lt;/code&gt;&lt;/strong&gt; in a non-template base &lt;strong&gt;&lt;code&gt;xcommon&lt;/code&gt;&lt;/strong&gt; improving compilation speed and preventing binary code duplication.&lt;/p&gt;
&lt;h2 id="xproperty-an-implementation-of-the-observer-pattern"&gt;Xproperty: an implementation of the observer pattern&lt;/h2&gt;
&lt;p&gt;In order to update the frontend upon changes of widget properties, xwidgets relies on an implementation of the observer pattern called &lt;a href="https://github.com/jupyter-xeus/xproperty"&gt;&lt;strong&gt;&lt;code&gt;xproperty&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt;. xproperty is to xwidgets what &lt;a href="https://github.com/ipython/traitlets"&gt;traitlets&lt;/a&gt; are to ipywidgets.&lt;/p&gt;
&lt;p&gt;In order to trigger observers and validators in the owner object upon assignment of new values, xproperty relies on the overload of the assignment operator &lt;strong&gt;&lt;code&gt;=&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;inline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xproperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reference&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Before assigning the new value, invoke validators&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// which may also mutate the value.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;m_value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;invoke_validators&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Call class-level observer.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m_value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Call registered observers for that attribute&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;invoke_observers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m_name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Return the new value &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m_value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="method-chaining-for-widget-initialization"&gt;Method chaining for widget initialization&lt;/h2&gt;
&lt;p&gt;Jupyter interactive widgets have many attributes that may be specified at construction time.&lt;/p&gt;
&lt;p&gt;In the Python implementation, this is handled with keyword arguments, but the C++ programming language does not support keyword arguments. There exist various approaches to enable this feature with advanced metaprogramming techniques. In the case of xwidgets, this need is limited to the initialization of xproperty attributes, which allowed us to adopt a more scoped approach: a method chaining API for property initialization:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;slider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;slider&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;double&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="no"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;.min&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="no"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;.max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="no"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;.description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Another slider&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="na"&gt;.finalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;this was enabled by overriding the function call operator () on xproperties to pass an intial value (only when the said property is an rvalue). A static &lt;strong&gt;&lt;code&gt;initialize&lt;/code&gt;&lt;/strong&gt; method is used instead of the default constructor to prevent the initialization of the JavaScript counterpart while all attributes may not have been set yet. The frontend counterpart is only acquired with the &lt;strong&gt;&lt;code&gt;finalize()&lt;/code&gt;&lt;/strong&gt; call.&lt;/p&gt;
&lt;h2 id="building-upon-xwidgets"&gt;Building upon xwidgets&lt;/h2&gt;
&lt;p&gt;Jupyter interactive widgets are not limited to the controls available in the core package. In fact, there is a rich ecosystem of widget libraries built upon the core framework: &lt;a href="https://github.com/maartenbreddels/ipyvolume"&gt;ipyvolume&lt;/a&gt; (3-D plotting), &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; (maps visualization), &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt; (2-D plotting), &lt;a href="https://github.com/QuantStack/ipygany"&gt;ipygany&lt;/a&gt; (3-D mesh visualization), &lt;a href="https://github.com/martinRenou/ipycanvas"&gt;ipycanvas&lt;/a&gt; (generic drawing), &lt;a href="https://github.com/maartenbreddels/ipywebrtc"&gt;ipywebrtc&lt;/a&gt; (streaming video and audio), and many many more.&lt;/p&gt;
&lt;p&gt;For the C++ programming language, we have already provided:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/xleaflet"&gt;xleaflet&lt;/a&gt; (the C++ equivalent to ipyleaflet, reusing the same frontend),&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xwebrtc"&gt;xwebrtc&lt;/a&gt; (the C++ equivalent to ipywebrtc, reusing the same frontend).&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Screencast of xleaflet in JupyterLab, loading and visualizing a GeoJSON dataset in a C++ notebook." src="https://jupyter.org/blog/posts/2021/a-curiously-recurring-widget-library/images/004-1_IULQ8LZDnLFMmB1nsbNF0Q.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Screencast of xleaflet in JupyterLab, loading and visualizing a GeoJSON dataset in a C++ notebook.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Potentially, C++ backend to all Jupyter interactive widget packages could be provided, creating a huge opportunity for interactive data visualization in C++.&lt;/p&gt;
&lt;h2 id="c-should-allow-overloading-the-dot-operator"&gt;C++ should allow overloading the dot operator&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;xwidgets&lt;/strong&gt; and &lt;strong&gt;xproperty&lt;/strong&gt; makes heavy use of value semantics, and proxy objects.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At the moment, to access an attribute or method of a value held in an xproperty object, we must first call the function call operator () to access the undelying object first, which is cumbersome.&lt;/li&gt;
&lt;li&gt;This is also an issue in other places in the xwidgets stack, when making use of &lt;em&gt;e.g.&lt;/em&gt; reference proxies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Being able to automatically map all methods of the underlying type to be accessible in the xproperty would be incredibly powerful, and remove the need for explicitly accessing the underlying.&lt;/p&gt;
&lt;p&gt;Interestingly, the C++ standard does have the equivalent operator overload when it comes to pointer semantics, with the arrow operator &lt;strong&gt;&lt;code&gt;-&amp;gt;&lt;/code&gt;&lt;/strong&gt;. If overloading the dot operator . was allowed, this could enable this kind of usecase:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;struct V
{
    void f();
};

struct X
{
    V&amp;amp; operator.() { return m_value; }
    V m_value;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;in which case, &lt;strong&gt;&lt;code&gt;X::f&lt;/code&gt;&lt;/strong&gt; would call &lt;strong&gt;&lt;code&gt;V::f&lt;/code&gt;&lt;/strong&gt; .&lt;/p&gt;
&lt;p&gt;Allowing the overloading of the dot operator . would also enable usecases such as &lt;strong&gt;smart references&lt;/strong&gt; (similar to smart pointers, but with value semantics) and fully-fledged &lt;strong&gt;reference proxies&lt;/strong&gt; (such as the return type of &lt;code&gt;operator[]&lt;/code&gt; for &lt;code&gt;std::vector&amp;lt;bool&amp;gt;&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id="try-it-online"&gt;Try it online!&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;a href="https://mybinder.org/"&gt;MyBinder&lt;/a&gt;, you can try xwidgets without the need of installing anything on your computer. Just follow this link:&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://mybinder.org/v2/gh/jupyter-xeus/xwidgets/stable?filepath=notebooks/xwidgets.ipynb"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/a-curiously-recurring-widget-library/images/005-0_TQpdhVZSAnE-XOrm.jpg" alt="&amp;quot;Launch binder&amp;quot; badge" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the author&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt; is the founder and CEO of &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;, an open-source software development studio comprising maintainers of key projects of the scientific computing ecosystem.&lt;/p&gt;
&lt;p&gt;As an open-source developer, Sylvain is very active in the Jupyter project, contributing to the &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;Xeus&lt;/a&gt; stack, Jupyter interactive widgets, &lt;a href="https://github.com/voila-dashboards/voila"&gt;Voilà dashboards&lt;/a&gt;. He is a member of the Jupyter steering committee and was the vice chair of &lt;a href="https://jupytercon.com/"&gt;JupyterCon 2020&lt;/a&gt;. Sylvain also contributes to the &lt;a href="https://conda-forge.org/"&gt;conda-forge&lt;/a&gt; project and he is the co-creator of the &lt;a href="https://github.com/xtensor-stack/xtensor"&gt;Xtensor&lt;/a&gt; C++ tensor algebra library.&lt;/p&gt;
</content><category term="C++"/><category term="widgets"/></entry><entry><title>Benjamin Ragan-Kelley</title><link href="https://jupyter.org/blog/posts/2020/benjamin-ragan-kelley/" rel="alternate"/><published>2020-10-03T21:02:00+00:00</published><updated>2025-04-10T15:24:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2020-10-03:/blog/posts/2020/benjamin-ragan-kelley/</id><summary type="html">&lt;p&gt;JupyterCon 2020 keynote speaker announcement&lt;/p&gt;
</summary><content type="html">&lt;figure&gt;
&lt;img alt="Benjamin Ragan Kelley" src="https://jupyter.org/blog/posts/2020/benjamin-ragan-kelley/images/001-1_AYnnhyE_AZjubmH_0h6a3g.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Benjamin Ragan Kelley&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It all started in April 2005 when freshman Min RK reached out to his physics professor, Brian Granger,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dr. Granger,&lt;br&gt;
Talking to you this afternoon prompted me to put the rather vague idea I had into a less vague writing, so I thought I would send you a better explanation of the application I had in mind…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;laying out his vision for an interactive development environment for computational physics. Reading this today, we can see how prescient that vision was, and included key elements of what Jupyter has become.&lt;/p&gt;
&lt;p&gt;Min then joined Brian and Fernando in contributing to IPython and became one of the main driving forces behind a project that has grown to global prominence, with a lasting influence on the entire field of scientific computing.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Screenshot of early web-based notebook experiments by Min Ragan-Kelley" src="https://jupyter.org/blog/posts/2020/benjamin-ragan-kelley/images/002-1_KAE0N_xnOR9iHM4opZW5cQ.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Some of Min’s early experiments for a web-based notebook.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The rest is history, Min has spent the following fifteen years contributing to IPython and Jupyter. We owe him some of the key components of the project such as JupyterHub. He was honored along with the rest of the Jupyter steering council with the &lt;a href="https://awards.acm.org/award_winners/ragan-kelley_7769426"&gt;2017 ACM Software System Award&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Today, Min is a senior research engineer and the head of the &lt;a href="https://www.simula.no/research/projects/department-numerical-analysis-and-scientific-computing"&gt;Department of Numerical Analysis and Scientific Computing&lt;/a&gt; at the &lt;a href="https://www.simula.no/"&gt;Simula Research Laboratory&lt;/a&gt; in Oslo, Norway.&lt;/p&gt;
&lt;p&gt;Beyond Jupyter, he has contributed widely to open source software, especially in the scientific Python community. He helps maintain numerous scientific packages in the conda-forge package management system.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;It is an honor for me to introduce Min’s keynote! We hope you will join us at the conference and enjoy his talk. There are only a few days left and it is still time to &lt;a href="https://www.eventbrite.com/e/jupytercon-2020-tickets-109183767588"&gt;sign up&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;— &lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt;, &lt;a href="https://jupytercon.com/"&gt;JupyterCon 2020&lt;/a&gt; Vice Chair&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2020/benjamin-ragan-kelley/images/003-0_8MVJWeKy1_BOYGpm.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The JupyterCon schedule of &lt;a href="https://cfp.jupytercon.com/2020/schedule/tutorial-sessions/"&gt;tutorials&lt;/a&gt; and &lt;a href="https://cfp.jupytercon.com/2020/schedule/general-sessions/"&gt;talks&lt;/a&gt; is published. &lt;a href="https://www.eventbrite.com/e/jupytercon-2020-tickets-109183767588"&gt;Join us&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content><category term="events"/><category term="JupyterCon"/></entry><entry><title>The templating system of nbconvert 6</title><link href="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/" rel="alternate"/><published>2020-09-26T07:31:00+00:00</published><updated>2020-09-26T08:20:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2020-09-26:/blog/posts/2020/the-templating-system-of-nbconvert-6/</id><summary type="html">&lt;p&gt;One of the main changes in nbconvert 6 is the refactor of the template system, which should be easier to extend and build upon.&lt;/p&gt;</summary><content type="html">&lt;p&gt;One of the main changes in nbconvert 6 is the refactor of the template system, which should be easier to extend and build upon.&lt;/p&gt;
&lt;p&gt;In this article, we dive into the template system, and provide a tutorial on how to build a custom template for &lt;a href="https://github.com/jupyter/nbconvert"&gt;nbconvert&lt;/a&gt; or &lt;a href="https://github.com/voila-dashboards/voila"&gt;Voilà&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="from-classic-to-lab"&gt;From Classic to Lab&lt;/h2&gt;
&lt;h3 id="my-notebooks-look-different"&gt;My notebooks look different!&lt;/h3&gt;
&lt;p&gt;If you are accustomed to convert notebook files to HTML by typing&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jupyter nbconvert notebook.ipynb --to html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;you may have noticed differences in the generated HTML when switching to the latest release of nbconvert. In fact, nbconvert now produces the same DOM structure as &lt;strong&gt;JupyterLab’s&lt;/strong&gt; notebook implementation, which is styled with JupyterLab’s CSS.&lt;/p&gt;
&lt;p&gt;One can even apply the &lt;strong&gt;dark theme&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jupyter nbconvert xleaflet.ipynb --to html --HTMLExporter.theme=dark
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="The HTML output of nbconvert with the lab template and the dark theme" src="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/images/001-1_9EeevFjz59QjiqAU9L3P-Q.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;HTML&lt;/strong&gt; output of nbconvert with the &lt;strong&gt;lab template&lt;/strong&gt; and the &lt;strong&gt;dark theme&lt;/strong&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;While JupyterLab uses CodeMirror to render code cells, nbconvert makes use of the &lt;a href="https://pygments.org/"&gt;&lt;strong&gt;Pygments&lt;/strong&gt;&lt;/a&gt; library to produce syntax-colored static HTML. To mimick the JupyterLab CodeMirror styling, we created a Pygments theme called &lt;a href="https://github.com/jupyterlab/jupyterlab_pygments"&gt;&lt;strong&gt;jupyterlab-pygments&lt;/strong&gt;&lt;/a&gt;. JupyterLab Pygments uses JupyterLab’s CSS variables for coloring and will therefore reflect the theme that is applied to the notebook.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; at the moment, only the default &lt;em&gt;&lt;strong&gt;light&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;dark&lt;/strong&gt;&lt;/em&gt; themes are supported, but we plan on adding support for third-party JupyterLab themes after the release of JupyterLab 3, which introduces a new packaging system for extensions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="but-i-wanted-my-notebooks-to-look-the-same"&gt;But I wanted my notebooks to look the same!&lt;/h3&gt;
&lt;p&gt;Well, if you want to retain the classic notebook styling that was used in earlier versions of CSS, it is still possible using the &lt;strong&gt;classic&lt;/strong&gt; template.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jupyter nbconvert xleaflet.ipynb --to html --template classic
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="The HTML output of nbconvert with the classic template" src="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/images/002-1_Bn333mVpbD3zu7iqWXH4hA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;HTML&lt;/strong&gt; output of nbconvert with the &lt;strong&gt;classic&lt;/strong&gt; &lt;strong&gt;template&lt;/strong&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;With this template, you retrieve the original style of nbconvert outputs and of the classic notebook.&lt;/p&gt;
&lt;p&gt;Another perk of the new nbconvert release is the &lt;strong&gt;WebPDF&lt;/strong&gt; exporter. The WebPDF exporter supports the same templates and themes as the HTML exporter, and produces a PDF output that renders the same rich content as the HTML exporter, such as rich HTML tables, widgets etc.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jupyter nbconvert xleaflet.ipynb --to webpdf --HTMLExporter.theme=dark
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="The WebPDF output of nbconvert with the lab template and the dark theme" src="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/images/003-1_82urGQO9ya4D_IMTNQtyWw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;WebPDF&lt;/strong&gt; output of nbconvert with the &lt;strong&gt;lab template&lt;/strong&gt; and the &lt;strong&gt;dark theme&lt;/strong&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="executing-the-notebook-before-rendering"&gt;Executing the notebook before rendering&lt;/h3&gt;
&lt;p&gt;Nbconvert’s two main categories of transformations are &lt;em&gt;&lt;strong&gt;preprocessors&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;exporters&lt;/strong&gt;&lt;/em&gt;. Preprocessors take a notebook as an input, and return a transformed notebook, while exporters return other types of content, such as HTML or PDF. An important preprocessor is the &lt;strong&gt;ExecutePreprocessor&lt;/strong&gt;, which spawns a kernel for the notebook, execute all cells, and populate outputs.&lt;/p&gt;
&lt;p&gt;It can be invoked before the export by passing &lt;code&gt;--execute&lt;/code&gt;. For example, the &lt;code&gt;xleaflet.ipynb&lt;/code&gt; notebook uses the &lt;a href="https://github.com/jupyter-xeus/xeus-cling"&gt;xeus-cling&lt;/a&gt; C++ kernel and makes use of the &lt;a href="https://github.com/jupyter-xeus/xleaflet"&gt;xleaflet&lt;/a&gt; interactive widget, which can be displayed when converting to HTML or with the WebPDF exporter.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jupyter nbconvert xleaflet.ipynb --to html --execute
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="The HTML output of nbconvert with the execute preprocessor" src="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/images/004-1_YmZfT8M_0wGCq9Ir8jYa6Q.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;HTML&lt;/strong&gt; output of nbconvert with the &lt;strong&gt;execute preprocessor&lt;/strong&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Similarly, the &lt;strong&gt;WebPDF&lt;/strong&gt; exporter will also display interactive widgets!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The PDF output of nbconvert with the execute preprocessor" src="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/images/005-1_nrUKm5eexRd9ReMergNnEw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;PDF&lt;/strong&gt; output of nbconvert with the &lt;strong&gt;execute preprocessor&lt;/strong&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Future plans for the WebPDF exporter include offering more options to users with respect to &lt;strong&gt;page breaks&lt;/strong&gt;, and providing &lt;strong&gt;bookmarks&lt;/strong&gt; for the main sections of the document.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="nbconvert-templates"&gt;Nbconvert templates&lt;/h2&gt;
&lt;p&gt;Unlike with earlier versions of nbconvert, templates are now &lt;strong&gt;directories&lt;/strong&gt;, which may contain a &lt;strong&gt;jinja&lt;/strong&gt; template but also other assets, such as macros, CSS files etc. The nbconvert template system also provides an inherittance mechanism which makes it simple to tweak existing templates in a derived one, by overriding bits of it.&lt;/p&gt;
&lt;h3 id="selecting-a-template"&gt;Selecting a template&lt;/h3&gt;
&lt;p&gt;Most exporters in nbconvert are subclasses of &lt;a href="https://nbconvert.readthedocs.io/en/latest/api/exporters.html#nbconvert.exporters.TemplateExporter"&gt;&lt;strong&gt;&lt;code&gt;TemplateExporter&lt;/code&gt;&lt;/strong&gt;&lt;/a&gt;, and make use of jinja to render notebooks into the destination format. Nbconvert templates can be selected by name with the &lt;code&gt;--template&lt;/code&gt; command line option.&lt;/p&gt;
&lt;p&gt;For example, the &lt;code&gt;reveal&lt;/code&gt; template, shipped with nbconvert, turns Jupyter notebooks into HTML &lt;strong&gt;slideshows&lt;/strong&gt; using the RevealJS library. Which cells should be skipped, or where breaks betweens slides should be, are specified in the notebook cell &lt;strong&gt;metadata&lt;/strong&gt;. The classic notebook and JupyterLab both provide means to set the appropriate values.&lt;/p&gt;
&lt;p&gt;To select the reveal template, simply type:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jupyter nbconvert &amp;lt;path-to-notebook&amp;gt; --to html --template reveal
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the case of the &lt;code&gt;xleaflet.ipynb&lt;/code&gt; notebook showed earlier, we get:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Creating a reveal slideshow with the dark theme" src="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/images/006-1_qXvACe6siMh8a2IfB2JDZw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Creating a reveal &lt;strong&gt;slideshow&lt;/strong&gt; with the dark theme&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This demonstrates that the nbconvert templating system can be used to completely override how we look at notebook documents. Using metadata, we can even create arbitrary layouts and rich views of the same content.&lt;/p&gt;
&lt;h3 id="where-are-nbconvert-templates-installed"&gt;Where are nbconvert templates installed?&lt;/h3&gt;
&lt;p&gt;Nbconvert 6 templates are &lt;strong&gt;directories&lt;/strong&gt; containing resources such as &lt;strong&gt;jinja&lt;/strong&gt; templates and other assets. They are installed in the data directory of nbconvert, namely &lt;code&gt;&amp;lt;installation prefix&amp;gt;/share/jupyter/nbconvert&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Running &lt;code&gt;jupyter --paths&lt;/code&gt; shows all Jupyter directories and search paths. For example, on Linux, &lt;code&gt;jupyter --paths&lt;/code&gt; returns:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;jupyter&lt;span class="w"&gt; &lt;/span&gt;--paths
config:
&lt;span class="w"&gt;    &lt;/span&gt;/home/&amp;lt;username&amp;gt;/.jupyter
&lt;span class="w"&gt;    &lt;/span&gt;/&amp;lt;sys-prefix&amp;gt;/etc/jupyter
&lt;span class="w"&gt;    &lt;/span&gt;/usr/local/etc/jupyter
&lt;span class="w"&gt;    &lt;/span&gt;/etc/jupyter
data:
&lt;span class="w"&gt;    &lt;/span&gt;/home/&amp;lt;username&amp;gt;/.local/share/jupyter
&lt;span class="w"&gt;    &lt;/span&gt;/&amp;lt;sys-prefix&amp;gt;/share/jupyter
&lt;span class="w"&gt;    &lt;/span&gt;/usr/local/share/jupyter
&lt;span class="w"&gt;    &lt;/span&gt;/usr/share/jupyter
runtime:
&lt;span class="w"&gt;    &lt;/span&gt;/home/&amp;lt;username&amp;gt;/.local/share/jupyter/runtime
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In our case, only the &lt;strong&gt;data&lt;/strong&gt; section is relevant. Listing the content of &lt;code&gt;&amp;lt;sys-prefix&amp;gt;/share/jupyter/nbconvert/templates&lt;/code&gt; in a raw installation of nbconvert will show&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;sys-prefix&amp;gt;/share/jupyter/nbconvert/templates
asciidoc&lt;span class="w"&gt; &lt;/span&gt;base&lt;span class="w"&gt; &lt;/span&gt;classic&lt;span class="w"&gt; &lt;/span&gt;compatibility&lt;span class="w"&gt; &lt;/span&gt;html&lt;span class="w"&gt; &lt;/span&gt;lab&lt;span class="w"&gt; &lt;/span&gt;latex&lt;span class="w"&gt; &lt;/span&gt;markdown&lt;span class="w"&gt; &lt;/span&gt;python&lt;span class="w"&gt; &lt;/span&gt;reveal&lt;span class="w"&gt; &lt;/span&gt;rst&lt;span class="w"&gt; &lt;/span&gt;script
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;base&lt;/code&gt; template should not be used directly, but is typically inherited from. The &lt;code&gt;compatibility&lt;/code&gt; directory provides some content for backward compatibility with earlier verions of nbconvert. Three templates are available for the HTML exporter: &lt;code&gt;lab&lt;/code&gt;, &lt;code&gt;classic&lt;/code&gt;, and &lt;code&gt;reveal&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="the-content-of-nbconvert-templates"&gt;The content of nbconvert templates&lt;/h3&gt;
&lt;h4 id="the-confjson-file"&gt;The &lt;code&gt;conf.json&lt;/code&gt; file&lt;/h4&gt;
&lt;p&gt;Nbconvert templates all include a &lt;strong&gt;conf.json&lt;/strong&gt; file used to indicate the base template that it is inheriting from, the mimetype corresponding to that template (which determines which exporters are compatible with it, and which file is the entry point), and preprocessors to run when using that template before running the exporter. For example, inspecting the configuration of the &lt;code&gt;reveal&lt;/code&gt; template we see that&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;it inherits from the &lt;code&gt;lab&lt;/code&gt; template,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;exports &lt;code&gt;text/html&lt;/code&gt;, and therefore will only work with the HTML and WebPDF exporters.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;and runs two preprocessors called &lt;code&gt;100-pygments&lt;/code&gt; and &lt;code&gt;500-reveal:&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;base_template&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;lab&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mimetypes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;text/html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;true&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;preprocessors&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;100-pygments&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;nbconvert.preprocessors.CSSHTMLHeaderPreprocessor&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;enabled&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;true&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;500-reveal&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;nbconvert.exporters.slides._RevealMetadataPreprocessor&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;enabled&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;true&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;CSSHTMLHeaderPreprocessor&lt;/code&gt; inlines the CSS required for the syntax highlighting of input cells.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;RevealMetadataPreprocessor&lt;/code&gt; massages the notebook metadata and consumes the information required to set up the layout of the slideshow.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nbconvert walks up the inheritance structure determined by &lt;code&gt;conf.json&lt;/code&gt; and produces an agregated configuration, merging the dictionaries of registered preprocessors. The ordering of the preprocessor names determines the order in which they will be run.&lt;/p&gt;
&lt;h4 id="jinja-templates"&gt;Jinja templates&lt;/h4&gt;
&lt;p&gt;Besides the &lt;code&gt;conf.json&lt;/code&gt; file, nbconvert templates most typically include jinja templates files. They may also override files from the base templates, or provide extra content.&lt;/p&gt;
&lt;p&gt;For example, inspecting the content of the &lt;code&gt;classic&lt;/code&gt; template located in &lt;code&gt;share/jupyter/nbconvert/templates/classic&lt;/code&gt;, we find the following content:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;share/jupyter/nbconvert/templates/classic
├── static
│   └── styles.css
├── conf.json
├── index.html.j2
└── base.html.j2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;we see that it includes the &lt;code&gt;index.html.j2&lt;/code&gt; jinja template (which is the main entry point for HTML exporters) as well as CSS and a base template file in &lt;code&gt;base.html.j2&lt;/code&gt;. The only preprocessor listed in &lt;code&gt;conf.json&lt;/code&gt; is the pygments syntax highlighting…&lt;/p&gt;
&lt;h3 id="inheritance-in-jinja"&gt;Inheritance in Jinja&lt;/h3&gt;
&lt;p&gt;In nbconvert, jinja templates can inherit from any other jinja template available in its current directory or base template directory by name. Jinja templates of other directories can be addressed by their path from the Jupyter data directory. Using the path is also useful when using a jinja template that may be overriden locally.&lt;/p&gt;
&lt;p&gt;For example, in the reveal template, &lt;code&gt;index.html.j2&lt;/code&gt; extends &lt;code&gt;base.html.j2&lt;/code&gt; which is in the same directory, and &lt;code&gt;base.html.j2&lt;/code&gt; extends &lt;code&gt;lab/base.html.j2&lt;/code&gt;. This approach allows using content that is available in other templates or may be overriden in the current template.&lt;/p&gt;
&lt;h2 id="building-a-custom-template"&gt;Building a custom template&lt;/h2&gt;
&lt;p&gt;Now, let’s create a custom template! If you work at ACME Corporation, you may want to create a template that follows the graphical charter of ACME Corp, and includes the logo in a banner.&lt;/p&gt;
&lt;p&gt;Besides the logo, titles should also use the “&lt;a href="https://fonts.google.com/specimen/Acme"&gt;ACME Regular&lt;/a&gt;” font, which has a cartoon-style look. The other parts of the template are inherited from the regular lab template.&lt;/p&gt;
&lt;p&gt;Setting up a logo banner, and the font change, the &lt;code&gt;acme&lt;/code&gt; nbconvert template produces the following result with a very simple notebook:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jupyter nbconvert acme.ipynb --to html --template acme
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="The HTML output of nbconvert with the acme template" src="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/images/007-1_jhxkC7lv5SFirR-xfQJpsA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;HTML&lt;/strong&gt; output of nbconvert with the &lt;strong&gt;acme template&lt;/strong&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Now you can create sophisticated templates making use of sophisticated front-end framework and processing the notebook metadata in creative ways!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The source for the ACME nbconvert template is available &lt;a href="https://github.com/SylvainCorlay/nbconvert-acme/"&gt;here&lt;/a&gt;.&lt;br&gt;
Beyond the template files in &lt;code&gt;share/jupyter/nbconvert/acme&lt;/code&gt;, the repo provides the logic for packaging this template into a PyPI wheel with data files. You will also find content related to the use of that template with Voilà, which is the subject of the next section.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="from-nbconvert-templates-to-voila-templates"&gt;From nbconvert templates to Voilà templates&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/images/008-1_BTJSFb_pQ8TSVwc6bPgjbA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/voila-dashboards/voila"&gt;&lt;strong&gt;Voilà&lt;/strong&gt;&lt;/a&gt; turns Jupyter notebooks into standalone web applications and &lt;strong&gt;dashboards&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It differs from nbconvert in that the output web application is connected to a Jupyter kernel, allowing it to respond to user input through widget controls and other UI components, while with nbconvert, any action that requires a roundtrip to the kernel will not work.&lt;/p&gt;
&lt;p&gt;However, &lt;strong&gt;Voilà leverages the nbconvert template system&lt;/strong&gt; to benefit from their flexibility in overriding the front-end looks and behavior. From a user standpoint, the system is made so that the same templates will be usable for both systems.&lt;/p&gt;
&lt;p&gt;However, template authors interested in advanced features of Voilà may be interested in the following information.&lt;/p&gt;
&lt;h3 id="where-are-voila-templates-installed"&gt;Where are Voilà templates installed?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Voilà templates are installed in the &lt;code&gt;&amp;lt;installation prefix&amp;gt;/share/jupyter/voila&lt;/code&gt; directory (while nbconvert templates are in &lt;code&gt;&amp;lt;installation prefix&amp;gt;/share/jupyter/nbconvert&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Just like nbconvert templates, Voilà templates are directories, they use the same &lt;code&gt;conf.json&lt;/code&gt; configuration mechanism.&lt;/li&gt;
&lt;li&gt;Voilà can use nbconvert HTML templates without modification.&lt;/li&gt;
&lt;li&gt;When there exists an nbconvert and a Voilà template of the same name, the conf.json files are recursively merged, as well as the content of the directory, with a higher precedence for the Voilà template.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="overriding-nbconvert-templates-with-voila"&gt;Overriding nbconvert templates with Voilà&lt;/h3&gt;
&lt;p&gt;When specifying the &lt;code&gt;acme&lt;/code&gt; template that we developed earlier, with command&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;voila xleaflet.ipynb --template acme
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Voilà will look pick up the acme nbconvert template. Since this template inherits from lab and Voilà has an overridden lab template (with e.g. the logic for rendering widgets), it will pick up the Voilà flavor of the lab template. Most typically, the Voilà flavor of a template does not add much on top of nbconvert besides boilerplate such as&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a call to the macro that includes the &lt;strong&gt;JavaScript assets&lt;/strong&gt; for the Voilà front-end logic.&lt;/li&gt;
&lt;li&gt;calls to macro related to &lt;strong&gt;error logging&lt;/strong&gt; when using the Voilà preview.&lt;/li&gt;
&lt;li&gt;calls to macros related to the &lt;strong&gt;progressive rendering&lt;/strong&gt; of notebooks as it is being executed, and the display of an “in-progress” &lt;strong&gt;spinner&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These macros are provided in the &lt;code&gt;base&lt;/code&gt; Voilà template, and can also be overridden in derived templates.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2020/the-templating-system-of-nbconvert-6/images/009-1_ey1ie8kpgPMTvHU6nvjKvw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;h2 id="future-developments"&gt;Future developments&lt;/h2&gt;
&lt;p&gt;In the coming weeks and months, we plan on polishing the experience of nbconvert users.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JupyterLab 3, which should be released shortly, includes a more dynamic extension system which does not require the main JupyterLab application to be rebuilt. We plan on adding support for a category of lab extensions called “&lt;strong&gt;mime renderers&lt;/strong&gt;“ which are used for rich rendering of data in cell outputs. This should enable the use of complex mime types such as GeoJSON or Vega visualizations in nbconvert and Voilà.&lt;/li&gt;
&lt;li&gt;We are working on improving the &lt;code&gt;reveal&lt;/code&gt; template, to include a &lt;strong&gt;custom reveal theme&lt;/strong&gt; making use of JupyterLab CSS variables, so that it can be easily combined with JupyterLab themes.&lt;/li&gt;
&lt;li&gt;The JupyterLab 3 extension system may also enable us to enable &lt;strong&gt;third-party JupyterLab themes&lt;/strong&gt; in nbconvert.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;WebPDF&lt;/strong&gt; exporter should expose options on output format and where page breaks should be. At the moment, we prevent page breaks until the maximum dimensions of PDF documents are reached.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;Many people were involved in the nbconvert 6 release! The full list of contributors is available &lt;a href="https://nbconvert.readthedocs.io/en/latest/changelog.html#id7"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Among them, we are especially indebted to &lt;a href="https://twitter.com/maartenbreddels"&gt;&lt;strong&gt;Maarten Breddels&lt;/strong&gt;&lt;/a&gt;, who was the main architect of the new template system.&lt;/li&gt;
&lt;li&gt;We owe the split of the execute preprocessor and the new &lt;strong&gt;nbclient&lt;/strong&gt; package to &lt;a href="https://twitter.com/codeseal"&gt;&lt;strong&gt;Matthew Seal&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://twitter.com/davidbrochart"&gt;&lt;strong&gt;David Brochart&lt;/strong&gt;&lt;/a&gt;. Matthew took on a large amount of maintenance work on the project over the past year.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The work on Voilà and nbconvert by the QuantStack team was funded by &lt;a href="https://www.techatbloomberg.com/"&gt;Bloomberg&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p&gt;Sylvain Corlay is the CEO of &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;, an open-source software development team specialized scientific computing comprising maintainers of major projects of the ecosystem.&lt;/p&gt;
&lt;p&gt;As an open-source developer, Sylvain is mostly active in the Jupyter ecosystem, and the general PyData stack. He is currently a steering committee member for Project Jupyter, and a member of the board of directors of NumFOCUS.&lt;/p&gt;
</content><category term="publishing"/></entry><entry><title>SlicerJupyter: a 3D Slicer kernel for interactive publications</title><link href="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/" rel="alternate"/><published>2020-07-08T16:29:00+00:00</published><updated>2020-07-08T16:58:00+00:00</updated><author><name>Jean-Christophe Fillion-Robin</name></author><id>tag:jupyter.org,2020-07-08:/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/</id><summary type="html">&lt;p&gt;Use Jupyter and 3D Slicer kernel to implement biomedical data processing workflows in a notebook.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Use Jupyter and 3D Slicer kernel to implement biomedical data processing workflows in a notebook.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The Jupyter ecosystem is a powerful platform for exploratory computational science, and now it can connect with some of the deep and rich domain-specific desktop applications that have decades of feature development already invested in them. With the integration of &lt;a href="https://www.slicer.org/"&gt;3D Slicer&lt;/a&gt; with Jupyter through the &lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt;’s interpreter, we demonstrate how a &lt;a href="https://www.qt.io/"&gt;Qt-based&lt;/a&gt; graphical desktop application with 3D visualization provided by &lt;a href="https://vtk.org/"&gt;Visualization Toolkit (VTK)&lt;/a&gt;, image processing provided by the &lt;a href="https://itk.org/"&gt;Insight Toolkit (ITK)&lt;/a&gt;, can be used through a Jupyter notebook. This approach is available on the &lt;a href="https://github.com/Slicer/SlicerJupyter"&gt;SlicerJupyter&lt;/a&gt; GitHub repository and could be extended to other applications that embed Python, such as Blender, FreeCAD, or ParaView.&lt;/p&gt;
&lt;p&gt;This xeus-python integration is beneficial both for the Jupyter ecosystem and desktop applications. Features that have been developed for decades for desktop applications become readily available for Jupyter users without learning a new working environment or redeveloping features. For a desktop application, the Jupyter notebook can serve as a way to create reproducible data processing workflows, scientific publications, and maintainable tutorials without requiring local software installation. From Jupyter, you can now quickly create simple medical imaging applications with extremely rich interactivity from 3D Slicer. Read below for a discussion of the features available and the history of the project.&lt;/p&gt;
&lt;h2 id="powerful-medical-imaging-capabilities-available-through-jupyter"&gt;Powerful Medical Imaging Capabilities Available Through Jupyter&lt;/h2&gt;
&lt;p&gt;3D Slicer (or Slicer for short) is a C++ desktop application that uses Qt, ITK, and VTK libraries for visualization and medical image analysis. Slicer’s embedded Python interpreter makes all its features accessible with the Python programming language. Slicer has a simple built-in console to run Python commands interactively and can run Python scripts from files, but these are not as convenient as cell-base interactive notebooks, which have become popular among data scientists and researchers in recent years.&lt;/p&gt;
&lt;p&gt;By integrating the xeus-python kernel, we can use a Slicer process as a Jupyter kernel. xeus-python leverages the &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;xeus&lt;/a&gt; C++ implementation of the Jupyter kernel protocol. xeus-python is &lt;a href="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/"&gt;an alternative to ipykernel&lt;/a&gt;, which can be used with a vanilla CPython interpreter, interfacing to standard CPython Jupyter widgets like &lt;a href="https://github.com/InsightSoftwareConsortium/itkwidgets"&gt;itkwidgets&lt;/a&gt;, but it can also be coupled with custom interpreters and GUI event loops, like the Slicer interpreter and its Qt event loop. This allows you to represent a complete scene in Medical Reality Markup Language, MRML, Slicer’s internal data structure. The kernel exposes the full medical imaging API and representation of your data in a meaningful way for Python developers, allowing access through standard Python ecosystem formats such as pandas dataframes and NumPy arrays in the Notebook.&lt;/p&gt;
&lt;h3 id="interactivity-levels"&gt;Interactivity Levels&lt;/h3&gt;
&lt;p&gt;You can also use Jupyter interactive widgets (sliders, buttons, etc.) to control Slicer, modify data, or adjust processing and visualization parameters. Interactivity can be implemented at different levels.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Level 1&lt;/strong&gt;: Standard Jupyter widgets display application specific objects by automatic conversion of application-specific data objects to standard Python objects. For example, Slicer markup fiducial lists are displayed as a nicely formatted table and model nodes are rendered as 3D objects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Level 2&lt;/strong&gt;: Static image widgets display content that the desktop application renders. These widgets can be made interactive by modifying data and rendering parameters using additional standard widgets. This makes rich visualization capabilities — sophisticated rendering various data types, rendering of very large data sets, etc. directly available in Jupyter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Level 3&lt;/strong&gt;: Dynamic viewer widgets display 2D and 3D views rendered by the desktop application. Mouse and keyboard events are forwarded to the desktop application that allows zooming/rotating views, and to utilize all 3D interactions implemented in the desktop such as placing annotations, making measurements, or segmenting images the same way as if it was done on the desktop appication’s screen. This is implemented in the Slicer Jupyter kernel using &lt;a href="https://ipycanvas.readthedocs.io/en/latest/"&gt;ipycanvas&lt;/a&gt; and &lt;a href="https://github.com/mwcraig/ipyevents"&gt;ipyevents&lt;/a&gt; packages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Level 4&lt;/strong&gt;: Full desktop graphical user interface integration. Users can see parts of the application window rendered in notebook cells, including standard desktop widgets (sliders, menus, etc.). It is implemented using noVNC and TigerVNC in Slicer Jupyter. This is particularly useful when the application runs on a remote server.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/oZ3_cRXX2QM" title="Medical image processing in your web browser using Jupyter notebooks and 3D Slicer" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;
&lt;p&gt;Video demonstrating how to run 3D Slicer using Binder&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;These interactive tools allow developers to implement complete data processing workflows in a notebook, even if certain steps require manual user inputs such as segmenting 3D regions or setting seed points.&lt;/p&gt;
&lt;h3 id="try-it-online"&gt;Try it online!&lt;/h3&gt;
&lt;p&gt;Since Jupyter notebooks can be used from any web browser, it can essentially turn any desktop application to a web application. By setting up a remote Jupyter server, users do not have to install anything on their computers. We have set up a demonstration of this using Binder (&lt;a href="http://www.mybinder.org"&gt;www.mybinder.org&lt;/a&gt;) that anybody can try at &lt;a href="https://mybinder.org/v2/gh/Slicer/SlicerNotebooks/master"&gt;https://mybinder.org/v2/gh/Slicer/SlicerNotebooks/master&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://mybinder.org/v2/gh/Slicer/SlicerNotebooks/master"&gt;&lt;img alt="Click on the binder image to launch the demo" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/001-0_powLrWNrbtb0dRWs.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;Click on the binder image to launch the demo&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The docker image that installs and configures Slicer and all dependencies (ipycanvas, ipyevents, VNC, etc.) is available at &lt;a href="https://github.com/Slicer/SlicerDocker/tree/master/slicer-notebook"&gt;https://github.com/Slicer/SlicerDocker/tree/master/slicer-notebook&lt;/a&gt;. For deployment to non-technical users, applications can be deployed using Voilà (&lt;a href="https://voila.readthedocs.io/"&gt;https://voila.readthedocs.io/&lt;/a&gt;), which only shows relevant content and interactive widgets, so the notebook looks like a simple dynamic web page.&lt;/p&gt;
&lt;p&gt;The current implementation is already stable and offers a wide range of features, but there is still room for design and performance improvements. For example, we could not implement fully automatic conversion of application-specific data objects to displayable Python objects (due to complex implementation of display hooks); xeus-python debugger’s threading model needs to be improved to allow using it without locking the application’s main thread; and dynamic viewer widget’s performance (level 3 interaction) could be optimized to achieve higher refresh rates.&lt;/p&gt;
&lt;h2 id="history-of-slicer-and-this-integration"&gt;History of Slicer and this integration&lt;/h2&gt;
&lt;p&gt;Built over two decades with support from the NIH and a worldwide open source developer community, 3D Slicer is a unique, multi-platform desktop application for analysis, integration, and visualization of medical images that is heavily used by researchers globally for basic and applied research in a wide range of topics. The 3D Slicer Community includes physician-scientists with disease-specific knowledge of clinical challenges, computer scientists and physicists who develop novel algorithms, imaging informatics researchers, software engineers with the ability to understand clinical problems and create reliable tools, and application engineers with the multidisciplinary skills to deploy these tools in a range of cancer research settings. Slicer is maintained by Kitware, Inc., and the NAMIC consortium, and has an active open source software community. Slicer is used in hospitals and by researchers, with more than 10k academic citations and more than 150k downloads in the last year alone.&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://download.slicer.org"&gt;&lt;img alt="Click on the image to download 3D Slicer" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/002-1_ePhHKkjqV-AW0mvDkaeurw.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;Click on the image to download 3D Slicer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It can be used for image processing workflows on 2D, 3D, and 4D images. What makes Slicer so useful is its huge set of community contributed modules that extend its functionality, as well as its ability to read DICOM and a wide array of exotic file formats.&lt;/p&gt;
&lt;p&gt;Slicer has been scriptable in Python for well over a decade, but a robust &lt;a href="https://github.com/Slicer/SlicerJupyter"&gt;SlicerJupyter&lt;/a&gt; extension is born from significant development effort by the community. The idea for this integration dates back to SciPy in 2014, when Jean-Christophe Fillion-Robin of Kitware organized a sprint intended to integrate Slicer and an IPython notebook, motivated by the dream of creating interactive and fun tutorials for Slicer. Mike Sarahan and Jean-Christophe created this proof of concept &lt;a href="https://github.com/commontk/QEmbedIPython#qt-embed-ipython"&gt;https://github.com/commontk/QEmbedIPython#qt-embed-ipython&lt;/a&gt;, but it was far from usable. In 2015 Matt McCormick of Kitware, created the &lt;a href="https://github.com/Slicer/SlicerDocker"&gt;SlicerDocker&lt;/a&gt; repository to support headless builds and rendering in a Docker image. Then in June 2018, while attending the Slicer Project Week, Andras Lasso (Queen’s University) and Jean-Christophe learned about Xeus, a C++ implementation of the Jupyter kernel protocol developed by QuantStack that would help streamline the integration of Slicer with Jupyter. To support this effort, Andras and Jean-Christophe created the &lt;a href="https://github.com/Slicer/SlicerJupyter"&gt;Slicer/SlicerJupyter&lt;/a&gt; GitHub repository. They also contributed changes to Xeus to support this new integration paradigm where the event loop of the kernel is driven by a Qt-based Desktop application (see &lt;a href="https://github.com/jupyter-xeus/xeus/pull/63"&gt;here&lt;/a&gt;). Building on this foundation, Isaiah Norton, then working at Brigham and Women’s Hospital, contributed additional improvements like a better auto-completion using jedi (see &lt;a href="https://github.com/Slicer/SlicerJupyter/pull/12"&gt;https://github.com/Slicer/SlicerJupyter/pull/12&lt;/a&gt;) as well as integration with Binder. More recently, Jean-Christophe and Sylvain Corlay (QuantStack) met after the Slicer project week while attending SciPy in Austin. Following the creation of a new project called xeus-python (started by Martin Renou at QuantStack), we took the integration of Jupyter and Slicer to the next level by adding support for improved interactive use and MRML data node visualization directly in the notebook.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the authors&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Alphabetically ordered&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sylvain Corlay&lt;/strong&gt; is the founder and CEO of QuantStack, and a core Jupyter developer. He co-authored xeus and xeus-python.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Sylvain Corlay" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/003-1_DKAhOe_Y4JdGYkgi9jHBSQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Sylvain Corlay&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Jean-Christophe Fillion-Robin&lt;/strong&gt; is an open-source enthusiast, original author of the SlicerJupyter extension and a principal engineer at Kitware Inc where he leads the development of “3D Slicer” based commercial applications. J-Christophe also maintains &lt;a href="https://scikit-build.org"&gt;scikit-build&lt;/a&gt;, an improved build system generator for CPython C/C++/Fortran/Cython extensions.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Jean-Christophe Fillion-Robin" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/004-1_slg9clPxU3DhL4W2pE2kCA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Jean-Christophe Fillion-Robin&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Mike Grauer&lt;/strong&gt; is a Technical Leader on the data and analytics team at Kitware. He is specialized in building scalable server-side processing frameworks that enable scientific workflows over web platforms.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Mike Grauer" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/005-1_SuBw-BD8efPla8tfd98RUg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Mike Grauer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Andras Lasso&lt;/strong&gt; is an original author of the SlicerJupyter extension, Senior Research Engineer and Associate Director of the Laboratory for Percutaneous Surgery at Queen’s University.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Andras Lasso" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/006-1_kINpFRIt94iHaxTA90zncQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Andras Lasso&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Matt McCormick&lt;/strong&gt; is an open source, medical imaging researcher working at Kitware Inc. Matt is an active, contributing member of scientific open source software efforts such as the Insight Toolkit (ITK) and scientific Python (SciPy) communities, and maintains the Jupyter 3D widget, &lt;a href="https://github.com/InsightSoftwareConsortium/itkwidgets"&gt;itkwidgets&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Matt McCormick" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/007-1_Pm17Os2v8Kf_GiZQw1G_ZQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Matt McCormick&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Isaiah Norton&lt;/strong&gt; is a Senior Software Developer at TileDB, Inc. with experience in digital pathology and image-guided surgical navigation.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Isaiah Norton" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/008-1_eR4Y9MX-2lcRsXEKodCJrQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Isaiah Norton&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Steve Pieper&lt;/strong&gt; is a Chief Architect and active developer of the 3D Slicer application for well over a decade. He is CEO of Isomics, Inc, where he uses a range of software technologies to perform medical imaging research with leading universities and companies.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Steve Pieper" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/009-1_aNwZz5TLENXuS2WQRb_N9w.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Steve Pieper&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Martin Renou&lt;/strong&gt; is a scientific software developer at QuantStack. He is the original author of xeus-python, the xeus-based Python kernel, and contributed to the new concurrency model used for the debugger.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Martin Renou" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/010-1_Cy9QfZytimqXQut2-bdcIA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Martin Renou&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Mike Sarahan&lt;/strong&gt; is a software engineer at RStudio, PBC working on bringing language ecosystems together. He is passionate about making software work for data scientists in ways that are easy to maintain and improve.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Mike Sarahan" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/011-1_YKNdPIBH39iFBIL9nD_kfg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Mike Sarahan&lt;/figcaption&gt;
&lt;/figure&gt;
</content><category term="kernels"/><category term="science"/><category term="visualization"/></entry><entry><title>Report on the Jupyter Community Workshop on Dashboarding</title><link href="https://jupyter.org/blog/posts/2020/report-on-the-jupyter-community-workshop-on/" rel="alternate"/><published>2020-02-14T21:06:00+00:00</published><updated>2020-02-14T21:06:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2020-02-14:/blog/posts/2020/report-on-the-jupyter-community-workshop-on/</id><summary type="html">&lt;p&gt;This report is long overdue! From June 3rd to June 6th 2019, thirty-five developers from the Jupyter community met in Paris for a four-day workshop on dashboarding with Project Jupyter.&lt;/p&gt;</summary><content type="html">&lt;p&gt;This report is long overdue! From June 3rd to June 6th 2019, thirty-five developers from the Jupyter community met in Paris for a four-day workshop on dashboarding with Project Jupyter.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Attendees to the Jupyter Community Workshop on Dashboarding (Photo credit to Lindsey Heagy)" src="https://jupyter.org/blog/posts/2020/report-on-the-jupyter-community-workshop-on/images/001-1_e8gJ4j2hCn4XMPagp6etOA.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Attendees to the Jupyter Community Workshop on Dashboarding (Photo credit to Lindsey Heagy)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For four days, attendees worked full time on the Jupyter project, including hacking sessions and discussions on improvements to Jupyter components and new development. We were lucky to count a large number of core developers to the project in the group.&lt;/p&gt;
&lt;p&gt;Beyond the hacking sessions, each day was concluded with a series of presentations and demos of the progress made during the workshop. In partnership with the &lt;a href="https://twitter.com/pydataparis"&gt;PyData Paris&lt;/a&gt; team, we had a special installment of the PyData Paris Meetup with&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;an invited presentation by &lt;a href="https://twitter.com/egouillart"&gt;Emmanuelle Gouillart&lt;/a&gt; on &lt;a href="https://plot.ly/dash/"&gt;Plotly Dash&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;a series of lightning talks by attendees of the workshop on their achievements, including a talk by &lt;a href="https://github.com/philippjfr"&gt;Philip Rudiger&lt;/a&gt; on the first release of &lt;a href="https://github.com/holoviz/panel"&gt;Panel&lt;/a&gt;, and an announcement of the first releases of &lt;a href="https://github.com/voila-dashboards/voila"&gt;Voilà&lt;/a&gt; and the Voilà Gallery.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We ended the week with a social evening at the &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; offices in Paris.&lt;/p&gt;
&lt;h2 id="why-a-workshop-on-jupyter-dashboarding-with-jupyter"&gt;Why a workshop on Jupyter Dashboarding with Jupyter?&lt;/h2&gt;
&lt;p&gt;The Jupyter ecosystem is used extensively in scientific computing both in academia and industry, and a rich ecosystem of data visualization tools has been developed around the Jupyter widgets frameworks, from geographical data visualization to protein folding simulation.&lt;/p&gt;
&lt;p&gt;However, the Jupyter ecosystem still did not provide a means for developers to transition from notebooks to stand-alone web applications that can be accessed by multiple users.&lt;/p&gt;
&lt;p&gt;This has been a longstanding request from the community: provide better tools built upon the Jupyter stack to share results with students, peers, or the general public.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;These are the challenges that we decided to tackle during that week. The workshop was attended by many Jupyter core developers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="highlights-of-the-week"&gt;Highlights of the week&lt;/h2&gt;
&lt;p&gt;Many of the developers spent the week working on the Voilà and Panel projects. Both projects had their first public releases during that week (see the first public announcement of &lt;a href="https://medium.com/@philipp.jfr/panel-announcement-2107c2b15f52"&gt;Panel&lt;/a&gt; and &lt;a href="https://jupyter.org/blog/posts/2019/and-voila/"&gt;Voilà&lt;/a&gt;).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;During this week, a team of participants including Yuvi Panda, Pascal Bugnion, and Jeremy Tuloup iterated on the first version of the Voilà gallery. Several first-time contributors to the widget framework authored example dashboards for the gallery, showcasing their existing work. Yuvi also produced the first deployment scenarii for Voilà on Heruku.&lt;/li&gt;
&lt;li&gt;Cheryl Quah, from Bloomberg MC-ed a panel on dashboarding in the Jupyter ecosystem, including lots of questions and comparisons with Dash.&lt;/li&gt;
&lt;li&gt;Philip Rudigger started working on a Bokeh/ipywidgets integration for better interoperability between the two frameworks.&lt;/li&gt;
&lt;li&gt;Other contributors iterated on creating new Voilà templates, such as voila-vuetify, adding the ability to position Jupyter widgets and outputs in arbitrary location in the dashboard template. Grant Nestor created visual mockups for a UI for creating dashboard layouts in JupyterLab. Grant also helped iterating on logos for the project, and gave a presentation on dynamically loading JavaScript modules in the browser.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;This event would not have been possible without the generous support provided by &lt;a href="https://www.techatbloomberg.com/"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;, who made this workshop series possible&lt;/p&gt;
&lt;p&gt;We are grateful to &lt;a href="https://twitter.com/SG_CIB"&gt;&lt;strong&gt;Société Générale&lt;/strong&gt;&lt;/a&gt; for funding the catering for the workshop.&lt;/p&gt;
&lt;p&gt;The hosting of the workshop at &lt;a href="https://cri-paris.org/"&gt;CRI&lt;/a&gt; was paid for by &lt;a href="https://twitter.com/QuantStack"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The public meetup was organized in partnership with the &lt;a href="https://twitter.com/pydataparis"&gt;&lt;strong&gt;PyData Paris&lt;/strong&gt;&lt;/a&gt; team.&lt;/p&gt;
&lt;p&gt;Finally, we especially thank &lt;a href="https://twitter.com/ruv7?lang=en"&gt;&lt;strong&gt;Ana Ruvalcaba&lt;/strong&gt;&lt;/a&gt; from Project Jupyter for her incredible work on the logistics and finances of the Jupyter Community Workshop series.&lt;/p&gt;
</content><category term="dashboards"/><category term="events"/><category term="visualization"/><category term="workshops"/></entry><entry><title>Voilà is now a Jupyter subproject</title><link href="https://jupyter.org/blog/posts/2019/voila-is-now-an-official-jupyter-subproject/" rel="alternate"/><published>2019-12-29T12:11:00+00:00</published><updated>2019-12-29T12:15:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2019-12-29:/blog/posts/2019/voila-is-now-an-official-jupyter-subproject/</id><summary type="html">&lt;p&gt;It is a great pleasure to announce that the Voilà project has been incorporated as a Jupyter subproject. Voilà will now be subject to the Jupyter governance and code of conduct.&lt;/p&gt;</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;It is a great pleasure to announce that the Voilà project has been incorporated as a Jupyter subproject. Voilà will now be subject to the &lt;a href="https://github.com/jupyter/governance/blob/master/governance.md"&gt;Jupyter governance&lt;/a&gt; and &lt;a href="https://github.com/jupyter/governance/blob/master/conduct/code_of_conduct.md"&gt;code of conduct&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For reference, the Jupyter Enhancement Proposal (JEP) for the Voilà incorporation is available &lt;a href="https://github.com/jupyter/enhancement-proposals/pull/42"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="what-is-voila"&gt;What is Voilà?&lt;/h2&gt;
&lt;p&gt;Voilà helps you communicate insights, by transforming a Jupyter Notebook into a stand-alone web application you can share. It gives you control over what your readers experience in a secure and customizable interactive dashboard.&lt;/p&gt;
&lt;p&gt;The easiest way to get started with Voilà is to install it via &lt;code&gt;pip&lt;/code&gt; or &lt;code&gt;conda&lt;/code&gt; and type &lt;code&gt;voila some_notebook.ipynb&lt;/code&gt; to turn the said notebook into a dashboard.&lt;/p&gt;
&lt;p&gt;Besides, Voilà includes a templating system that allows to overload the behavior of the front-end. Using this templating system, Voilà can be used to create&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;slideshows (with voila-reveal)&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A Voilà slideshow created with the voila-reveal template." src="https://jupyter.org/blog/posts/2019/voila-is-now-an-official-jupyter-subproject/images/001-1_mp59BtUkz046smQek2-BFA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A Voilà slideshow created with the voila-reveal template.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;dashboards (with voila-gridstack)&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A Voilà Dashboard based on the voila-gridstack template." src="https://jupyter.org/blog/posts/2019/voila-is-now-an-official-jupyter-subproject/images/002-1_P447LmtfAnhIcCol6q6FBw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A Voilà Dashboard based on the voila-gridstack template.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="why-moving-voila-under-the-jupyter-governance"&gt;Why moving Voilà under the Jupyter governance?&lt;/h2&gt;
&lt;p&gt;While the project was initially started by QuantStack, the team now comprises developers from Bloomberg, UC Berkeley, JP Morgan, and Cal Poly San Luis Obispo. OVH has been supportive of the project by kindly providing the free hosting of the gallery on their infrastructure.&lt;/p&gt;
&lt;p&gt;We believe that the &lt;em&gt;&lt;strong&gt;multi-stakeholder&lt;/strong&gt;&lt;/em&gt; nature of the Voilà project is well-suited for the Jupyter organization.&lt;/p&gt;
&lt;p&gt;The Voilà project is largely built upon Jupyter subprojects and standards.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The standard &lt;strong&gt;notebook file format&lt;/strong&gt; is the main entry point to Voilà.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;nbconvert&lt;/strong&gt; is used for the conversion to progressively-rendered HTML.&lt;/li&gt;
&lt;li&gt;naturally, we use &lt;strong&gt;jupyter_client&lt;/strong&gt; for handling the execution of notebook cells&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;jupyter_server&lt;/strong&gt; is the default back-end.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JupyterHub&lt;/strong&gt; is at the foundation of the voila-gallery project.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JupyterLab&lt;/strong&gt; components (mime renderers, input and output areas) are used in the front-end implementation. Voilà also includes a preview JupyterLab extension.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ipywidgets&lt;/strong&gt; and custom jupyter widget libraries such as bqplot, ipyvolume, ipyleaflets provide the bulk of the interactivity of Voilà applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voilà is more a &lt;em&gt;remix&lt;/em&gt; of existing Jupyter components (with changes to enable that use case) than a completely new application.&lt;/p&gt;
&lt;h2 id="resources"&gt;Resources&lt;/h2&gt;
&lt;p&gt;Should you be interested in Voilà, feel free to try it on Binder or locally! You can also engage with the developer community during our public team meetings and the various GitHub repositories of the project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the Voilà &lt;strong&gt;GitHub repository&lt;/strong&gt; is available here: &lt;a href="https://github.com/voila-dashboards/voila"&gt;https://github.com/voila-dashboards/voila&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;Documentation&lt;/strong&gt; is hosted on &lt;em&gt;Read the Docs&lt;/em&gt;: &lt;a href="https://voila.readthedocs.io"&gt;https://voila.readthedocs.io&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;Team Compass&lt;/strong&gt; holds the calendar for the public developer meetings, as well as the meeting minutes: &lt;a href="https://voila-dashboards.github.io"&gt;https://voila-dashboards.github.io&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;Announcement&lt;/strong&gt; of the first Voilà release was published on this blog: &lt;a href="https://jupyter.org/blog/posts/2019/and-voila/"&gt;And voilà!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Voilà was started by the team of open-source developers at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; as a separate project, but with the full intent to incorporate it into Jupyter. The initial project development at QuantStack was funded by &lt;a href="https://twitter.com/techatbloomberg"&gt;Bloomberg&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Now, Voilà contributors work in many institutions, including UC Berkeley, Cal Poly San Luis Obispo, JP Morgan, and Faculty (formerly ASI Data Science).&lt;/li&gt;
&lt;li&gt;The Voilà Gallery is kindly hosted by &lt;a href="https://www.ovh.com/"&gt;OVH&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content><category term="dashboards"/><category term="visualization"/><category term="Voilà"/></entry><entry><title>Field Report on the Kernel Community Workshop</title><link href="https://jupyter.org/blog/posts/2019/field-report-on-the-kernel-community-workshop/" rel="alternate"/><published>2019-10-07T13:24:00+00:00</published><updated>2019-10-16T14:53:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2019-10-07:/blog/posts/2019/field-report-on-the-kernel-community-workshop/</id><summary type="html">&lt;p&gt;From May 27th to May 29th 2019, thirty developers from the Jupyter community met in Paris for a three-days workshop on the Jupyter kernel protocol.&lt;/p&gt;</summary><content type="html">&lt;p&gt;From May 27th to May 29th 2019, thirty developers from the Jupyter community met in Paris for a three-days workshop on the Jupyter kernel protocol.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Attendees to the Jupyter Community Workshop on Kernels" src="https://jupyter.org/blog/posts/2019/field-report-on-the-kernel-community-workshop/images/001-1_AKYqXS6qtE0k6EcTKl3BEQ.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Attendees to the Jupyter Community Workshop on Kernels&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For three days, attendees worked full time on the Jupyter project, including hacking sessions and discussions on improvements to Jupyter protocols and standards.&lt;/p&gt;
&lt;p&gt;We were lucky to count five core developers to the project and several more regular contributors to the larger ecosystem in the group!&lt;/p&gt;
&lt;p&gt;Beyond the hacking sessions, each day was concluded with a series of presentations and demos of the progress made during the workshop.&lt;/p&gt;
&lt;h2 id="why-a-workshop-on-jupyter-kernels"&gt;Why a workshop on Jupyter kernels?&lt;/h2&gt;
&lt;p&gt;The Jupyter Kernel protocol is one of the main extension points of the Jupyter ecosystem. Dozen of language kernels have been developed by the community, and these languages can then leverage the other components of the stack, such as the notebook, the console, and interactive widgets.&lt;/p&gt;
&lt;p&gt;One of the objectives of this event was to foster collaboration between kernel developers and core contributors and develop common tools used across all language kernels. Another goal was to work improving the protocol, to support visual debugging, parameterized kernels, etc.&lt;/p&gt;
&lt;h2 id="technical-achievements"&gt;Technical Achievements&lt;/h2&gt;
&lt;p&gt;A lot of work was done during the workshop. Several people were working on new Jupyter kernels for programming languages.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We were amazed to see how much was achieved in just three days. Today, we are still working on projects that stemmed from this community workshop.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="jupyterlab-debugger"&gt;JupyterLab Debugger&lt;/h3&gt;
&lt;p&gt;One area in which the Jupyter team is actively working is support for &lt;strong&gt;visual debugging in JupyterLab&lt;/strong&gt;. This is a major endeavor spanning from the front-end to the back-end, including changes to the Jupyter protocol.&lt;/p&gt;
&lt;p&gt;The kernel workshop was the occasion for several developers (&lt;a href="https://twitter.com/wuoulf"&gt;Wolf Vollprecht&lt;/a&gt;, &lt;a href="https://twitter.com/maartenbreddels"&gt;Maarten Breddels&lt;/a&gt;, &lt;a href="https://twitter.com/johanmabille"&gt;Johan Mabille&lt;/a&gt;, &lt;a href="https://twitter.com/lgouarin"&gt;Loic Gouarin&lt;/a&gt;) to get together and hack on the implementation of the frontend. A lot of work had been done ahead of the workshop with &lt;a href="https://github.com/QuantStack/xeus-python"&gt;a new Python kernel&lt;/a&gt; based on the &lt;a href="https://github.com/QuantStack/xeus/"&gt;Xeus&lt;/a&gt; library. This new kernel includes a backend to the &lt;strong&gt;Debug Adapter Protocol&lt;/strong&gt; over kernel messages.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The JupyterLab Visual Debugger" src="https://jupyter.org/blog/posts/2019/field-report-on-the-kernel-community-workshop/images/002-1_O0nYHhfEne2BH4XsknaPhg.gif" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterLab Visual Debugger&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;There are other key contributors to the debugger project who did not attend the community workshop. We should mention &lt;a href="https://twitter.com/jtpio"&gt;Jeremy Tuloup&lt;/a&gt; and &lt;a href="https://twitter.com/micronova"&gt;Afshin Darian&lt;/a&gt; who are spearheading the frontend development.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="a-calculator-jupyter-kernel-based-on-xeus"&gt;A Calculator Jupyter Kernel based on xeus&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://twitter.com/VasavanT"&gt;Vasavan Thirusittampalam&lt;/a&gt; and &lt;a href="https://twitter.com/ThLacharme"&gt;Thibault Lacharme&lt;/a&gt; were in the middle of their summer internships as scientific software developers at QuantStack when they attended the workshop. During the event, they set themselves up to implement a new Jupyter kernel in C++!&lt;/p&gt;
&lt;p&gt;At the end of the workshop, they were able to demonstrate a functional &lt;strong&gt;calculator kernel&lt;/strong&gt; based on &lt;a href="https://github.com/QuantStack/xeus/"&gt;xeus&lt;/a&gt;, a C++ implementation of the Jupyter protocol! This was later polished and resulted in the publication of a blog post on the Jupyter blog: “&lt;a href="https://jupyter.org/blog/posts/2019/building-a-calculator-jupyter-kernel/"&gt;&lt;em&gt;&lt;strong&gt;Building a Calculator Jupyter Kernel&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;”. This example may serve as an example for people interested in creating new language kernels with xeus.&lt;/p&gt;
&lt;h3 id="a-prototype-julia-backend-to-jupyter-interactive-widgets"&gt;A prototype Julia backend to Jupyter interactive Widgets.&lt;/h3&gt;
&lt;p&gt;During the workshop &lt;a href="https://twitter.com/SebasGuts"&gt;Sebastian Gutsche&lt;/a&gt; (who is the author of the &lt;a href="https://github.com/sebasguts/jupyter_kernel_singular"&gt;Singular&lt;/a&gt; Jupyter kernel and a co-author of the &lt;a href="https://github.com/gap-packages/JupyterKernel"&gt;GAP&lt;/a&gt; kernel), set himself to develop a backend to Jupyter interactive widgets for the &lt;strong&gt;Julia&lt;/strong&gt; progamming language. The current state of the code can be found &lt;a href="https://github.com/sebasguts/iwidgets"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Julia backend to jupyter widgets is still early-stage but should this project be completed, it would enable other Jupyter widget libraries for the users of the Julia Jupyter kernel, such as ipyvolume, ipyleaflet, bqplot, etc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;
&lt;img alt="The Julia backend to Jupyter widgets" src="https://jupyter.org/blog/posts/2019/field-report-on-the-kernel-community-workshop/images/003-1_xv77xrNuUHKLjLinum0dlQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The Julia backend to Jupyter widgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="parameterized-kernelspecs"&gt;Parameterized Kernelspecs&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://twitter.com/ivanov"&gt;Paul Ivanov&lt;/a&gt; and &lt;a href="https://twitter.com/rgbkrk"&gt;Kyle Kelley&lt;/a&gt; worked on ironing out the proposal for the support of &lt;strong&gt;parameterized kernelspecs&lt;/strong&gt;. The objective is to make it possible to pass user-specified arguments to kernels upon launch.&lt;/p&gt;
&lt;p&gt;In the proposal, the parameters expected by the kernel executable and the possible values for these parameters may be specified in the kernelspec file or a companion file to the kernelspec in the form of a JSON schema.&lt;/p&gt;
&lt;p&gt;Paul and Kyle produced extensive notes on various aspects on the subjects such as&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the storing of previously used values of the parameters (in notebooks)&lt;/li&gt;
&lt;li&gt;the web UI design on how to specify parameters&lt;/li&gt;
&lt;li&gt;the definition of default values&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More details will be shared at a later stage on the subject of parameterized kernelspecs.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: the subject of parameterized kernelspecs was also central in the earlier community workshop about the Jupyter server organized at IBM by Luciano Resende.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="forking-of-jupyter-kernels"&gt;Forking of Jupyter Kernels&lt;/h3&gt;
&lt;p&gt;Starting of kernels is an expensive operation, and executing a whole notebook even more. For certain use cases (such as dashboards based on &lt;a href="https://github.com/voila-dashboards/voila"&gt;Voilà&lt;/a&gt;), it is useful to have a pre-executed notebook ready, so that dashboards can be presented instantly to a user. To enable this, &lt;a href="https://twitter.com/maartenbreddels"&gt;Maarten Breddels&lt;/a&gt; came up with the idea of forking kernels and put together a proof-of-concept implementation. The implementation can be found in pull requests to &lt;code&gt;jupyter_client&lt;/code&gt; (&lt;a href="https://github.com/jupyter/jupyter_client/pull/441"&gt;PR #441&lt;/a&gt;) and &lt;code&gt;ipykernel&lt;/code&gt; (&lt;a href="https://github.com/ipython/ipykernel/pull/410"&gt;PR #410&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Forking kernels will also allow interesting features such as an undo/rollback of cell execution in the notebook. While it is still a proof of concept, this subject has already sparked interest in the community.&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;This event would not have been possible without the generous support provided by &lt;a href="https://www.techatbloomberg.com/"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;, who made this workshop series possible&lt;/p&gt;
&lt;p&gt;We are grateful to &lt;a href="https://www.cfm.fr/"&gt;&lt;strong&gt;CFM&lt;/strong&gt;&lt;/a&gt; for gracefully hosting the event.&lt;/p&gt;
&lt;p&gt;We should also thank &lt;a href="https://twitter.com/ruv7?lang=en"&gt;&lt;strong&gt;Ana Ruvalcaba&lt;/strong&gt;&lt;/a&gt; from Project Jupyter for her incredible work on the logistics and finances of the Jupyter Community Workshop series.&lt;/p&gt;
</content><category term="C++"/><category term="events"/><category term="kernels"/><category term="workshops"/></entry><entry><title>Interactive GIS in Jupyter with ipyleaflet</title><link href="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/" rel="alternate"/><published>2019-09-24T22:54:00+00:00</published><updated>2019-09-25T15:19:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2019-09-24:/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/</id><summary type="html">&lt;p&gt;As Jupyter grew in popularity, a broad ecosystem of visualization packages based on Jupyter widgets has been developed, bringing even more interactivity to the Jupyter world.&lt;/p&gt;</summary><content type="html">&lt;p&gt;As Jupyter grew in popularity, a broad ecosystem of visualization packages based on Jupyter widgets has been developed, bringing even more interactivity to the Jupyter world.&lt;/p&gt;
&lt;p&gt;In this article, we dive into Jupyter Interactive Widgets and the &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; package, an interactive maps visualization system for Jupyter.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A non-interactive map." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/001-1_YA26aVkLDM1KXjNtGu5-Hw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A non-interactive map.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="jupyter-widgets"&gt;Jupyter Widgets&lt;/h2&gt;
&lt;p&gt;Jupyter Interactive Widgets are “special objects” that can be instantiated by the user in their code and result in a counterpart component being created in the front-end.&lt;/p&gt;
&lt;p&gt;The core &lt;code&gt;ipywidgets&lt;/code&gt; package provides a collection of controls that Jupyter users can use to build simple UIs as part of their notebooks (sliders, buttons, dropdowns, layout components).&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Basic ipywidgets controls." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/002-1_a8s90I7Kj3DyBjmh_LjAaw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Basic ipywidgets &lt;strong&gt;controls&lt;/strong&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;More than a collection of controls, it provides a framework upon which a large ecosystem of components has been built, allowing notebook authors to capture user inputs in very diverse ways.&lt;/p&gt;
&lt;p&gt;Popular libraries built upon interactive widgets include&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bloomberg/bqplot"&gt;&lt;strong&gt;bqplot&lt;/strong&gt;&lt;/a&gt;, a 2-D plotting system for Jupyter,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/maartenbreddels/ipyvolume/"&gt;&lt;strong&gt;ipyvolume&lt;/strong&gt;&lt;/a&gt;, a 3-D plotting package based on WebGL and ThreeJS,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-widgets/pythreejs"&gt;&lt;strong&gt;PythreeJS&lt;/strong&gt;&lt;/a&gt;, a 3-D scene description package exposing a large part of the ThreeJS API to Jupyter,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mariobuikhuizen/ipyvuetify"&gt;&lt;strong&gt;ipyvuetify&lt;/strong&gt;&lt;/a&gt;, a large collection of VuetifyJS components exposed to Jupyter,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/maartenbreddels/ipywebrtc"&gt;&lt;strong&gt;ipywebrtc&lt;/strong&gt;&lt;/a&gt;, a library exposing the features of the WebRTC protocol to Jupyter kernels,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/twosigma/beakerx"&gt;&lt;strong&gt;beakerx&lt;/strong&gt;&lt;/a&gt;, a collection of widgets, extensions, and kernels for Jupyter,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and many more… This list is not comprehensive and dozens of other widget packages have been developed.&lt;/p&gt;
&lt;p&gt;Key aspects of Jupyter widgets include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bidirectionality&lt;/strong&gt;: Widgets are not just meant for display but can also be used to capture user inputs, which can then trigger new computation. Notebook authors can compose sophisticated applications including a variety of components from different packages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Language Agnosticism&lt;/strong&gt;: Built upon the Jupyter ecosystem, the interactive widget protocol used for the synchronization between the kernel and the front-end is well-specified and can be implemented for any kernel.&lt;br&gt;
Back-ends for other languages than Python already exist, such as for C++ (with the &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; Jupyter kernel), and languages of the JVM such as Clojure or Groovy (with the &lt;a href="http://beakerx.com/"&gt;beakerx&lt;/a&gt; kernels).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;: Jupyter widgets are not meant as a monolithic system with one and only one way to achieve a specific task. We strive to provide a foundational layer allowing third-party widget authors to be as inventive as possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;A common pattern for Jupyter widget packages has been to bring the capabilities of popular JavaScript visualization frameworks to Jupyter with a bridge based on ipywidgets. This is the case for the ipyleaflet package, as well as pythreejs and ipyvuetify.&lt;/p&gt;
&lt;p&gt;Another use case is the development of &lt;em&gt;ad hoc&lt;/em&gt; controls that are not necessarily relevant for a mainstream visualization package, but may be specific to a scientific field. An example is the &lt;a href="https://github.com/erdc/ipymesh"&gt;ipymesh&lt;/a&gt; project by Chris Kees which can be used to draw PSLG (planar straight-line graphs) in the Jupyter notebook.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="ipyleaflet"&gt;ipyleaflet&lt;/h2&gt;
&lt;p&gt;ipyleaflet is a Jupyter - LeafletJS bridge, bringing mapping capabilities to the notebook and JupyterLab.&lt;/p&gt;
&lt;p&gt;Built as a bridge between the LeafletJS package and Jupyter, the ipyleaflet API maps to that of LeafletJS, bringing most of the core features of the package to Jupyter, and enabling a few popular LeafletJS extensions. A small difference is that following the Python coding style, ipyleaflet makes use of &lt;em&gt;snake_case&lt;/em&gt; instead of &lt;em&gt;CamelCase&lt;/em&gt; for attribute names.&lt;/p&gt;
&lt;h3 id="ipyleaflet-features"&gt;ipyleaflet features&lt;/h3&gt;
&lt;p&gt;The main components to the library are layers and controls, respectively items to be displayed on the map, and interactive widgets overlayed on the map area for greater interactivity.&lt;/p&gt;
&lt;p&gt;The first thing for which you may want to change the default value are the zoom level, the position, or the base layer for the map.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Changing the basemap layer in an ipyleaflet map." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/003-1_02DmPnByfXtPkeYnytNvfA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Changing the basemap layer in an ipyleaflet map.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Maps can be interactively edited in the Jupyter notebook, by dynamically changing or adding layers. In this screenshot, we add a custom layer including a GeoJSON dataset.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: An alternative layer to GeoJSON is GeoData, which lets the user load the data in the form of a GeoPandas dataframe instead of raw GeoJSON.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;
&lt;img alt="Adding a GeoJSON dataset to an interactive map." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/004-1_3t7T3EGIeA10R0XrrM9ZVw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Adding a GeoJSON dataset to an interactive map.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A number of simple primitives are available such as markers and heatmaps. In the following screencast, we show how primitive properties can be linked with other widgets, and used as means to take user input on a map:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Linking properties of ipyleaflet primitives to other Jupyter widgets." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/005-1_31XAuFgaeln-mrjxxRzdxA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Linking properties of ipyleaflet primitives to other Jupyter widgets.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;em&gt;splitmap&lt;/em&gt; control can be used to compare to different set of ipyleaflet layers at the same location.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The splitmap control." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/006-1_lZT_nX-jH3jcMLFdhTUxXw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;splitmap&lt;/strong&gt; control.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another interesting layer is the &lt;em&gt;velocity&lt;/em&gt; layer which can be used to display wind velocity data. This control can take data in the form of an &lt;a href="https://github.com/pydata/xarray"&gt;xarray&lt;/a&gt; dataset.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The velocity layer." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/007-1_u2J2aJy6FfBaFytG0ppruw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;velocity&lt;/strong&gt; layer.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;More classical visualization tools are also available, such as &lt;em&gt;choropleths&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A choropleth layer." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/008-1_MbLnLa_LsugvYdBNjGhhQQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A &lt;strong&gt;choropleth&lt;/strong&gt; layer.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="jupyterlab-integration-with-the-sidecar-and-theming-support"&gt;JupyterLab Integration with the Sidecar and Theming Support&lt;/h3&gt;
&lt;p&gt;ipyleaflet is well integrated with JupyterLab&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ipyleaflet controls make use of the &lt;strong&gt;JupyterLab themes&lt;/strong&gt; for coloring so that they don’t stand out when using e.g. a dark theme.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The support for JupyterLab themes in ipyleaflet." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/009-1_6tCnE8oedSXuEtiGKA1fAA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The support for JupyterLab &lt;strong&gt;themes&lt;/strong&gt; in ipyleaflet.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ipyleaflet can be used in combination with the &lt;a href="https://github.com/jupyter-widgets/jupyterlab-sidecar/"&gt;&lt;strong&gt;JupyterLab sidecar&lt;/strong&gt;&lt;/a&gt; widget.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Using the sidecar widget in JupyterLab to display a map aside of the notebook." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/010-1_eUr0hcPcBInlp125yA7sHg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using the &lt;strong&gt;sidecar&lt;/strong&gt; widget in JupyterLab to display a map aside of the notebook.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Together with the sidecar, a map can be programmatically added to the right-side toolbar of the JupyterLab application, and interactively edited in the notebook. This prevents the back-and-forth scrolling often required to see how changes are reflected visually.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The workflow enabled by ipyleaflet in combination with the sidecar is similar to that of the &lt;a href="https://github.com/OpenGeoscience/geonotebook"&gt;geonotebook&lt;/a&gt; project by Christopher Kotfila, Jonathan Beezley, and Dan LaManna from &lt;a href="https://www.kitware.com/"&gt;Kitware&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;
&lt;img alt="The geonotebook (which was based on the classic notebook) provided a similar workflow to the lab sidecar." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/011-1_u2dMqR9n5Vwl1ELtpTbVCg.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;geonotebook&lt;/strong&gt; (which was based on the classic notebook) provided a similar workflow to the lab sidecar.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="a-more-advanced-example"&gt;A more advanced example&lt;/h3&gt;
&lt;p&gt;Combined with other widget libraries such as bqplot or the core ipywidget package, ipyleaflet users can easily compose more complex applications and dashboards. In the following screencast, we explore the wealth-of-nations dataset with a leafletmap, a bqplot line chart and a dropdown widget:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Exploring the wealth-of-nations dataset with ipyleaflet, bqplot and core ipywidgets." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/012-1_0SvmdK7ykkDXZ4oU-x6QzA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Exploring the wealth-of-nations dataset with ipyleaflet, bqplot and core ipywidgets.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="trying-ipyleaflet-online-with-mybinder"&gt;Trying ipyleaflet online with mybinder&lt;/h3&gt;
&lt;p&gt;If you would like to try out ipyleaflet &lt;em&gt;now&lt;/em&gt;, it is possible thanks to the binder project. Just click on the image below!&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://mybinder.org/v2/gh/jupyter-widgets/ipyleaflet/stable?filepath=examples"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/013-1_AsxYLD3dKd9Vej3SII_eLg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="interactive-gis-in-c-xleaflet"&gt;Interactive GIS in C++: xleaflet&lt;/h3&gt;
&lt;p&gt;As mentioned earlier, interactive widgets back-ends for other programming languages have be implemented. There is a C++ back-end for ipywidgets: &lt;a href="https://github.com/QuantStack/xwidgets"&gt;xwidgets&lt;/a&gt; which is the building block for creating other C++ widgets back-ends.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/014-0_aPvM-7TR9IbP_NXO.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xleaflet"&gt;xleaflet&lt;/a&gt; is the C++ - LeafletJS bridge that exposes almost the same API as ipyleaflet, only that you use it from a C++ interpreter! It is based upon xwidgets which brings the bidirectional communication with the front-end.&lt;/p&gt;
&lt;p&gt;You can learn more about the &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; Jupyter kernel, xwidgets and xleaflet by reading the following &lt;a href="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/"&gt;blogpost&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="xleaflet is the C++ backend to the jupyter-leaflet integration." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/015-1_m2ElLEj6r-6uDqXmA0tqRw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;&lt;strong&gt;xleaflet&lt;/strong&gt; is the C++ backend to the jupyter-leaflet integration.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="deploying-ipyleaflet-based-dashboards-with-voila"&gt;Deploying ipyleaflet-based dashboards with Voilà&lt;/h3&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/016-1_36JTV2RMHwg0DEW6V00d2A.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/voila"&gt;Voilà&lt;/a&gt; is a tool that turns Jupyter notebooks into standalone dashboards. Built upon the Jupyter stack, it inherits the language agnosticism of the ecosystem, and can be used to produce standalone applications based on ipyleaflet.&lt;/p&gt;
&lt;p&gt;A companion project to Voilà is the Voilà gallery project, a public facing set up of JupyterHub serving Voilà dashboard. It is kindly hosted by &lt;a href="https://www.ovh.com/fr/"&gt;OVH&lt;/a&gt;. You can check out the Voilà gallery at URL &lt;a href="https://voila-gallery.org/services/gallery/"&gt;https://voila-gallery.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For more resources about &lt;em&gt;voilà&lt;/em&gt;, check out&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the original announcement of the project: &lt;a href="https://blog.jupyter.org/and-voil%C3%A0-f6a2c08a4a93"&gt;&lt;em&gt;And Voilà!&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and for the gallery: &lt;a href="https://jupyter.org/blog/posts/2019/a-gallery-of-voila-examples/"&gt;&lt;em&gt;A Gallery of Voilà Examples&lt;/em&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you check out the Voilà gallery, don’t miss Jeremy Tuloup’s GPX loader demo!&lt;/p&gt;
&lt;h2 id="jupyter-for-geo-sciences"&gt;Jupyter for Geo Sciences&lt;/h2&gt;
&lt;p&gt;Jupyter’s adoption is exploding in the GeoScience space. Notable projects building upon Jupyter include&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jeodpp.jrc.ec.europa.eu/home/"&gt;&lt;em&gt;&lt;strong&gt;JEODPP&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; (JRC Earth Observation Data and Processing Platform) is a EU project providing petabyte scale storage and high-throughput computing capacities to facilitate large scale analysis of Earth Observation data. The main front-end to the platform is base on Jupyter. The mapping capability is based on &lt;strong&gt;ipyleaflet&lt;/strong&gt;. End users can request custom visualization that are returned to them in the form of lazily computed tile layers.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pangeo.io"&gt;&lt;em&gt;&lt;strong&gt;Pangeo&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; is a community platform providing open, reproducible, and scalable sciences. The Pangeo software ecosystem involves open source tools such as xarray, Iris, Dask, Jupyter, and many other packages.&lt;/li&gt;
&lt;li&gt;It was &lt;a href="https://jupyter.org/blog/posts/2019/jupyter-meets-the-earth/"&gt;recently announced&lt;/a&gt; that the NSF would be funding the UC Berkeley + NCAR “&lt;em&gt;&lt;strong&gt;EarthCube&lt;/strong&gt;&lt;/em&gt;” proposal “Jupyter meets the Earth: Enabling discovery in geoscience through interactive computing at scale”. The plan involves the development of interactive dashboards with &lt;strong&gt;Voilà&lt;/strong&gt; and contributions to the Voilà codebase.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="related-projects"&gt;Related Projects&lt;/h2&gt;
&lt;h3 id="jupyter-gmaps"&gt;Jupyter-gmaps&lt;/h3&gt;
&lt;p&gt;We should mention the &lt;a href="https://github.com/pbugnion/gmaps"&gt;jupyter-gmaps&lt;/a&gt; project by Pascal Bugnion. Jupyter-gmaps is a bridge between Google maps and Jupyter. Just like ipyleaflet, jupyter-gmaps is built upon the jupyter interactive widgets framework but relies on Google maps for the display instead of LeafletJS library.&lt;/p&gt;
&lt;p&gt;This is a high-quality widget by another core developer of ipywidgets. Pascal is also one of the people behind Voilà and the Voilà gallery.&lt;/p&gt;
&lt;h3 id="folium"&gt;Folium&lt;/h3&gt;
&lt;p&gt;The &lt;a href="https://github.com/python-visualization/folium"&gt;Folium&lt;/a&gt; project enables maps visualization in the Jupyter notebook. Just like ipyleaflet, it is based on LeafletJS. Folium was created by Rob Story and is now maintained by Frank Conengmo and Filipe Fernandes.&lt;/p&gt;
&lt;p&gt;A key difference between Folium and ipyleaflet is that ipyleaflet is built upon ipywidgets and allows bidirectional communication between the front-end and the backend enabling the use of the map to capture user input, while Folium is meant for displaying static data only. Folium enables many LeafletJS extensions, some of which may not be available in ipyleaflet at the moment.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;The ipyleaflet project was started in 2015 by &lt;a href="https://twitter.com/ellisonbg?lang=en"&gt;Brian Granger&lt;/a&gt;, and funded by the &lt;a href="https://www.erdc.usace.army.mil/"&gt;ERDC&lt;/a&gt;. The further development by Sylvain Corlay and Martin Renou was supported by &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are grateful to &lt;a href="https://www.ovh.com"&gt;OVH&lt;/a&gt; for kindly hosting the &lt;a href="http://voila-gallery.org"&gt;Voilà gallery&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Other key contributors to Voilà and ipyleaflet that should be thanked here are Maarten Breddels, Pascal Bugnion, and Yuvi Panda. We should also mention the recent contributions by &lt;a href="https://twitter.com/VasavanT"&gt;Vasavan Thirusittampalam&lt;/a&gt; who worked on the full-screen control and better interoperability with geopandas.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the Authors&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt;, and &lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; are Scientific Software Developers at &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="sylvain-corlay"&gt;Sylvain Corlay&lt;/h3&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/017-1_6-g_O5JJQn4uSoAreSq9Pw_2x.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sylvain Corlay&lt;/strong&gt; is the founder and CEO of QuantStack.&lt;/p&gt;
&lt;p&gt;As an Open Source Developer, Sylvain contributes to Project Jupyter in the areas of interactive widgets and language kernels and is a steering committee member of the Project. Beyond QuantStack, Sylvain serves as a member of the board of directors of the NumFOCUS foundation. He also co-organizes the PyData Paris Meetup.&lt;/p&gt;
&lt;h3 id="martin-renou"&gt;Martin Renou&lt;/h3&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/018-1_eZ36LOdroOy_-KBEN8TLlg_2x.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Martin Renou&lt;/strong&gt; is a Scientific Software Developer at QuantStack. Prior to joining QuantStack, Martin also worked as a Software developer at Enthought. He studied at the French Aerospace Engineering School ISAE-Supaero, with major in autonomous systems and programming.&lt;/p&gt;
&lt;p&gt;As an open source developer, Martin has worked on a variety of projects, such as SciviJS (a JavaScript 3-D mesh visualization library), Xtensor, and Xeus.&lt;/p&gt;
</content><category term="geoscience"/><category term="science"/><category term="visualization"/></entry><entry><title>And voilà!</title><link href="https://jupyter.org/blog/posts/2019/and-voila/" rel="alternate"/><published>2019-06-11T17:42:00+00:00</published><updated>2021-01-08T08:38:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2019-06-11:/blog/posts/2019/and-voila/</id><summary type="html">&lt;p&gt;… from Jupyter notebooks to standalone applications and dashboards&lt;/p&gt;
</summary><content type="html">&lt;p&gt;The goal of Project Jupyter is to improve the workflows of researchers, educators, scientists, and other practitioners of scientific computing, from the &lt;em&gt;&lt;strong&gt;exploratory phase&lt;/strong&gt;&lt;/em&gt; of their work to the &lt;em&gt;&lt;strong&gt;communication&lt;/strong&gt;&lt;/em&gt; of the results.&lt;/p&gt;
&lt;p&gt;But interactive notebooks are not the best communication tool for all audiences. While they have proven invaluable to provide a &lt;em&gt;narrative&lt;/em&gt; alongside the source, they are not ideal to address &lt;em&gt;&lt;strong&gt;non-technical readers&lt;/strong&gt;&lt;/em&gt;, who may be put off by the presence of code cells, or the need to run the notebook to see the results. Finally, following the order as the code often results in the most interesting content to be at the &lt;em&gt;&lt;strong&gt;end&lt;/strong&gt;&lt;/em&gt; of the document.&lt;/p&gt;
&lt;p&gt;Another challenge with sharing notebooks is the &lt;em&gt;&lt;strong&gt;security&lt;/strong&gt;&lt;/em&gt; model. How can we offer the interactivity of a notebook making use of e.g. Jupyter widgets without allowing arbitrary code execution by the end user?&lt;/p&gt;
&lt;p&gt;We set ourselves to solve these challenges, and we are happy to announce the first release of &lt;em&gt;&lt;strong&gt;Voilà&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/and-voila/images/001-1_c1xwFRqy99o8nLVxDSqNZg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Voilà&lt;/strong&gt;&lt;/em&gt; turns Jupyter notebooks into standalone web applications.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Voilà supports &lt;em&gt;&lt;strong&gt;Jupyter interactive widgets&lt;/strong&gt;&lt;/em&gt;, including the roundtrips to the kernel.&lt;/li&gt;
&lt;li&gt;Voilà &lt;em&gt;&lt;strong&gt;does not permit arbitrary code execution&lt;/strong&gt;&lt;/em&gt; by consumers of dashboards.&lt;/li&gt;
&lt;li&gt;Built upon Jupyter standard protocols and file formats, Voilà works with any Jupyter kernel (C++, Python, Julia), making it a &lt;em&gt;&lt;strong&gt;language-agnostic&lt;/strong&gt;&lt;/em&gt; dashboarding system.&lt;/li&gt;
&lt;li&gt;Voilà is extensible. It includes a flexible &lt;em&gt;&lt;strong&gt;template system&lt;/strong&gt;&lt;/em&gt; to produce rich application layouts.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="installation-and-first-time-use"&gt;Installation and first-time use&lt;/h2&gt;
&lt;p&gt;Voilà can be installed from pypi:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install voila
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or conda-forge:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda install voila -c conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Upon installation, several components are installed, one of which is the &lt;code&gt;voila&lt;/code&gt; command-line utility. You can try it by typing &lt;code&gt;voila notebook.ipynb&lt;/code&gt;. It results in the browser opening to a new tornado application showing markdown cells, rich outputs, and interactive widgets.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="From a notebook to a standalone web application" src="https://jupyter.org/blog/posts/2019/and-voila/images/002-1_imDFJcYj8k-apbrvIK9ZVQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;From a notebook to a standalone web application&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;As you can see in the screencast, Jupyter interactive widgets remain fully functional even when they require computation by the kernel.&lt;/p&gt;
&lt;p&gt;You can immediately try out some of the command-line options to Voilà&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;with &lt;code&gt;--strip_sources=False&lt;/code&gt;, input cells will be included in the resulting web application (as read-only pygment snippets).&lt;/li&gt;
&lt;li&gt;with &lt;code&gt;--theme=dark&lt;/code&gt;, Voilà will make use of the dark JupyterLab theme, which will apply to code cells, widgets and all other visible components.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Making use of the dark theme and including input cells" src="https://jupyter.org/blog/posts/2019/and-voila/images/003-1_ce142q3rm3TgJZVNEgGWcw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Making use of the dark theme and including input cells&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Note that code is only shown, voilà does not allow users to edit or execute arbitrary code.&lt;/p&gt;
&lt;h2 id="voilas-execution-model"&gt;Voilà’s execution model&lt;/h2&gt;
&lt;p&gt;The execution model of Voilà is the following: upon connection to a notebook URL, Voilà launches the kernel for that notebook, and runs all the cells as it populates the notebook model with the outputs.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The execution model of Voilà" src="https://jupyter.org/blog/posts/2019/and-voila/images/004-1_KZj7rmVqAHmY1b-P-QMPLw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The execution model of Voilà&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;After the execution, the associated kernel is not shut down. The notebook is converted to HTML and served to the user. The rendered HTML includes JavaScript that establishes a connection to the kernel. Jupyter interactive widgets referred in cell outputs are rendered and connected to their counterpart in the kernel. The kernel is only shut down when the user closes their browser tab.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The current version of Voilà only responds to the initial GET request when all the cells have finished running, which may take a long time, but there is &lt;a href="https://github.com/QuantStack/voila/pull/133"&gt;ongoing work&lt;/a&gt; on enabling progressive rendering, which should make it into a release soon.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;An important aspect of this execution model is that the front-end does not determine what code is run by the backend. In fact, unless specified otherwise (with option &lt;code&gt;--strip-sources=False&lt;/code&gt;), the source of the rendered notebook does not even make it to the front-end. The instance of the &lt;code&gt;jupyter_server&lt;/code&gt; instantiated by Voilà actually disallows execute requests by default.&lt;/p&gt;
&lt;h2 id="support-for-custom-interactive-widgets"&gt;Support for custom interactive widgets&lt;/h2&gt;
&lt;p&gt;Voilà can render custom Jupyter widget libraries, including (but not limited to) &lt;a href="https://github.com/bloomberg/bqplot"&gt;bqplot&lt;/a&gt;, &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleafet&lt;/a&gt;, &lt;a href="https://github.com/maartenbreddels/ipyvolume"&gt;ipyvolume&lt;/a&gt;, &lt;a href="https://github.com/matplotlib/jupyter-matplotlib/"&gt;ipympl&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/ipysheet"&gt;ipysheet&lt;/a&gt;, &lt;a href="https://github.com/plotly/plotly.py"&gt;plotly&lt;/a&gt;, &lt;a href="https://github.com/maartenbreddels/ipywebrtc"&gt;ipywebrtc&lt;/a&gt;, etc.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Including bqplot figures with Voilà" src="https://jupyter.org/blog/posts/2019/and-voila/images/005-1_iBz5dUYHT5N9dbymPKTGCg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Including &lt;a href="https://github.com/bloomberg/bqplot"&gt;bqplot&lt;/a&gt; figures with Voilà&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Together with &lt;a href="https://github.com/matplotlib/jupyter-matplotlib/"&gt;ipympl&lt;/a&gt;, Voilà is actually a simple means to render interactive matplotlib figures in a standalone web application:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Rendering interactive matplotlib figures in a web application with voilà" src="https://jupyter.org/blog/posts/2019/and-voila/images/006-1_e3k8ZgJoCp0Pm-yZ5Xr0Xg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Rendering interactive matplotlib figures in a web application with voilà&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="voila-is-language-agnostic"&gt;Voilà is language-agnostic&lt;/h2&gt;
&lt;p&gt;Voilà can be used to produce applications with any Jupyter kernel. The following screencast shows how Voilà can be used to produce a simple dashboard in C++ making use of leaflet.js maps, with the &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; C++ kernel and the &lt;a href="https://github.com/QuantStack/xleaflet"&gt;xleaflet&lt;/a&gt; package.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A standalone Voilà page making use of the C++ Jupyter kernel, xeus-cling (input cells display enabled)." src="https://jupyter.org/blog/posts/2019/and-voila/images/007-1_os2ABw7hEnfd1Dq5pOrTDg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A standalone Voilà page making use of the C++ Jupyter kernel, &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; (input cells display enabled).&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We hope that Voilà will be a stimulant to other languages (R, Julia, JVM/Java) to provide stronger widgets support.&lt;/p&gt;
&lt;h2 id="richer-layouts-with-voila-templates"&gt;Richer layouts with Voilà templates&lt;/h2&gt;
&lt;p&gt;The main extension point to Voilà is the custom &lt;em&gt;&lt;strong&gt;template system&lt;/strong&gt;&lt;/em&gt;. The HTML served to the end-user is produced from the notebook model by applying a Jinja template, which can be defined by the user.&lt;/p&gt;
&lt;p&gt;An example template for voilà is the &lt;code&gt;voila-gridstack&lt;/code&gt; template, which can be installed from pypi with&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install voila-gridstack
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can try it by typing &lt;code&gt;voila notebook.ipynb --template=gridstack&lt;/code&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Making use of the Gridstack template to produce a dashboard with bqplot charts" src="https://jupyter.org/blog/posts/2019/and-voila/images/008-1_grVVSeKyw7bXYU7fZmHgQQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Making use of the Gridstack template to produce a dashboard with &lt;a href="https://github.com/bloomberg/bqplot/"&gt;bqplot&lt;/a&gt; charts&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;a href="https://github.com/QuantStack/voila-gridstack/"&gt;gridstack Voilà template&lt;/a&gt; makes use of the cell metadata to lay out the application.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A roadmap item for the gridstack Voilà template is to support the entire spec for the deprecated &lt;a href="https://github.com/jupyter/dashboards"&gt;jupyter dashboards&lt;/a&gt; and to create a WYSIWYG editor for these templates in the form of a JupyterLab extension.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Note that &lt;a href="https://github.com/QuantStack/voila-gridstack/"&gt;voila-gridstack&lt;/a&gt; template is still at an early stage of development.&lt;/p&gt;
&lt;h2 id="how-to-make-custom-voila-templates"&gt;How to make custom Voilà templates?&lt;/h2&gt;
&lt;p&gt;A Voilà template is actually a &lt;em&gt;&lt;strong&gt;folder&lt;/strong&gt;&lt;/em&gt; placed in the standard directory &lt;code&gt;PREFIX/share/jupyter/voila/templates&lt;/code&gt; and which may include&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nbconvert&lt;/code&gt; templates (the jinja templates used to transform the notebook into HTML)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;static&lt;/code&gt; resources&lt;/li&gt;
&lt;li&gt;custom &lt;code&gt;tornado&lt;/code&gt; templates such as &lt;code&gt;404.html&lt;/code&gt; etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these are optional. It may also contain a &lt;code&gt;conf.json&lt;/code&gt; file to set up which template to use as a base. The directory structure for a Voilà template is the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;PREFIX/share/jupyter/voila/templates/template_name/
|
├── conf.json                # Template configuration file
├── nbconvert_templates/     # Custom nbconvert templates
├── static/                  # Static directory
└── templates/               # Custom tornado templates
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Voilà template system can be used to completely override the behavior of the front-end. One can make use of modern JavaScript frameworks such as &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt; or &lt;a href="https://vuejs.org/"&gt;Vue.js&lt;/a&gt; to produce modern UI including Jupyter widgets and outputs.&lt;/p&gt;
&lt;p&gt;Another example template for Voilà is &lt;code&gt;voila-vuetify&lt;/code&gt;, which is built upon vue.js:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The voila-vuetify template makes use of Vue.js" src="https://jupyter.org/blog/posts/2019/and-voila/images/009-1_HtXNf1rq26u9ss8L-Oo6VQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;a href="https://github.com/QuantStack/voila-vuetify"&gt;voila-vuetify&lt;/a&gt; template makes use of Vue.js&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;The voila-gridstack and voila-vuetify templates are still at an early stage of development, but will be iterated upon quickly in the next weeks as we are exploring templates.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="a-jupyter-server-extension"&gt;A Jupyter server extension&lt;/h2&gt;
&lt;p&gt;Beyond the &lt;code&gt;voila&lt;/code&gt; command-line utility, the Voilà package also include a Jupyter &lt;em&gt;&lt;strong&gt;server extension&lt;/strong&gt;&lt;/em&gt;, so that Voilà dashboards can be served alongside the Jupyter notebook application.&lt;/p&gt;
&lt;p&gt;When Voilà is installed, a running Jupyter server will serve the Voilà web application under &lt;code&gt;BASE_URL/voila&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="the-jupyter-community-workshop-on-dashboarding"&gt;The Jupyter Community Workshop on Dashboarding&lt;/h2&gt;
&lt;p&gt;From June 3rd to June 6th 2019, a &lt;a href="https://jupyter.org/blog/posts/2019/jupyter-community-workshop-dashboarding-with-project/"&gt;community workshop on dashboarding&lt;/a&gt; with Project Jupyter took place in Paris. Over thirty Jupyter contributors and community members gathered to discuss dashboarding technologies and hack together.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The participants to the Paris Jupyter community workshop on dashboarding" src="https://jupyter.org/blog/posts/2019/and-voila/images/010-1_6LggiPlUoCSkP2A1aHp_3w.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The participants to the Paris Jupyter community workshop on dashboarding&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Several dashboarding solutions such as Dash and Panel were presented during the workshop and featured at the &lt;a href="https://www.meetup.com/PyData-Paris/events/261452824/"&gt;PyData Paris Meetup&lt;/a&gt; which was organized on the same week.&lt;/p&gt;
&lt;p&gt;The workshop was also the occasion for several contributors to start working on Voilà. Custom templates, a dashboard gallery, logos and UX mockups for JupyterLab extensions have been developed.&lt;/p&gt;
&lt;p&gt;We will soon publish a more detailed post on the workshop, detailing the many tracks of development that have been explored!&lt;/p&gt;
&lt;h2 id="what-is-coming"&gt;What is coming?&lt;/h2&gt;
&lt;p&gt;There is a lot of planned work around Voilà in the next weeks and months. Current work streams include better &lt;em&gt;&lt;strong&gt;integration with JupyterHub&lt;/strong&gt;&lt;/em&gt; for publicly sharing dashboard between users, as well as &lt;em&gt;&lt;strong&gt;JupyterLab extensions&lt;/strong&gt;&lt;/em&gt; (a &lt;a href="https://github.com/QuantStack/voila/pull/217"&gt;Voilà “preview” extension for notebooks&lt;/a&gt;, and a WYSIWYG editor for dashboard layouts). There are also ongoing discussions with the &lt;a href="https://www.ovh.com/fr/"&gt;OVH&lt;/a&gt; cloud provider (which already supports binder by handling some of its traffic) on hosting a binder-like service dedicated to Voilà dashboards. So stay tuned for more exciting developments!&lt;/p&gt;
&lt;p&gt;Last but not least, we are especially excited about what &lt;em&gt;&lt;strong&gt;you&lt;/strong&gt;&lt;/em&gt; will be building upon Voilà!&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;The development of Voilà and related packages at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; is sponsored by &lt;a href="http://www.techatbloomberg.com"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are also grateful to the attendees of the &lt;a href="https://jupyter.org/blog/posts/2019/jupyter-community-workshop-dashboarding-with-project/"&gt;&lt;strong&gt;Jupyter Community Workshop on Dashboarding&lt;/strong&gt;&lt;/a&gt; for their numerous contributions to Voilà!&lt;/p&gt;
&lt;p&gt;We would like to thank &lt;a href="https://twitter.com/choldgraf"&gt;Chris Holdgraf&lt;/a&gt; for his work on improving documentation, and integration with JupyterHub.&lt;/p&gt;
&lt;p&gt;We should mention &lt;a href="https://twitter.com/yuvipanda"&gt;Yuvi Panda&lt;/a&gt; and &lt;a href="https://twitter.com/pascalbugnion"&gt;Pascal Bugnion&lt;/a&gt; for getting the &lt;code&gt;voila-gallery&lt;/code&gt; project off the ground during the workshop. We are grateful to &lt;a href="https://twitter.com/zrsailer"&gt;Zach Sailer&lt;/a&gt; for his continued work on improving &lt;code&gt;jupyter_server&lt;/code&gt;. We should finally not forget to mention the prior art by &lt;a href="https://twitter.com/pascalbugnion"&gt;Pascal Bugnion&lt;/a&gt; with the Jupyter widgets server which was also an inspiration for Voilà.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the Authors&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/SylvainCorlay"&gt;&lt;em&gt;Sylvain Corlay&lt;/em&gt;&lt;/a&gt; is the founder and CEO of &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt; and a core team member for Project Jupyter.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/maartenbreddels"&gt;Maarten Breddels&lt;/a&gt; is an independent scientific software developer partnering with &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt; on numerous projects, and a core developer of Project Jupyter.&lt;/p&gt;
</content><category term="dashboards"/><category term="Voilà"/></entry></feed>