<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Jupyter Blog - GitHub</title><link href="https://jasongrout.github.io/medium-archive/pelican/" rel="alternate"/><link href="https://jasongrout.github.io/medium-archive/pelican/feeds/tag-github.atom.xml" rel="self"/><id>https://jasongrout.github.io/medium-archive/pelican/</id><updated>2022-08-11T09:23:00+00:00</updated><subtitle>The Project Jupyter blog: news, releases, and community stories, archived from blog.jupyter.org.</subtitle><entry><title>Requiring 2FA for Jupyter GitHub Organizations</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2022/requiring-2fa-for-jupyter-github-organizations/" rel="alternate"/><published>2022-07-05T15:00:00+00:00</published><updated>2022-08-11T09:23:00+00:00</updated><author><name>Rick Wagner</name></author><id>tag:jasongrout.github.io,2022-07-05:/medium-archive/pelican/posts/2022/requiring-2fa-for-jupyter-github-organizations/</id><summary type="html">&lt;p&gt;This requirement and the outlined plan was discussed and agreed upon at the Jupyter Governance meeting on Friday, July 1, 2022.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;em&gt;This requirement and the outlined plan was discussed and agreed upon at the Jupyter Governance meeting on Friday, July 1, 2022.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;By October 1, 2022, Project Jupyter aims to &lt;a href="https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-two-factor-authentication-for-your-organization/requiring-two-factor-authentication-in-your-organization"&gt;require two-factor authentication (2FA)&lt;/a&gt; for all GitHub organizations hosting repositories for &lt;a href="https://jupyter.org/governance/list_of_subprojects.html#official-subprojects-with-ssc-representation"&gt;official Jupyter Subprojects&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.blog/2021-08-16-securing-your-github-account-two-factor-authentication/"&gt;Enabling 2FA&lt;/a&gt; is the single most important step Jupyter contributors can take to protect their GitHub accounts from bad actors. This benefits the entire Jupyter Community by reducing the chance for malicious code to be slipped into a repository.&lt;/p&gt;
&lt;p&gt;Fortunately, most Jupyter GitHub organization members and external collaborators have 2FA enabled, at this time. This process will get us to 100% so we can enable the requirement as a GitHub org setting.&lt;/p&gt;
&lt;h2 id="whats-the-process"&gt;What’s the process?&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa"&gt;GitHub Documentation on 2FA&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We recommend that all GitHub users secure their account with 2FA, even if you don’t have an organizational role like admin or owner, or write permissions to a Jupyter repository.&lt;/p&gt;
&lt;p&gt;Over the next month (by August 1, 2022) contributors to the Jupyter Security Subproject will reach out to owners of each Jupyter GitHub org with a list of their users without 2FA enabled. The list of users will be an intersection across the GitHub orgs so that users aren’t contacted multiple times, and org maintainers are asked to do double work.&lt;/p&gt;
&lt;p&gt;From there, the org owners can decide how they want to work within their area of the Community. They may choose to contact the users or ask the Security Subproject to reach out to the users. Or, the users without 2FA may no longer need the access or role they were granted.&lt;/p&gt;
&lt;p&gt;At end of August, 2022, we’ll review the list of the remaining accounts without 2FA. (Hopefully none!) If possible, we’ll begin enabling the requirement on our GitHub orgs. The Security Subproject will work with org owners on plans for contacting any remaining users.&lt;/p&gt;
&lt;p&gt;At the end of September, 2022, users without 2FA enabled may lose explicit permissions or roles within Jupyter GitHub orgs. This will only impact access to private repositories, commit privileges, or having a role such as owner or admin. Read access to public repositories will remain the same, along with opening issues or pull requests. And once users enable 2FA on their account, any previous permissions or roles can be restored.&lt;/p&gt;
&lt;h2 id="what-github-orgs-does-this-apply-to"&gt;What GitHub orgs does this apply to?&lt;/h2&gt;
&lt;p&gt;All GitHub orgs hosting repositories for &lt;a href="https://jupyter.org/governance/list_of_subprojects.html#official-subprojects-with-ssc-representation"&gt;official Jupyter Subprojects&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ipython/"&gt;IPython&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter/"&gt;Jupyter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyterlab/"&gt;JupyterLab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyterhub/"&gt;JupyterHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/voila-dashboards/"&gt;Voilà&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-server/"&gt;Jupyter Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-widgets/"&gt;Jupyter Widgets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-xeus/"&gt;jupyter-xeus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><category term="GitHub"/><category term="security"/></entry><entry><title>Securely pushing to GitHub from a JupyterHub with gh-scoped-creds</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2022/securely-pushing-to-github-from-a-jupyterhub/" rel="alternate"/><published>2022-04-21T16:54:00+00:00</published><updated>2022-04-21T16:57:00+00:00</updated><author><name>yuvipanda</name></author><id>tag:jasongrout.github.io,2022-04-21:/medium-archive/pelican/posts/2022/securely-pushing-to-github-from-a-jupyterhub/</id><summary type="html">&lt;p&gt;Many JupyterHub users want to push and pull their content from GitHub in order to collaborate and share their work. However, working on a…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2022/securely-pushing-to-github-from-a-jupyterhub/images/001-1_9E0cif7g07xWAOfsFFmijw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Many JupyterHub users want to push and pull their content from GitHub in order to collaborate and share their work. However, working on a JupyterHub means working on &lt;em&gt;shared infrastructure&lt;/em&gt;, not your own laptop, and this poses some extra security risks that have made two-way sync with GitHub more difficult. This post describes &lt;code&gt;gh-scoped-creds&lt;/code&gt;, a new tool to make it quick and easy to authorize a JupyterHub session with push access to GitHub in a secure and simple manner.&lt;/p&gt;
&lt;p&gt;GitHub user credentials are &lt;a href="https://github.blog/2022-04-15-security-alert-stolen-oauth-user-tokens/"&gt;high value targets&lt;/a&gt; for cybercriminals in today’s security environment, and any system that stores these credentials long term paints an unwanted target on itself. Current solutions — putting an ssh key on the JupyterHub, using a &lt;a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token"&gt;personal access token&lt;/a&gt; or deploy keys — involve storing long term valid GitHub credentials in the filesystem. As users can do this by themselves without admin intervention, admins often are not aware these (often unencrypted) credentials are on their filesystems. If an attacker compromises an ssh key or a personal access token, they have unlimited access to all GitHub repos the compromised user had access to, including repos in high-impact GitHub organizations. In the recent credential theft incident, Travis-CI and Heroku were ‘lucky’ in that the &lt;a href="https://github.blog/2022-04-15-security-alert-stolen-oauth-user-tokens/"&gt;attackers accessed npm infrastructure&lt;/a&gt; — and since npm is owned by GitHub, GitHub was able to detect that Travis CI and Heroku had compromised credentials. You and the users of repositories you have rights to might not be so lucky. It’s 2022, and &lt;a href="https://github.com/cncf/tag-security/blob/main/supply-chain-security/compromises/README.md"&gt;supply chain attacks are everywhere&lt;/a&gt; — you aren’t special, you’re just one link in a long chain attackers use to get to someone else.&lt;/p&gt;
&lt;p&gt;There is a clear need for a simple solution that lets users push to GitHub from JupyterHub in a secure manner without admins having to worry about securing high-value GitHub credentials long term. It is not acceptable to “Just Say No” to users wanting this functionality either — if you try to ‘sacrifice’ usability for security, you end up getting neither.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/yuvipanda/gh-scoped-creds/"&gt;&lt;code&gt;gh-scoped-creds&lt;/code&gt;&lt;/a&gt; attempts to solve this problem by allowing users to grant &lt;em&gt;time-limited&lt;/em&gt; push access to &lt;em&gt;specific repositories&lt;/em&gt; to &lt;em&gt;specific JupyterHub installations&lt;/em&gt; in a user friendly way.&lt;/p&gt;
&lt;p&gt;Here’s a quick GIF running through the user workflow.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2022/securely-pushing-to-github-from-a-jupyterhub/images/002-1_B3qjACXLBG9pBOlzY8WNxA.mp4" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Push access is scoped both by time (credentials expire after 8 hours) as well as repository (access is granted per-repository, per-hub). While you need to refresh credentials every 8 hours, the list of repositories is remembered until you explicitly revoke access. You can always grant access to your own personal repositories, but repositories belonging to organisations might require admins to approve push access to them.&lt;/p&gt;
&lt;p&gt;You can also run the command from the terminal as &lt;code&gt;gh-scoped-creds&lt;/code&gt; instead of using the IPython magic &lt;code&gt;%ghscopedcreds&lt;/code&gt; as shown in the demo. This way, you can also use this from a HPC system, not just a JupyterHub!&lt;/p&gt;
&lt;p&gt;Setting this up for your JupyterHub requires a tiny bit of work from the admin — see &lt;a href="https://github.com/yuvipanda/gh-scoped-creds/"&gt;the project README&lt;/a&gt; for more details. Shouldn’t take long, and it’s a one-time task. Once that’s set up, your users can securely push to GitHub from the comfort of their JupyterHubs!&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="https://twitter.com/fperez_org"&gt;Fernando Perez&lt;/a&gt; for using his &lt;a href="https://classes.berkeley.edu/content/2021-spring-stat-159-001-lec-001"&gt;stat159 class&lt;/a&gt; at &lt;a href="https://www.berkeley.edu/"&gt;UC Berkeley&lt;/a&gt; to test this project out.&lt;/p&gt;
</content><category term="GitHub"/><category term="JupyterHub"/></entry><entry><title>Binder + Zenodo: A how-to guide</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/binder-with-zenodo/" rel="alternate"/><published>2019-06-21T13:46:00+00:00</published><updated>2019-06-22T15:42:00+00:00</updated><author><name>Chris Holdgraf</name></author><id>tag:jasongrout.github.io,2019-06-21:/medium-archive/pelican/posts/2019/binder-with-zenodo/</id><summary type="html">&lt;p&gt;Interactive and reproducible repositories powered by Zenodo and Binder.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Interactive and reproducible repositories powered by &lt;a href="https://zenodo.org/"&gt;Zenodo&lt;/a&gt; and &lt;a href="https://mybinder.org/"&gt;Binder&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When the Binder project was first launched, we imagined a world in which scientific scholarship and reproducibility could be carried out by the community using a fully-open stack of technology. We’re happy to say that this is now possible!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Zenodo DOIs now work with BinderHub" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/binder-with-zenodo/images/001-1_r8_qd2QciZ9B4hD2QnYXwQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Zenodo DOIs now work with BinderHub&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;a href="https://binderhub.readthedocs.io/"&gt;BinderHub&lt;/a&gt; team recently added in support for building Binder links that point to &lt;a href="https://zenodo.org/"&gt;Zenodo repositories&lt;/a&gt;. Zenodo is a general purpose open-access repository hosted by CERN that allows researchers to archive and apply a DOI to information that they put up on the web.&lt;/p&gt;
&lt;p&gt;Zenodo has the ability to archive &lt;strong&gt;GitHub repositories&lt;/strong&gt;, which means that you can archive the code, data, or reports that underly a scientific analysis and assign it a unique, citeable identifier. Now that BinderHub knows how to resolve a Zenodo identifier, you’ll be able to share Binder links that point to Zenodo and provide interactive access to your repository, letting readers reproduce results and interact with your analyses!&lt;/p&gt;
&lt;p&gt;Here’s a quick primer for how to do this:&lt;/p&gt;
&lt;h2 id="step-1-create-a-zenodo-account"&gt;Step 1: Create a Zenodo account&lt;/h2&gt;
&lt;p&gt;First off you’ll need to create an account on Zenodo. You can&lt;br&gt;
do so using a number of different log-in options.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/binder-with-zenodo/images/002-0_SbAeCLCNSpmbRQB6.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;h2 id="step-2-create-your-binder-ready-repository-on-github"&gt;Step 2: Create your Binder-ready repository on GitHub&lt;/h2&gt;
&lt;p&gt;Next, you should create your Binder-ready repository on GitHub. Binder uses pre-existing best practices in data science in order to infer and build the environment needed for your repository.&lt;/p&gt;
&lt;p&gt;To make a repository Binder-ready, &lt;a href="https://mybinder.readthedocs.io/en/latest/introduction.html"&gt;follow the instructions in the Binder docs&lt;/a&gt;.&lt;br&gt;
Briefly, what you need to do is add the configuration files that define the environment needed to run your code. Once those files are in place, and you’ve added an analysis script (a Jupyter or R Notebook) that actually runs your code and displays the results, your repository is ready to build with Binder.&lt;/p&gt;
&lt;h2 id="step-3-make-sure-your-repository-is-ready-to-be-published"&gt;Step 3: Make sure your repository is ready to be published!&lt;/h2&gt;
&lt;p&gt;Once you create a DOI for your repository, it will be frozen in time — you won’t be able to easily update it. So double check that the repository builds properly with Binder and runs the way that you’d expect it to.&lt;/p&gt;
&lt;p&gt;Make sure to launch a Binder from your repository and run the analyses you’d like others to run. If they produce the expected result from within a Binder session, then they’ll continue to do so for others (assuming you have pinned your versions and followed other best practices in reproducibility).&lt;/p&gt;
&lt;h2 id="step-4-create-a-zenodo-doi-for-your-repository"&gt;Step 4: Create a Zenodo DOI for your repository&lt;/h2&gt;
&lt;p&gt;Now that your repository is ready, you’ll connect Zenodo with GitHub to create a DOI for your repository. Remember that this will be unique to the current state of the repo — future changes to this repository won’t be reflected in the DOI.&lt;/p&gt;
&lt;p&gt;We recommend following the &lt;a href="https://guides.github.com/activities/citable-code/"&gt;GitHub &lt;strong&gt;Citable Code Guide&lt;/strong&gt;&lt;/a&gt; which provides some best-practices for creating your Zenodo DOI for a GitHub repository. Click the image below to be taken to this (excellent) guide.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The GitHub Citable Code guide." src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/binder-with-zenodo/images/003-0_LIxxv68WDxy6VkfY.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The GitHub Citable Code guide.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Once you’re done, you should have a Zenodo DOI badge&lt;br&gt;
like the one below:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A Zenodo DOI badge" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/binder-with-zenodo/images/004-1_CfBmxs8apLrlbGN5vG9MTA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A Zenodo DOI badge&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="step-5-create-a-binder-link-for-your-zenodo-doi"&gt;Step 5: Create a Binder link for your Zenodo DOI&lt;/h2&gt;
&lt;p&gt;Finally, use your Zenodo DOI to create a Binder link that allows others to interact with and replicate your results. You can create a Binder link for your Zenodo record by heading to &lt;a href="https://mybinder.org/"&gt;https://mybinder.org&lt;/a&gt; and filling in the form:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Building a Binder link for your Zenodo archive with the Binder UI." src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/binder-with-zenodo/images/005-1_xOABVY2hNtVmjV5-LXreFw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Building a Binder link for your Zenodo archive with the Binder UI.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This will give you a link you can share with others as well as the Markdown and reStructured text snippets for creating a badge.&lt;/p&gt;
&lt;p&gt;The link’s structure should look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://mybinder.org/v2/zenodo/&amp;lt;zenodo-DOI&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For example, if your Zenodo DOI is &lt;code&gt;10.5281/zenodo.3242074&lt;/code&gt; (corresponding to &lt;a href="https://doi.org/10.5281/zenodo.3242074"&gt;this zenodo repository&lt;/a&gt;), the Binder link for it would be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://mybinder.org/v2/zenodo/10.5281/zenodo.3242074/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can even pair this Binder link with your Zenodo DOI badge that&lt;br&gt;
we showed above!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The “launch binder” button contains a Binder link for your Zenodo archive. Clicking will launch a Binder session." src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/binder-with-zenodo/images/006-1_hFRv6rDl9BekAFkxDpowOg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The “launch binder” button contains a Binder link for your Zenodo archive. Clicking will launch a Binder session.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;And that’s it! You now have an archived version of your analysis with a unique identifier. This identifier can be used in conjunction with BinderHub to allow readers to &lt;em&gt;interact&lt;/em&gt; with your code and results!&lt;/p&gt;
&lt;h2 id="last-minute-update"&gt;Last minute update 🎉&lt;/h2&gt;
&lt;p&gt;A few hours before publishing this post we merged a contribution from &lt;a href="https://twitter.com/temorrell"&gt;Tom Morrell&lt;/a&gt; who works at CalTech’s library that allows you to launch records from &lt;a href="https://data.caltech.edu/"&gt;CalTech’s Data Repository&lt;/a&gt; as well! For example a notebook to analyze traffic to the archive itself: &lt;a href="https://mybinder.org/v2/zenodo/10.22002/d1.1250"&gt;https://mybinder.org/v2/zenodo/10.22002/d1.1250&lt;/a&gt;. You should also check out &lt;a href="https://medium.com/@lorenaabarba/excellent-6b99d506aa28"&gt;a quick response to this post from Lorena Barba&lt;/a&gt;, who describes her group’s approach to creating reproducible, citable bundles for figures in papers, and how Binder+Zenodo DOIs might fit into that workflow!&lt;/p&gt;
&lt;h2 id="whats-next"&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;We are close to closing the loop of fully reproducible computational environments for scientific publication. We’re excited to see journals begin to integrate these workflows with their own publishing pipelines. For example, the &lt;a href="https://conp-pcno.github.io/"&gt;Neurolibre project&lt;/a&gt; is deploying their own BinderHub and using it alongside their reviewing and archiving process in order to provide more rich&lt;br&gt;
interaction with submitted material.&lt;/p&gt;
&lt;p&gt;Each type of repository needs a small amount of custom work to be integrated with Binder. We started with Zenodo because it is well known,&lt;br&gt;
general purpose and integrated with GitHub already. If there is an archive you’d like to see integrated please do stop by &lt;a href="https://github.com/jupyter/repo2docker"&gt;this repository&lt;/a&gt; and open a new issue or contribute the code to do so directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you’re working with a publisher and are interested in this&lt;/strong&gt;&lt;br&gt;
please reach out! The Binder community would love to work with you in deploying these open tools to make your published work more open and accessible. Whether it is big or small, we hope that these workflows can make an impact across the publishing landscape, and we’re looking forward to seeing what people do next!&lt;/p&gt;
</content><category term="Binder"/><category term="GitHub"/><category term="open science"/><category term="reproducibility"/></entry><entry><title>Introducing repo2docker</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2018/introducing-repo2docker/" rel="alternate"/><published>2018-12-14T18:24:00+00:00</published><updated>2018-12-14T19:02:00+00:00</updated><author><name>Chris Holdgraf</name></author><id>tag:jasongrout.github.io,2018-12-14:/medium-archive/pelican/posts/2018/introducing-repo2docker/</id><summary type="html">&lt;p&gt;The Binder Project’s repo2docker tool gives data scientists the benefits of containerization technology without needing to learn Docker…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/introducing-repo2docker/images/001-1_mZMTfkZE6o94aIr6DG-hYA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;The Binder Project’s &lt;a href="https://repo2docker.readthedocs.io/en/latest/"&gt;repo2docker&lt;/a&gt; tool gives data scientists the benefits of containerization technology without needing to learn Docker itself. To make your repository compatible with repo2docker, you only need to add text files that are already present in many repositories. This means that you get the benefits of containerization, a powerful and complex ecosystem, without having to change your workflow.&lt;/p&gt;
&lt;p&gt;repo2docker is a lightweight command-line tool written in Python that takes a path or URL to a git repository and creates a suitable docker image for it. To achieve this it follows the steps that a human would take to do so. The steps are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Inspect the repository for common “configuration” files (like &lt;code&gt;requirements.txt&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;From these well-known files infer the Docker commands to run; and&lt;/li&gt;
&lt;li&gt;Build a Docker image.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It has a few more tricks up its sleeve, such as automatically installing RStudio for you when it detects that you are using R. Once the image has been built, a Docker container is created and executed, giving you access to the environment in which the repository author wanted the code to be executed. To achieve this, one needs access to two things: repo2docker and a docker daemon (they do not necessarily have to have docker installed on their local computer).&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://jupyterhub-team-compass.readthedocs.io/en/latest/team.html#jupyterhub-team"&gt;JupyterHub team&lt;/a&gt; just released &lt;a href="https://github.com/jupyter/repo2docker/blob/0.7.0/CHANGES.rst#version-070"&gt;v0.7 of repo2docker&lt;/a&gt;, so we decided to spend a bit of time explaining what it’s all about.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="An example repo2docker workflow. In this case, repo2docker is invoked locally. repo2docker is passed a URL to a git repository (). It then clones the repository, discovers configuration files in the repo (in this case, requirements.txt), builds a Docker image with this environment installed, and opens a local Jupyter server to explore and run the contents of the repo." src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/introducing-repo2docker/images/002-1_lPmCcgJois-PygoFXI6Bhw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;An example repo2docker workflow. In this case, repo2docker is invoked locally. repo2docker is passed a URL to a git repository (&lt;a href="https://github.com/norvig/pytudes"&gt;https://github.com/norvig/pytudes&lt;/a&gt;). It then clones the repository, discovers configuration files in the repo (in this case, &lt;code&gt;requirements.txt&lt;/code&gt;), builds a Docker image with this environment installed, and opens a local Jupyter server to explore and run the contents of the repo.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="the-guiding-principles-behind-repo2docker"&gt;The guiding principles behind repo2docker&lt;/h2&gt;
&lt;p&gt;repo2docker is meant to be as lightweight and common-sense as possible. The driving principles behind repo2docker are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Leverage pre-existing workflows&lt;/strong&gt; in data science as much as possible. This means using standard configuration files (like &lt;code&gt;requirements.txt&lt;/code&gt;) instead of requiring people to learn new configuration patterns.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The shareable unit is a repository&lt;/strong&gt; or directory containing human-readable files. Not a single file (like a notebook) nor a binary blob (like a built docker image). This means that humans can inspect and extend other repositories meant for repo2docker, and that they can manually do what repo2docker does automatically. No black box.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be workflow agnostic&lt;/strong&gt;. repo2docker supports many languages and user interfaces, it can run arbitrary shell scripts that are baked into the image, or it can trigger a script to be run each time a person runs the Docker image.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be extensible and composable&lt;/strong&gt;. repo2docker should allow for multiple languages, tools, or workflows to be defined in a single GitHub repository. It should also be relatively easy to extend to support new use-cases.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable deterministic outputs&lt;/strong&gt;. We want repo2docker to make it possible for authors to generate the exact same environment from their repository every time, provided that they follow best-practices in computational methods (like providing specific version numbers for packages). repo2docker can build a specific commit, tag, or branch of a repository, which allows for an image to be deterministically built.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="how-can-repo2docker-be-used"&gt;How can repo2docker be used?&lt;/h2&gt;
&lt;p&gt;Over the last 18 months, we have been using repo2docker in production to automatically generate images that run repositories for &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt;.&lt;br&gt;
It is used to build around 1000 unique repositories every week. The core functionality has proven itself and is considered production ready.&lt;/p&gt;
&lt;p&gt;Over the last year, we’ve seen a few major use-cases come out of repo2docker:&lt;/p&gt;
&lt;p&gt;First, it can be used as a &lt;strong&gt;part of production systems&lt;/strong&gt; like BinderHub. BinderHub automatically uses repo2docker to build images that run a user’s environment, and lets them share links that let others interact with the image.&lt;/p&gt;
&lt;p&gt;Second, repo2docker can be used to &lt;strong&gt;build an image for use with a JupyterHub&lt;/strong&gt;. For example, teachers have used repo2docker to convert their GitHub repository with course materials into a runnable Docker image that students access via a shared jupyterhub in the cloud.&lt;/p&gt;
&lt;p&gt;Finally, repo2docker has been used by individuals who wish to &lt;strong&gt;build reproducible images from their local work&lt;/strong&gt;. repo2docker can optionally run a Jupyter server from within the built image, which makes it possible to verify the results of analyses in an environment that was built solely from the configuration files present in the repository.&lt;/p&gt;
&lt;h2 id="what-next"&gt;What next?&lt;/h2&gt;
&lt;p&gt;We think that repo2docker serves as a useful tool for the community and that it is an important part of the large reproducible scientific software stack. It gives data scientists the benefits of containerization technology without needing to learn a new tool like Docker. It achieves this by being a lightweight command-line tool written in Python that automates the creation of the environment in which the authors of a piece of software wanted it to be executed.&lt;/p&gt;
&lt;p&gt;We’d love to see the repo2docker community grow, and for more&lt;br&gt;
languages, interfaces, use-cases, and workflows to be supported&lt;br&gt;
with &lt;a href="https://repo2docker.readthedocs.io/en/latest/architecture.html?highlight=build%20pack#buildpack"&gt;repo2docker’s build pack system&lt;/a&gt;. Let us know what you think!&lt;/p&gt;
&lt;p&gt;repo2docker is primarily maintained by the &lt;a href="https://jupyterhub-team-compass.readthedocs.io/en/latest/team.html"&gt;JupyterHub and Binder teams&lt;/a&gt;. If you’d like to get involved with the community or want to learn&lt;br&gt;
more about the tool, reach out! Check out these links for more information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter/repo2docker"&gt;repo2docker repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://repo2docker.readthedocs.io"&gt;repo2docker documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://discourse.jupyter.org"&gt;JupyterHub community forum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitter.im/jupyterhub/binder"&gt;Binder gitter channel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/em&gt;*: some folks might be wondering why we developed repo2docker instead of contributing to a pre-existing containerization tool such as the excellent* &lt;a href="https://github.com/openshift/source-to-image"&gt;&lt;em&gt;source2image project&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. We take the decision to create new open-source tech very seriously, and wrote a blog post about our decision to do-so in this case:&lt;/em&gt; &lt;a href="http://words.yuvi.in/post/why-not-s2i/"&gt;http://words.yuvi.in/post/why-not-s2i/&lt;/a&gt;&lt;/p&gt;
</content><category term="Docker"/><category term="GitHub"/></entry><entry><title>We Analyzed 1 Million Jupyter Notebooks — Now You Can Too [Guest Post]</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2018/we-analyzed-1-million-jupyter-notebooks-now-you-can-too/" rel="alternate"/><published>2018-03-23T08:58:00+00:00</published><updated>2018-03-23T08:58:00+00:00</updated><author><name>Adam Rule</name></author><id>tag:jasongrout.github.io,2018-03-23:/medium-archive/pelican/posts/2018/we-analyzed-1-million-jupyter-notebooks-now-you-can-too/</id><summary type="html">&lt;p&gt;This is a guest post on how members of the Jupyter community publish code, visualizations, and text using Jupyter Notebooks. We’re excited…&lt;/p&gt;
</summary><content type="html">&lt;figure&gt;
&lt;img alt="One of the 1 million+ notebooks we scraped from GitHub in July 2017. This notebook combines code, visualizations, and text to create an effective computational narrative." src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/we-analyzed-1-million-jupyter-notebooks-now-you-can-too/images/001-1_dl30JL7jWGPtxuJIuJGGRg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;One of the 1 million+ notebooks we scraped from GitHub in July 2017. This notebook combines code, visualizations, and text to create an effective computational narrative.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a guest post on how members of the Jupyter community publish code, visualizations, and text using Jupyter Notebooks. We’re excited the Design Lab is sharing their research and data on the blog.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;If you have a post relevant to the community you’d like to share on the Jupyter Blog, please contact us.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;-The Jupyter Team&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In July 2017, my team in the &lt;a href="http://designlab.ucsd.edu"&gt;Design Lab&lt;/a&gt; at &lt;a href="http://ucsd.edu/"&gt;UC San Diego&lt;/a&gt; scraped and analyzed over 1 million Jupyter Notebooks from GitHub. &lt;strong&gt;Today I am excited to announce we are&lt;/strong&gt; &lt;a href="https://library.ucsd.edu/dc/collection/bb6931851t"&gt;&lt;strong&gt;making these data publicly available&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;for you to explore!&lt;/strong&gt; While only a snapshot of one corner of the Jupyter universe, these data provide unique perspective into how people use and share Jupyter Notebooks.&lt;/p&gt;
&lt;p&gt;The collection includes over 1 million notebooks as well as metadata about the nearly 200,000 repositories where they lived. The full dataset is nearly 600GB so we have created a smaller 5GB sampler dataset for you to get started. This includes roughly 6,000 notebooks from 1000 repositories.&lt;/p&gt;
&lt;p&gt;We originally collected these data to explore how people use narrative text in Jupyter Notebooks. We found many notebooks, even those accompanying academic publications, had little in the way of descriptive text. This is likely because many analysts view their notebooks as personal and messy works-in-progress. On the other hand, many of the notebooks we collected were masterpieces of &lt;a href="/posts/2015/project-jupyter-computatio-nalnarratives-as-the-engine/"&gt;computational narrative&lt;/a&gt;, elegantly explaining complex analyses (one notebook even had more text than &lt;em&gt;The Great Gatsby&lt;/em&gt;). We think this spread reflects a tension between data &lt;em&gt;exploration&lt;/em&gt;, which tends to produce messy notebooks, and process &lt;em&gt;explanation&lt;/em&gt;, in which analysts clean and organize their notebooks for a particular audience.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Over 25% of the 1 million+ notebooks we collected from GitHub had no descriptive text, yet some rivaled classic novels in length." src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/we-analyzed-1-million-jupyter-notebooks-now-you-can-too/images/002-1_0O1x_D0FTRUwX-6qdo1whA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Over 25% of the 1 million+ notebooks we collected from GitHub had no descriptive text, yet some rivaled classic novels in length.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Beyond simply counting lines and words, we also looked at how authors organized their code and text. For example, most notebooks had markdown headers and nearly a third linked to other resources. Most notebooks had code comments and over a third defined new functions.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Analyzing this data helped us see how people organize notebook code and text." src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/we-analyzed-1-million-jupyter-notebooks-now-you-can-too/images/003-1_AquKZXRbdFxzY74sTj34VA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Analyzing this data helped us see how people organize notebook code and text.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We will be presenting the full results of our analysis in April at the &lt;a href="http://chi2018.acm.org"&gt;2018 ACM CHI Conference on Human Factors in Computing Systems&lt;/a&gt; and you can read more about our work in this &lt;a href="http://adamrule.com/files/papers/chi_2018_computational_notebooks_final_web.pdf"&gt;preprint&lt;/a&gt; copy of our paper. In the meantime, our team has moved on to developing tools that take some of the effort out of cleaning and organizing Jupyter Notebooks.&lt;/p&gt;
&lt;p&gt;There is so much left to explore in the data we collected. We are excited to see what you do with them! Thank you to the UC San Diego Library for graciously hosting the data. If you encounter a problem downloading them, please open an issue on &lt;a href="https://github.com/activityhistory/jupyter_on_github"&gt;this GitHub repo&lt;/a&gt;.&lt;/p&gt;
</content><category term="GitHub"/></entry><entry><title>Rendering Notebooks on GitHub</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2015/rendering-notebooks-on-github/" rel="alternate"/><published>2015-05-07T19:47:00+00:00</published><updated>2017-08-28T20:08:00+00:00</updated><author><name>Project Jupyter</name></author><id>tag:jasongrout.github.io,2015-05-07:/medium-archive/pelican/posts/2015/rendering-notebooks-on-github/</id><summary type="html">&lt;p&gt;We are pleased to announce that, starting today, and as announced on the GitHub blog, Jupyter/IPython notebook (.ipynb) files will render directly on GitHub. This …&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2015/rendering-notebooks-on-github/images/001-1_Edn_LpbSpLeNKfWkEdG2Jg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;We are pleased to announce that, starting today, and as announced on &lt;a href="https://github.com/blog/1995-github-jupyter-notebooks-3"&gt;the GitHub blog&lt;/a&gt;, Jupyter/IPython notebook (&lt;code&gt;.ipynb&lt;/code&gt;) files will render directly on GitHub. This feature works for notebooks in any of the supported Jupyter &lt;a href="https://github.com/ipython/ipython/wiki/IPython-kernels-for-other-languages"&gt;programming languages&lt;/a&gt; on both public and private repos. This capability will complement &lt;a href="https://nbviewer.jupyter.org"&gt;nbviewer&lt;/a&gt; and make it easier for GitHub users to create, view and share notebooks on GitHub.&lt;/p&gt;
&lt;p&gt;Here are some great examples of notebook based content that can now be viewed directly on GitHub:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cameron Davidson-Pilon’s &lt;a href="https://github.com/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers/blob/master/Chapter1_Introduction/Chapter1.ipynb"&gt;Probabilistic Programming and Bayesian Methods for Hackers&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Lorena Barba’s &lt;a href="https://github.com/barbagroup/AeroPython/blob/master/lessons/01_Lesson01_sourceSink.ipynb"&gt;Aerodynamics-Hydrodynamics with Python&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Benjamin Laken’s &lt;a href="https://github.com/benlaken/Comment_BadruddinAslam2014/blob/master/Monsoon_analysis.ipynb"&gt;Monsoon Analysis&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We want to thank the GitHub team for bringing this new feature to GitHub. In particular &lt;a href="https://github.com/tclem"&gt;@tclem&lt;/a&gt;, &lt;a href="https://github.com/arfon"&gt;@arfon&lt;/a&gt;, &lt;a href="https://github.com/sshirokov"&gt;@sshirokov&lt;/a&gt;, and &lt;a href="https://github.com/skalnik"&gt;@skalnik&lt;/a&gt; have all done an incredible job building this at GitHub. The first discussion of how to bring notebook rendering to GitHub happened almost 18 months ago, and a lot of work made this feature possible today. With over &lt;a href="https://github.com/search?l=&amp;amp;q=nbformat+extension%3Aipynb&amp;amp;ref=advsearch&amp;amp;type=Code&amp;amp;utf8=%E2%9C%93"&gt;200,000 notebooks&lt;/a&gt; available on GitHub, you already have a lot to read!&lt;/p&gt;
&lt;p&gt;We are excited to see how this feature will impact science education and research on GitHub, as well as encourage the adoption of the Jupyter notebook as a standard file format across a wide range of fields. Jupyter notebook files are a JSON-based open document format that supports code and results, narrative text, images, and equations in one file. These documents simplify the creation and communication of computational narratives and make the sharing and replication of scientific results and data analyses simpler.&lt;/p&gt;
&lt;h3 id="nbviewer"&gt;nbviewer&lt;/h3&gt;
&lt;p&gt;One key piece of infrastructure in sharing notebooks has been the &lt;a href="http://nbviewer.org"&gt;nbviewer&lt;/a&gt; service, which started as a side project of mine in the late summer of 2012. Nbviewer has grown through deep integration with GitHub, with the ability to browse all public users, organizations, repositories, branches, tags, and even Gists. This would not have been possible without &lt;a href="https://github.com/rgbkrk"&gt;@rgbkrk&lt;/a&gt; and &lt;a href="https://github.com/bollwyvl"&gt;@bollwyvl&lt;/a&gt;, who handle the development and deployment of nbviewer. It would also not have been possible without &lt;a href="https://developer.rackspace.com/"&gt;Rackspace&lt;/a&gt; and &lt;a href="http://www.fastly.com/"&gt;Fastly&lt;/a&gt;, who provide free hosting and fast static asset distribution. Nbviewer has steadily grown to render hundreds of thousands of notebooks every week, and usage is still increasing. Based on this, we believe that rendering on GitHub will be a highly used and appreciated feature.&lt;/p&gt;
&lt;p&gt;Although you can now view notebooks directly on GitHub, we are not planning to stop the development of nbviewer. While rendering directly in GitHub repositories is convenient and allows viewing notebooks in private repositories, there are number of reasons that nbviewer will continue to remain an important part of project Jupyter.&lt;/p&gt;
&lt;p&gt;First, there are many notebooks not hosted on GitHub. As before, these notebooks can still be viewed on nbviewer. Furthermore, the Jupyter/IPython team are actively working on improving integration with other content providers, building on our experience with GitHub. For example, a recent pull request of &lt;a href="https://github.com/jupyter/nbviewer/pull/443"&gt;@bollwyvl&lt;/a&gt; streamlines the process of adding new providers to nbviewer, with &lt;a href="https://github.com/jupyter/nbviewer/issues?q=is%3Aopen+is%3Aissue+label%3Aprovider"&gt;proposals&lt;/a&gt; for DropBox, GitLab, Google Drive, Stash, and other hosting and collaboration platforms.&lt;/p&gt;
&lt;p&gt;Second, because of security concerns, some features available on nbviewer will not be available on GitHub. For example, GitHub will not render any dynamic output display that uses JavaScript, custom CSS, and most custom HTML embedded in Markdown or in outputs. When this is the case, and GitHub cannot fully render your notebooks, you will see an icon that allows you to view the full notebook on nbviewer.&lt;/p&gt;
&lt;p&gt;Because nbviewer does not handle authentication, it will continue to support custom CSS, HTML and JavaScript in notebook. Thus, for highly customized or dynamic notebooks, nbviewer will still be the ideal place to share them.&lt;/p&gt;
&lt;p&gt;We would love your feedback! If you have comments or find bugs with notebook rendering on GitHub or nbviewer, please open an issue on our &lt;a href="https://github.com/jupyter/nbviewer"&gt;nbviewer repo&lt;/a&gt;. Also, please send a few tweets to thank all the people without whom this would have not happened.&lt;/p&gt;
&lt;p&gt;The Jupyter/IPython Team&lt;/p&gt;
</content><category term="GitHub"/><category term="nbviewer"/><category term="publishing"/></entry></feed>