<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Jupyter Blog - Sylvain Corlay</title><link href="https://jasongrout.github.io/medium-archive/pelican/" rel="alternate"/><link href="https://jasongrout.github.io/medium-archive/pelican/feeds/author-sylvain-corlay.atom.xml" rel="self"/><id>https://jasongrout.github.io/medium-archive/pelican/</id><updated>2025-04-10T15:24:00+00:00</updated><subtitle>The Project Jupyter blog: news, releases, and community stories, archived from blog.jupyter.org.</subtitle><entry><title>ipydatagrid is now part of Project Jupyter</title><link href="https://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2024-08-22:/medium-archive/pelican/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…&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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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;/strong&gt; &lt;a href="https://vega.github.io/vega/docs/expressions/"&gt;&lt;strong&gt;Vega Expressions&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2024/ipydatagrid-is-now-part-of-project-jupyter/images/004-0_U5H7uyoSLf0pZm6q.gif" 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://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2024-06-12:/medium-archive/pelican/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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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;Pioneering Web-based, Collaborative, and Open-source GIS Tools&lt;/p&gt;
&lt;p&gt;&lt;em&gt;By Sylvain Corlay [1], Anne Fouilloux [2], and Monika Weissschnur [3]&lt;/em&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="/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;p&gt;[1] &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;[2] &lt;a href="https://www.simula.no/"&gt;Simula&lt;/a&gt;[3] &lt;a href="https://www.simula.no/"&gt;Simula&lt;/a&gt;&lt;/p&gt;
</content><category term="collaboration"/><category term="geoscience"/><category term="JupyterGIS"/><category term="science"/></entry><entry><title>JupyterCon 2023 keynotes</title><link href="https://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2023-01-18:/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2022-12-05:/medium-archive/pelican/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;/em&gt; &lt;a href="https://www.cnam.fr/"&gt;&lt;em&gt;CNAM&lt;/em&gt;&lt;/a&gt; &lt;em&gt;for hosting us and to&lt;/em&gt; &lt;a href="https://www.inria.fr/"&gt;&lt;em&gt;INRIA&lt;/em&gt;&lt;/a&gt; &lt;em&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 Boshifor Wikimedia Commons" src="https://jasongrout.github.io/medium-archive/pelican/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 Boshifor 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://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2022-11-23:/medium-archive/pelican/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…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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="/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="/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://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2022-11-10:/medium-archive/pelican/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;/em&gt; &lt;a href="https://www.ovhcloud.com/"&gt;&lt;em&gt;OVHCloud&lt;/em&gt;&lt;/a&gt; &lt;em&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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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>Enabling the JupyterLab debugger with ipykernel</title><link href="https://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2021-05-13:/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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&gt;&lt;a href="https://mybinder.org/v2/gist/SylvainCorlay/a6405bbdfa9d58a670a67f3a47741bd2/HEAD?urlpath=doc%2Ftree%2Fdebugger.ipynb"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2021-01-27:/medium-archive/pelican/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;&lt;em&gt;Diving into the implementation of xwidgets&lt;/em&gt;&lt;/p&gt;
&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://jasongrout.github.io/medium-archive/pelican/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;/em&gt; &lt;em&gt;&lt;strong&gt;interpreted C++&lt;/strong&gt;&lt;/em&gt;&lt;em&gt;, we recommend the following posts:&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/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;br&gt;
-&lt;/em&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;br&gt;
-&lt;/em&gt; &lt;a href="/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://jasongrout.github.io/medium-archive/pelican/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;/blockquote&gt;
&lt;blockquote&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;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To summarize:&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;- with&lt;/em&gt; &lt;em&gt;&lt;strong&gt;value semantics&lt;/strong&gt;&lt;/em&gt;, &lt;em&gt;objects hold actual values, and copying an object copies their attributes. With value semantics, one should provide implementations of&lt;/em&gt; &lt;em&gt;&lt;strong&gt;copy, and move constructors&lt;/strong&gt;&lt;/em&gt;*, as well as* &lt;em&gt;&lt;strong&gt;copy and move assignment operators&lt;/strong&gt;&lt;/em&gt;*. Besides, values should not have virtual methods.*&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;- with&lt;/em&gt; &lt;em&gt;&lt;strong&gt;reference semantics&lt;/strong&gt;&lt;/em&gt;*, objects are manipulated through references (or pointers) and never by value. Reference semantics is typically used for polymorphic programming with* &lt;em&gt;&lt;strong&gt;virtual methods&lt;/strong&gt;&lt;/em&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;em&gt;&lt;strong&gt;clone&lt;/strong&gt;&lt;/em&gt; &lt;em&gt;virtual method.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&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://jasongrout.github.io/medium-archive/pelican/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;/em&gt; &lt;a href="https://github.com/xtensor-stack/xtensor"&gt;&lt;em&gt;xtensor&lt;/em&gt;&lt;/a&gt;, &lt;a href="http://eigen.tuxfamily.org/index.php?title=Main_Page"&gt;&lt;em&gt;eigen&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, or&lt;/em&gt; &lt;a href="https://github.com/blitzpp/blitz"&gt;&lt;em&gt;blitz&lt;/em&gt;&lt;/a&gt;&lt;em&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;/code&gt;&lt;/pre&gt;&lt;/div&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;&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;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="o"&gt;&amp;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;B&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="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&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;inline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xmaterialize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&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;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="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&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="n"&gt;this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&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;&lt;strong&gt;Precompilation and binary size optimization&lt;/strong&gt;&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;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;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;and in the source file (here in &lt;code&gt;xbutton.cpp&lt;/code&gt;), an instruction for the precompilation&lt;/li&gt;
&lt;/ul&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;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;/code&gt;&lt;/pre&gt;&lt;/div&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;&lt;span class="c1"&gt;// Call class-level observer.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&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="nx"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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="nx"&gt;m_value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&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;&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="nx"&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="nx"&gt;invoke_observers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m_name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&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;&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://jasongrout.github.io/medium-archive/pelican/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;&lt;strong&gt;C++ should allow overloading the dot operator&lt;/strong&gt;&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&gt;&lt;a href="https://mybinder.org/v2/gh/jupyter-xeus/xwidgets/stable?filepath=notebooks/xwidgets.ipynb"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2020-10-03:/medium-archive/pelican/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;p&gt;&lt;em&gt;JupyterCon 2020 keynote speaker announcement&lt;/em&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Benjamin Ragan Kelley" src="https://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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;/em&gt; &lt;a href="https://cfp.jupytercon.com/2020/schedule/tutorial-sessions/"&gt;&lt;em&gt;tutorials&lt;/em&gt;&lt;/a&gt; &lt;em&gt;and&lt;/em&gt; &lt;a href="https://cfp.jupytercon.com/2020/schedule/general-sessions/"&gt;&lt;em&gt;talks&lt;/em&gt;&lt;/a&gt; &lt;em&gt;is published.&lt;/em&gt; &lt;a href="https://www.eventbrite.com/e/jupytercon-2020-tickets-109183767588"&gt;&lt;em&gt;Join us&lt;/em&gt;&lt;/a&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://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2020-09-26:/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/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;p&gt;&lt;strong&gt;The &lt;code&gt;conf.json&lt;/code&gt; file&lt;/strong&gt;&lt;/p&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;it inherits from the &lt;code&gt;lab&lt;/code&gt; template,&lt;/li&gt;
&lt;li&gt;exports &lt;code&gt;text/html&lt;/code&gt;, and therefore will only work with the HTML and WebPDF exporters.&lt;/li&gt;
&lt;li&gt;and runs two preprocessors called &lt;code&gt;100-pygments&lt;/code&gt; and &lt;code&gt;500-reveal:&lt;/code&gt;&lt;/li&gt;
&lt;/ul&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;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;ul&gt;
&lt;li&gt;The &lt;code&gt;CSSHTMLHeaderPreprocessor&lt;/code&gt; inlines the CSS required for the syntax highlighting of input cells.&lt;/li&gt;
&lt;li&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;/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;p&gt;&lt;strong&gt;Jinja templates&lt;/strong&gt;&lt;/p&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://jasongrout.github.io/medium-archive/pelican/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;/em&gt; &lt;a href="https://github.com/SylvainCorlay/nbconvert-acme/."&gt;&lt;em&gt;here&lt;/em&gt;&lt;/a&gt;&lt;em&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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/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&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/the-templating-system-of-nbconvert-6/images/009-1_ey1ie8kpgPMTvHU6nvjKvw.mp4" 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>Report on the Jupyter Community Workshop on Dashboarding</title><link href="https://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2020-02-14:/medium-archive/pelican/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…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;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 Kernels (Photo credit to Lindsey Heagy)" src="https://jasongrout.github.io/medium-archive/pelican/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 Kernels (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="/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;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/report-on-the-jupyter-community-workshop-on/images/002-1_FMKOoximrvz6sASKu19C-g.webp" alt="" loading="lazy" data-body-image=""&gt;&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://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2019-12-29:/medium-archive/pelican/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…&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;h3 id="what-is-voila"&gt;What is Voilà?&lt;/h3&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;slideshows (with voila-reveal)&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="A Voilà slideshow created with the voila-reveal template." src="https://jasongrout.github.io/medium-archive/pelican/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;ul&gt;
&lt;li&gt;dashboards (with voila-gridstack)&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="A Voilà Dashboard based on the voila-gridstack template." src="https://jasongrout.github.io/medium-archive/pelican/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;h3 id="why-moving-voila-under-the-jupyter-governance"&gt;Why moving Voilà under the Jupyter governance?&lt;/h3&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;h3 id="resources"&gt;Resources&lt;/h3&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="/posts/2019/and-voila/"&gt;https://blog.jupyter.org/and-voilà-f6a2c08a4a93&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="acknowledgements"&gt;&lt;strong&gt;Acknowledgements&lt;/strong&gt;&lt;/h3&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;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/voila-is-now-an-official-jupyter-subproject/images/003-1_ZrMs1GjNdEYhsbqese6xVA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&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://jasongrout.github.io/medium-archive/pelican/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:jasongrout.github.io,2019-10-07:/medium-archive/pelican/posts/2019/field-report-on-the-kernel-community-workshop/</id><summary type="html">&lt;p&gt;From May 27th to May 29th, thirty developers from the Jupyter community met in Paris for a three-days workshop on the Jupyter kernel…&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://jasongrout.github.io/medium-archive/pelican/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://jasongrout.github.io/medium-archive/pelican/posts/2019/field-report-on-the-kernel-community-workshop/images/002-1_O0nYHhfEne2BH4XsknaPhg.mp4" 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="/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;&lt;strong&gt;A prototype Julia backend to Jupyter interactive Widgets.&lt;/strong&gt;&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://jasongrout.github.io/medium-archive/pelican/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;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/field-report-on-the-kernel-community-workshop/images/004-1_ZWbPC-X8_5rIU_kP03ztog.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
</content><category term="C++"/><category term="events"/><category term="kernels"/><category term="workshops"/></entry><entry><title>Jupyter Community Workshop: Building upon the Jupyter Kernel Protocol</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/jupyter-community-workshop-building-upon-the-jupyter/" rel="alternate"/><published>2019-04-04T09:52:00+00:00</published><updated>2019-04-11T14:17:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jasongrout.github.io,2019-04-04:/medium-archive/pelican/posts/2019/jupyter-community-workshop-building-upon-the-jupyter/</id><summary type="html">&lt;p&gt;We have some exciting news about the Jupyter Community Workshop on kernels!&lt;/p&gt;
</summary><content type="html">&lt;p&gt;We have some exciting news about the &lt;a href="/posts/2019/jupyter-community-workshops/"&gt;Jupyter Community Workshop&lt;/a&gt; on kernels!&lt;/p&gt;
&lt;p&gt;The workshop will be held in &lt;strong&gt;Paris&lt;/strong&gt;, France, from &lt;strong&gt;May 27th&lt;/strong&gt; to &lt;strong&gt;May 29th&lt;/strong&gt; 2019. The event is being hosted at Capital Fund Management(&lt;a href="https://www.cfm.fr//"&gt;CFM&lt;/a&gt;), in the heart of Paris.&lt;/p&gt;
&lt;p&gt;In this three-days event, we will have hands-on discussions, hacking sessions and technical presentations, with core Jupyter developers and custom language kernel authors. We will discuss the potential improvements and additions to the protocol, and work on common tools and infrastructure for testing and evaluating Jupyter kernels.&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/15PLTTyyhgzB15Qpal5uWD3oHRU3hR0_Bm-HEC59AbU8"&gt;&lt;strong&gt;Google Form&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;Why a Workshop on Jupyter Kernels?&lt;/p&gt;
&lt;/blockquote&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 now leverage other components of the stack, such as the notebook, the console, and interactive widgets.&lt;/p&gt;
&lt;p&gt;Most Jupyter kernel authors rely on the reference documentation for the Jupyter kernel protocol, and reach out to the core team for questions on the different communication channels. One of the objectives of this event is to foster collaboration between kernel developers, on the development of common tools for testing and supporting all aspect of the protocol.&lt;/p&gt;
&lt;p&gt;Beyond implementation of the current protocol, we will discuss the potential improvements and additions to the protocol, such as the support of debugging messages. Another issue to be discussed and worked on is the ability to parameterize kernelspecs, which has been extensively discussed at the last Jupyter developer meeting in Berkeley. Parameterized kernel specs could be used for kernels requiring extra command-line arguments. These arguments could be used to pass database connection credentials, or other metadata and parameters used for e.g. parallel computing frameworks.&lt;/p&gt;
&lt;p&gt;Common infrastructure for testing kernels, call into remote kernels with the kernel gateway would also be in scope for this event.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;Acknowledgements&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This would not have been possible without the generous support provided by &lt;a href="https://www.techatbloomberg.com/"&gt;Bloomberg&lt;/a&gt;, who made this workshop series possible.&lt;/p&gt;
&lt;p&gt;We are also grateful to &lt;a href="https://www.cfm.fr/"&gt;CFM&lt;/a&gt; for gracefully hosting the Jupyter kernels community workshop.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/jupyter-community-workshop-building-upon-the-jupyter/images/001-1_3piu1NkMJz9_5sA_j2wCdA.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
</content><category term="events"/><category term="kernels"/><category term="workshops"/></entry><entry><title>Jupyter Community Workshop: Dashboarding with Project Jupyter</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/jupyter-community-workshop-dashboarding-with-project/" rel="alternate"/><published>2019-02-19T18:02:00+00:00</published><updated>2019-02-19T18:23:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jasongrout.github.io,2019-02-19:/medium-archive/pelican/posts/2019/jupyter-community-workshop-dashboarding-with-project/</id><summary type="html">&lt;p&gt;We have some exciting news about the Jupyter Community Workshop on dashboarding!&lt;/p&gt;
</summary><content type="html">&lt;p&gt;We have some exciting news about the &lt;a href="/posts/2019/jupyter-community-workshops/"&gt;Jupyter Community Workshop&lt;/a&gt; on dashboarding!&lt;/p&gt;
&lt;p&gt;The workshop will be held in &lt;strong&gt;Paris&lt;/strong&gt;, France, from &lt;strong&gt;June 3rd to June 6th&lt;/strong&gt;, 2019. The event is being hosted at Center for Interdisciplinary Research (&lt;a href="https://cri-paris.org/"&gt;CRI&lt;/a&gt;), in the heart of Paris.&lt;/p&gt;
&lt;p&gt;The workshop committee consists of Maarten Breddels (&lt;a href="https://www.maartenbreddels.com/"&gt;Freelance&lt;/a&gt;), Pascal Bugnion (&lt;a href="https://faculty.ai"&gt;Faculty.ai&lt;/a&gt;), Sylvain Corlay (&lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;), Alexandre Gramfort (&lt;a href="https://team.inria.fr/parietal/"&gt;INRIA&lt;/a&gt;), and Vidar Tonaas Fauske (&lt;a href="https://www.simula.no/"&gt;Simula&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The workshop will last four days, with hands-on discussions, hacking sessions, and technical presentations. The goal of the event is to foster collaboration and the sharing of knowledge between downstream library authors and contributors, and favor upstream contributions.&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/1T8rwWch1MBf_k6qSaaBTws-oqsO7tr-n4Gkmv2AUZ40"&gt;&lt;strong&gt;Google Form&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In addition to the Community Workshop, we plan on holding a public Meetup on June 5th, in partnership with the &lt;a href="https://www.meetup.com/PyData-Paris/"&gt;PyData Paris Meetup&lt;/a&gt;, with a series of lightning talks of Project Jupyter and related projects.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;Why a Workshop on Dashboarding?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Jupyter ecosystem has great tools for teaching, exploration and development. Dashboards allow users to interact with a kernel with interactive controls, plots, maps, etc., and allow researchers and data scientists to share their results with students, with their peers, and with the general public. Currently, users of Jupyter are (mostly) forced towards other Python or R libraries or they make direct use of front-end technologies or develop directly in JavaScript.&lt;/p&gt;
&lt;p&gt;There are existing early technologies that allow serving dashboards based on notebooks, most notably &lt;a href="https://github.com/QuantStack/voila"&gt;voila&lt;/a&gt;. The goal of this workshop is to gather core Jupyter widgets developers, members of the community and users with experience in dashboarding to bring dashboarding to a level where it can be used by all members of the Jupyter ecosystem. Ultimately, we envisage users being able to develop and deploy dashboards entirely within the Jupyter ecosystem.&lt;/p&gt;
&lt;p&gt;We will lay the foundations for dashboarding as a first-class citizen in the Jupyter ecosystem.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Acknowledgements&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This would not have been possible without the generous support provided by &lt;a href="https://www.techatbloomberg.com/"&gt;Bloomberg&lt;/a&gt;, who made this workshop series possible.&lt;/p&gt;
&lt;p&gt;We are also grateful to the &lt;a href="https://cri-paris.org/"&gt;CRI&lt;/a&gt; for gracefully hosting the dashboarding community workshop.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/jupyter-community-workshop-dashboarding-with-project/images/001-1_r86y02IscdD91lt-mwYswg.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
</content><category term="dashboards"/><category term="events"/><category term="workshops"/></entry><entry><title>Release of ipywidgets 6.0</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2017/ipywidgets-6-release/" rel="alternate"/><published>2017-03-01T15:44:00+00:00</published><updated>2017-08-28T18:33:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jasongrout.github.io,2017-03-01:/medium-archive/pelican/posts/2017/ipywidgets-6-release/</id><summary type="html">&lt;p&gt;We are pleased to announce the release of ipywidgets 6.0, the Jupyter interactive widget library. Jupyter interactive widgets enable building simple GUIs in the Jupyter notebook. ipywidgets 6.0 is a major release of the project. In this release, we closed 197 issues and 309 pull requests with 732&lt;/p&gt;
</summary><content type="html">&lt;p&gt;We are pleased to announce the release of ipywidgets 6.0, the Jupyter interactive widget library. Jupyter interactive widgets enable building simple GUIs in the Jupyter notebook.&lt;/p&gt;
&lt;p&gt;ipywidgets 6.0 is a major release of the project. In this release, we closed &lt;a href="https://github.com/ipython/ipywidgets/issues?utf8=%E2%9C%93&amp;amp;q=is%3Aissue%20is%3Aclosed%20milestone%3A6.0%20"&gt;197 issues&lt;/a&gt; and &lt;a href="https://github.com/ipython/ipywidgets/pulls?q=is%3Apr+milestone%3A6.0+is%3Aclosed"&gt;309 pull requests&lt;/a&gt; with &lt;a href="https://github.com/ipython/ipywidgets/compare/5.2.2...6.0.0"&gt;732 commits&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="installation"&gt;Installation&lt;/h3&gt;
&lt;p&gt;Using conda:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;ipywidgets&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using pip:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;ipywidgets
jupyter&lt;span class="w"&gt; &lt;/span&gt;nbextension&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--py&lt;span class="w"&gt; &lt;/span&gt;--sys-prefix&lt;span class="w"&gt; &lt;/span&gt;widgetsnbextension
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="whats-new-in-ipywidgets-60"&gt;What’s new in ipywidgets 6.0?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Custom widget styling&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In addition to the existing &lt;code&gt;Widget.layout&lt;/code&gt; attribute, which enables the specification of layout-related css properties for the top-most DOM element of a widget, we added a new &lt;code&gt;Widget.style&lt;/code&gt; attribute. This attribute enables custom styling of various widget types (such as &lt;code&gt;Button.style.button_color&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;The top-level styling properties that were deprecated in ipywidgets 5.0 have been removed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Using widgets outside of the notebook&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Another change in 6.0 is the ability to render Jupyter interactive widgets outside of the notebook:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Widgets can be rendered in Sphinx documentation, either with the &lt;code&gt;jupyter-sphinx&lt;/code&gt; extension or the &lt;code&gt;nbsphinx&lt;/code&gt; notebook converter.&lt;/li&gt;
&lt;li&gt;Widgets now &lt;a href="http://nbviewer.jupyter.org/github/ipython/ipywidgets/blob/6.0.0/docs/source/examples/Widget%20List.ipynb"&gt;render on nbviewer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Jupyter interactive widgets can be embedded into static web sites, such as &lt;a href="http://jupyter.org/widgets"&gt;http://jupyter.org/widgets&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Custom widget libraries built upon ipywidgets 6.0 can also take advantage of these features.&lt;/p&gt;
&lt;p&gt;This feature required the formal specification of a mime type for Jupyter interactive widgets, which is now contained in the new &lt;code&gt;jupyter-widgets-schema&lt;/code&gt; npm package.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Redesign of the core widgets&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The widgets provided with the base Jupyter widget libraries have gone through a major re-design.&lt;/p&gt;
&lt;p&gt;We also migrated from the &lt;code&gt;less&lt;/code&gt; CSS preprocessor to the use of css variables. In addition to the main benefits of adopting web standards, we take advantage of css variables defined in JupyterLab to style the interactive widgets consistent with the environment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Migration to Typescript&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;jupyter-js-widgets&lt;/code&gt; JavaScript package, which is the front-end component of ipywidgets, has been completely refactored and migrated to the Typescript programming language. We also adopted the &lt;a href="http://phosphorjs.github.io/"&gt;PhosphorJS&lt;/a&gt; JavaScript framework, which is at the foundation of the JupyterLab project, for better layout capability and integration with JupyterLab.&lt;/p&gt;
&lt;h3 id="credits"&gt;Credits&lt;/h3&gt;
&lt;p&gt;This release has been a team effort of a large number of contributors. We would like to thank the following 31 people who contributed, and especially the 14 people who contributed for the first time in this release.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Contributors to this release (alphabetical order):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Afshin Darian (first contribution)&lt;br&gt;
Adam Chainz (first contribution)&lt;br&gt;
Benjamin Ragan-Kelley&lt;br&gt;
Brian Granger&lt;br&gt;
Cameron Oelsen (first contribution)&lt;br&gt;
Carol Willing&lt;br&gt;
Dave Willmer&lt;br&gt;
denfromufa&lt;br&gt;
Giles Weaver (first contribution)&lt;br&gt;
Gino Bustelo&lt;br&gt;
Grant Nestor (first contribution)&lt;br&gt;
Jason Grout&lt;br&gt;
Javier Pedemonte&lt;br&gt;
Jeff (first contribution)&lt;br&gt;
Jeroen Demeyer&lt;br&gt;
Jonathan Frederic&lt;br&gt;
Justin McCandless (first contribution)&lt;br&gt;
Ludwig Schmidt-Hackenberg (first contribution)&lt;br&gt;
Maarten Breddels (first contribution)&lt;br&gt;
Martin Renou (first contribution)&lt;br&gt;
Matthew Craig&lt;br&gt;
Matthias Bussonnier&lt;br&gt;
Michael Pacer (first contribution)&lt;br&gt;
Oliver Evans (first contribution)&lt;br&gt;
Paul Ivanov&lt;br&gt;
Philipp Rudiger (first contribution)&lt;br&gt;
Srinivas Kumar Sunkara (first contribution)&lt;br&gt;
Steven Silvester&lt;br&gt;
stonebig (first contribution)&lt;br&gt;
Thomas Kluyver&lt;br&gt;
Sylvain Corlay&lt;br&gt;
Yoshiki Vázquez Baeza&lt;/p&gt;
</content><category term="releases"/><category term="widgets"/></entry></feed>