<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Jupyter Blog - Binder</title><link href="https://jasongrout.github.io/medium-archive/pelican/" rel="alternate"/><link href="https://jasongrout.github.io/medium-archive/pelican/feeds/tag-binder.atom.xml" rel="self"/><id>https://jasongrout.github.io/medium-archive/pelican/</id><updated>2026-04-08T23:34:00+00:00</updated><subtitle>The Project Jupyter blog: news, releases, and community stories, archived from blog.jupyter.org.</subtitle><entry><title>Berkeley Institute for Data Science (BIDS) joins the mybinder.org</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2026/berkeley-institute-for-data-science-bids-joins-the/" rel="alternate"/><published>2026-04-08T23:34:00+00:00</published><updated>2026-04-08T23:34:00+00:00</updated><author><name>yuvipanda</name></author><id>tag:jasongrout.github.io,2026-04-08:/medium-archive/pelican/posts/2026/berkeley-institute-for-data-science-bids-joins-the/</id><summary type="html">&lt;p&gt;The Berkeley Institute for Data Science (BIDS) is now a part of the mybinder.org federation!&lt;/p&gt;
</summary><content type="html">&lt;h2 id="berkeley-institute-for-data-science-bids-joins-the-mybinderorg-federation-in-partnership-with-2i2c"&gt;Berkeley Institute for Data Science (BIDS) joins the mybinder.org federation in partnership with 2i2c&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://bids.berkeley.edu/"&gt;Berkeley Institute for Data Science (BIDS)&lt;/a&gt; is the birthplace of the current iteration of &lt;a href="https://mybinder.org"&gt;mybinder.org&lt;/a&gt;, all the way back in 2017. In 2026, they are back as a member of the &lt;a href="https://mybinder.readthedocs.io/en/latest/about/federation.html"&gt;federation&lt;/a&gt;, joining &lt;a href="https://2i2c.org"&gt;2i2c&lt;/a&gt; and &lt;a href="https://www.gesis.org/en/home"&gt;GESIS&lt;/a&gt; in contributing to the cloud costs of keeping mybinder.org running!&lt;/p&gt;
&lt;p&gt;The BIDS node is running on the &lt;a href="https://us.ovhcloud.com/"&gt;OVH Cloud Provider&lt;/a&gt;, joining the two existing nodes (from 2i2c and GESIS) running on &lt;a href="https://www.hetzner.com/"&gt;Hetzner&lt;/a&gt;. By running on a different cloud provider than our existing nodes, we reduce the risk that a cloud provider outage or policy change will take down the entire mybinder.org service. This immediately came into play, as Hetzner is having &lt;a href="https://github.com/jupyterhub/mybinder.org-deploy/issues/3686"&gt;a lot of trouble with its object storage service&lt;/a&gt;, increasing failure rates on mybinder.org. We were able to &lt;a href="https://github.com/jupyterhub/mybinder.org-deploy/pull/3704"&gt;shift more of our users&lt;/a&gt; to the BIDS node seamlessly, reducing disruptions for our end users.&lt;/p&gt;
&lt;p&gt;The BIDS node thus temporarily served 50% of our traffic, taking a higher than usual share of the load as we wait for error rates on Hetzner object store to get better. It has served more than 64,000 users so far in the short time it’s been up, and expected to do more.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Graph with three lines, representing the three current mybinder.org federation members: 2i2c, BIDS and GESIS. Shows data from Dec 2025 — end of March 2026. BIDS starts roughly in mid 2025, and ramps up to roughly over 1000 launches per day. GESIS handles roughly 3000, 2i2c handles roughly 2000. The graph is periodic weekly, as usage drops during the weekends" src="https://jasongrout.github.io/medium-archive/pelican/posts/2026/berkeley-institute-for-data-science-bids-joins-the/images/001-1_7pRDcpGYyl1R6pBWsIC5UQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Graph of mybinder.org sessions across our federation members over the last 4 months, showing the BIDS member taking on more of the load over time as it is brought online. The graph is jagged due to dips in demand over the weekend&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This node was brought up in partnership with &lt;a href="https://2i2c.org"&gt;2i2c&lt;/a&gt;. 2i2c contributed expertise in extending the mybinder.org deployment infrastructure to run on OVH, as well as working with UC Berkeley procurement to ensure that the cloud costs can be paid for on a continuous basis. Many thanks to the ever awesome &lt;a href="http://github.com/minrk/"&gt;MinRK&lt;/a&gt; (who is now &lt;a href="https://bids.berkeley.edu/news/min-ragan-kelley-and-his-journey-back-bids"&gt;back to working at BIDS&lt;/a&gt;!) for a lot of the technical work in taking this through!&lt;/p&gt;
&lt;p&gt;Want your organization to join the mybinder.org federation, materially making a difference in resilience and availability of the service, even at just a few hundred dollars a month? Come talk to us &lt;a href="https://jupyter.zulipchat.com"&gt;on the Jupyter Zulip&lt;/a&gt;!&lt;/p&gt;
</content><category term="Binder"/></entry><entry><title>mybinder.org adding request Origin to events archive</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2026/mybinder-org-adding-request-origin-to-events-archive/" rel="alternate"/><published>2026-02-02T16:27:00+00:00</published><updated>2026-03-02T23:33:00+00:00</updated><author><name>Min RK</name></author><id>tag:jasongrout.github.io,2026-02-02:/medium-archive/pelican/posts/2026/mybinder-org-adding-request-origin-to-events-archive/</id><summary type="html">&lt;p&gt;In February, the mybinder.org service will start tracking the “origin” of requests that launch a Binder session. The website that created a…&lt;/p&gt;
</summary><content type="html">&lt;figure&gt;
&lt;img alt="The binder logo" src="https://jasongrout.github.io/medium-archive/pelican/posts/2026/mybinder-org-adding-request-origin-to-events-archive/images/001-1_gICbzIC3Qbq6ireueH1FYA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Binder logo&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In February, the &lt;a href="http://mybinder.org"&gt;mybinder.org&lt;/a&gt; service will start tracking the “origin” of requests that launch a Binder session. The website that created a request to &lt;a href="http://mybinder.org"&gt;mybinder.org&lt;/a&gt; will be visible in the Binder analytics archive. This will help us monitor which websites are embedding Binder sessions for impact or abuse reports. It shouldn’t have any implications for private information but we are sharing here for transparency. The only cases where new information will be recorded is websites which embed mybinder.org kernels via tools like &lt;a href="https://thebe.readthedocs.io"&gt;Thebe&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When folks use &lt;a href="https://mybinder.org"&gt;mybinder.org&lt;/a&gt; to run sessions, each launch is added to a public &lt;a href="https://archive.analytics.mybinder.org"&gt;events archive&lt;/a&gt;. That means that every time anyone launches a session on mybinder.org, the repo and version used and the time of the launch is &lt;strong&gt;public information&lt;/strong&gt;. There is no such thing as a private launch on mybinder.org (this is part of why we don’t support private repos). No information about the user &lt;em&gt;requesting the build&lt;/em&gt; is recorded (ip address, user agent, browser info, etc.), though some of that is sent to Plausible and aggregated and anonymized for &lt;a href="https://plausible.io/mybinder.org"&gt;analytics&lt;/a&gt;. Notably, Plausible only covers regular browser visits, not launches via the API.&lt;/p&gt;
&lt;p&gt;There are 3 main ways that people launch sessions on mybinder.org:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;(the vast majority) — visiting mybinder.org in a browser&lt;/li&gt;
&lt;li&gt;embedding &lt;em&gt;kernels&lt;/em&gt; from mybinder.org on another website to make e.g. interactive documentation with a tool like &lt;a href="https://thebe.readthedocs.io"&gt;Thebe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;‘headless’ launches via scripts&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Up to now, these events are indistinguishable in the events archive. We’d like to start distinguishing these cases in the events archive to better classify how mybinder.org is used, but that means recording new information we didn’t track before, so we want to communicate clearly about it ahead of time.&lt;/p&gt;
&lt;p&gt;We are planning to add the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Origin"&gt;&lt;strong&gt;Origin&lt;/strong&gt;&lt;/a&gt; of the launch request to the public events archive at the end of February. This still doesn’t track anything about the &lt;em&gt;&lt;strong&gt;user&lt;/strong&gt;&lt;/em&gt; (no ip address, user agent, etc.), but rather the host of the page where the launch request originated. For the vast majority of cases, this is not new information, as the origin is e.g. &lt;code&gt;gesis.mybinder.org&lt;/code&gt; (which we already track confusingly as ‘origin’, though this is not the request Origin, it is the &lt;em&gt;federation member&lt;/em&gt; where the launch event takes place). Notably, case 1 still includes any regular browser links to &lt;code&gt;mybinder.org/v1/gh/repo/name/HEAD&lt;/code&gt;. We don’t record where those come from (that would be Referer).&lt;/p&gt;
&lt;p&gt;Where this &lt;em&gt;changes&lt;/em&gt; is cross-origin requests (case 2), that is, pages which &lt;em&gt;embed&lt;/em&gt; kernels from mybinder.org, such as documentation websites that use mybinder.org to embed kernels from mybinder.org via tools like Thebe to make executable documentation (which is rad!). These requests will now include the Origin of the request, which would be the hostname (e.g. &lt;code&gt;https://course.spacy.io&lt;/code&gt; ), not the full page.&lt;/p&gt;
&lt;p&gt;Script launches (case 3) typically lack this information, so will usually have &lt;code&gt;null&lt;/code&gt; data in the new field. But of course, scripts can do whatever they want, so this isn’t guaranteed to be accurate for malicious or deliberately spoofing scripts.&lt;/p&gt;
&lt;p&gt;If you want to have a private, not-recorded use of Binder, you must run your own BinderHub instance. If you want to suggest that we &lt;em&gt;not&lt;/em&gt; do this, or do it differently, please let us know in the &lt;a href="https://github.com/jupyterhub/binderhub/pull/2053"&gt;proposal discussion&lt;/a&gt;. You can also check the &lt;a href="https://mybinder.readthedocs.io/en/latest/about/user-guidelines.html#how-we-ensure-user-privacy"&gt;privacy policy&lt;/a&gt; for more information. We plan to apply the change at the end of February, 2026.&lt;/p&gt;
</content><category term="Binder"/></entry><entry><title>Simplifying and speeding up Binder builds with BuildKit</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2025/simplifying-and-speeding-up-binder-builds-with-buildkit/" rel="alternate"/><published>2025-03-03T14:05:00+00:00</published><updated>2025-03-03T14:05:00+00:00</updated><author><name>Chris Holdgraf</name></author><id>tag:jasongrout.github.io,2025-03-03:/medium-archive/pelican/posts/2025/simplifying-and-speeding-up-binder-builds-with-buildkit/</id><summary type="html">&lt;p&gt;The Binder Project allows users to build reproducible, sharable environments for interactive computing. To accomplish this, Binder uses a…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;The &lt;a href="http://mybinder.org"&gt;Binder Project&lt;/a&gt; allows users to build reproducible, sharable environments for interactive computing. To accomplish this, Binder uses a tool called &lt;a href="https://repo2docker.readthedocs.io/"&gt;repo2docker&lt;/a&gt; to generate an executable Docker image using the &lt;a href="https://repo2docker.readthedocs.io/en/latest/specification.html"&gt;Reproducible Execution Environment Specification&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2025/simplifying-and-speeding-up-binder-builds-with-buildkit/images/001-1_NOEeFGGHdpGZMHSq5ykl9A.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;The first time a repository is launched on Binder, repo2docker must build the reproducible environment for it. This process can take a long time because of all the dependencies that need to be installed and turned into the image. As a result, Binder launches can feel slow and clunky, which is a poor UX for workflows that are designed around quick interactive sessions.&lt;/p&gt;
&lt;p&gt;repo2docker was built several years ago, and followed patterns that were commonplace at the time. However, in the past few years the Docker community has made significant advances in optimizing the image building process. One-such improvement is the creation of &lt;a href="https://docs.docker.com/build/buildkit/"&gt;BuildKit&lt;/a&gt;, a replacement for Docker’s historical build system that is much more sophisticated. However, repo2docker hasn’t leveraged these improvements because it was still using the original Docker Build system.&lt;/p&gt;
&lt;p&gt;So, we’ve decided to spend a few cycles modernizing repo2docker’s image building logic by using the more modern &lt;a href="https://docs.docker.com/build/buildkit/"&gt;BuildKit API&lt;/a&gt; (via ‘docker buildx build’). This allows for optimizations like build parallelization, better build caching, and supporting some &lt;code&gt;Dockerfile&lt;/code&gt; features that Binder didn’t support earlier (particularly, &lt;code&gt;COPY --chown&lt;/code&gt;). It also lays a foundation for significantly simplifying the repo2docker build infrastructure and leveraging more of BuildKit’s parallelization functionality. For example, we’d like to &lt;a href="https://docs.docker.com/build/builders/drivers/kubernetes/"&gt;leverage BuildKit’s Kubernetes driver&lt;/a&gt; which distributes builds much more efficiently and in parallel.&lt;/p&gt;
&lt;p&gt;Authors of Binder repositories won’t need to take any action¹, and they’ll simply notice that mybinder.org (and any other community-run BinderHub instance) will be a bit snappier at building images.&lt;/p&gt;
&lt;p&gt;If you’d like to learn more about the changes that enabled this, &lt;a href="https://github.com/jupyterhub/mybinder.org-deploy/pull/3225"&gt;check out this mybinder.org pull request&lt;/a&gt; which has links to the repo2docker pull requests that added this functionality. We’re excited keep improving Binder, and are hopeful that this makes the experience of using mybinder.org and community Binders a little bit better.&lt;/p&gt;
&lt;h2 id="authors-and-acknowledgements"&gt;Authors and acknowledgements&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://github.com/yuvipanda"&gt;Yuvi Panda&lt;/a&gt; is a co-founder and the Technical Lead at &lt;a href="http://2i2c.org"&gt;2i2c&lt;/a&gt;. He is passionate about building participatory open infrastructure for scientific &amp;amp; educational use cases. He is a Project Jupyter team member primarily focused on infrastructure related projects (JupyterHub, Binder, etc). He also wrote most of the code for this &lt;code&gt;docker buildx&lt;/code&gt; transition, and shepherded it through to deployment on mybinder.org as well. He is ex-Wikimedia and ex-GNOME. Let’s eliminate accidental complexities wherever we find them.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://chrisholdgraf.com"&gt;Chris Holdgraf&lt;/a&gt; is a co-founder and the Executive Director of &lt;a href="http://2i2c.org"&gt;2i2c&lt;/a&gt;. He is on the Executive Council of Project Jupyter, and co-leads the &lt;a href="https://jupyterhub-team-compass.readthedocs.io/en/latest/team.html#jupyterhub-team"&gt;JupyterHub and Binder team&lt;/a&gt; as well as the &lt;a href="https://compass.jupyterbook.org"&gt;Jupyter Book team&lt;/a&gt;). He was previously a post-doctoral researcher in the Department of Statistics at &lt;a href="https://www.berkeley.edu/"&gt;UC Berkeley&lt;/a&gt;, and a Community Architect with the &lt;a href="https://data.berkeley.edu/"&gt;Division of Data Science&lt;/a&gt; at Berkeley. He’s interested in using open infrastructure to support interactive computing workflows in research and education.&lt;/p&gt;
&lt;p&gt;Many thanks to &lt;a href="https://github.com/minrk"&gt;@minrk&lt;/a&gt;, &lt;a href="https://github.com/manics"&gt;@manics&lt;/a&gt;, and &lt;a href="https://github.com/consideRatio"&gt;@consideRatio&lt;/a&gt; for their help reviewing and shaping this work.&lt;/p&gt;
&lt;h2 id="footnotes"&gt;Footnotes&lt;/h2&gt;
&lt;p&gt;¹ Unless they were relying on undocumented implementation details of the old builder — in particular, the presence of a &lt;code&gt;/.dockerenv&lt;/code&gt; file to detect if you are running in repo2docker &lt;a href="https://github.com/scikit-learn/scikit-learn/pull/30835"&gt;scikit-learn/scikit-learn#30835&lt;/a&gt; has an example.&lt;/p&gt;
</content><category term="Binder"/><category term="cloud computing"/><category term="JupyterHub"/><category term="reproducibility"/></entry><entry><title>Curvenote joins the mybinder.org federation</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2024/curvenote-joins-the-mybinder-org-federation/" rel="alternate"/><published>2024-02-22T16:19:00+00:00</published><updated>2024-02-22T16:19:00+00:00</updated><author><name>Steve Purves</name></author><id>tag:jasongrout.github.io,2024-02-22:/medium-archive/pelican/posts/2024/curvenote-joins-the-mybinder-org-federation/</id><summary type="html">&lt;p&gt;Curvenote is now a part of the mybinder.org federation. By hosting a BinderHub instance running on the company’s infrastructure, additional…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Curvenote is now a part of the mybinder.org federation. By hosting a BinderHub instance running on the company’s infrastructure, additional capacity is available on the &lt;a href="https://mybinder.org"&gt;https://mybinder.org&lt;/a&gt; service.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="curvenote.com/for/journals" src="https://jasongrout.github.io/medium-archive/pelican/posts/2024/curvenote-joins-the-mybinder-org-federation/images/001-0_4FQGtOrs8XWEQ75G.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;&lt;a href="https://curvenote.com/for/journals"&gt;curvenote.com/for/journals&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The mybinder.org project provides a critical, free public service for scientists, researchers and educators worldwide. The ability to spin up a Jupyter server to run someone’s research code or run a class without local configuration is something that many academics and educators rely on.&lt;/p&gt;
&lt;p&gt;Mybinder.org runs on a set of open source software components and standards, that not only powers the service but that also allows us to make solid steps forward in reproducibility in scientific research, namely &lt;a href="https://repo2docker.readthedocs.io/en/latest/specification.html"&gt;REES&lt;/a&gt; and open source software components (like &lt;a href="https://github.com/jupyterhub/repo2docker"&gt;repo2docker&lt;/a&gt;) .&lt;/p&gt;
&lt;p&gt;This is something we’re keen to shout about as Curvenote runs numerous small scale, independent, BinderHubs to power its journal infrastructure for &lt;a href="https://curvenote.com/for/journals"&gt;notebook based publishing for reproducible scientific journals&lt;/a&gt; with BinderHub, Jupyter and MyST Markdown (&lt;a href="https://mystmd.org"&gt;https://mystmd.org&lt;/a&gt;) being important components of that.&lt;/p&gt;
&lt;p&gt;Over the last few months a lot of work has gone into bringing up the Curvenote BinderHub instance on AWS. This is mainly because in the process, the AWS workflow based deployment has been pushed forward by &lt;a href="https://www.linkedin.com/in/1simon/"&gt;Simon Li&lt;/a&gt; (&lt;a href="https://github.com/manics"&gt;@manics&lt;/a&gt;, University of Dundee, &lt;a href="https://jupyterhub-team-compass.readthedocs.io/en/latest/team/index.html#jupyterhub-team"&gt;JupyterHub Core Team&lt;/a&gt;), solving many previous roadblocks around EKS (Elastic Kubernetes Service) usage and paving the way for easier future AWS based deployments (watch out for a future post from Simon with all the technical details).&lt;/p&gt;
&lt;p&gt;It’s been great to collaborate with Simon during that time and get exposure to the details of BinderHub deployment on AWS.&lt;/p&gt;
&lt;p&gt;The mybinder.org service makes a significant positive impact on public education, science and research. This impact is directly supported by the volunteer time of the BinderHub core team and the federation member organizations. Curvenote’s instance adds capacity to the service and a broader group of organizations contributing to the organization would lead to a more resilient public service, that is less prone to disruption when a single federation member leaves. If your organization has the resources to run and maintain a BinderHub, or makes heavy use of the mybinder.org service, encourage your organizations to run an instance and &lt;a href="https://mybinder.readthedocs.io/en/latest/about/federation.html"&gt;join the federation&lt;/a&gt;.&lt;/p&gt;
</content><category term="Binder"/><category term="open science"/></entry><entry><title>Mybinder.org reducing capacity</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2023/mybinder-org-reducing-capacity/" rel="alternate"/><published>2023-04-25T07:28:00+00:00</published><updated>2023-04-27T20:16:00+00:00</updated><author><name>Min RK</name></author><id>tag:jasongrout.github.io,2023-04-25:/medium-archive/pelican/posts/2023/mybinder-org-reducing-capacity/</id><summary type="html">&lt;p&gt;Funding is running out for the largest member of mybinder.org, which will be shutdown this week, reducing overall capacity&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Funding is running out for the largest member of mybinder.org, which has been sponsored by the Google Open Source Program Office. gke.mybinder.org will shut down and there will be a reduction in capacity at the end of April, 2023 (end of this week).&lt;/p&gt;
&lt;p&gt;Key points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Our funds on &lt;code&gt;gke.mybinder.org&lt;/code&gt;, the biggest part of the federation, will run out in April. Google has decided not to provide more credits.&lt;/li&gt;
&lt;li&gt;Traffic previously sent to GKE will mostly be delivered to OVHcloud, which has less capacity. We are also working to deploy new federation members to spread the load.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Service reductions to expect:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This may come with an increase in errors and failures, as GKE has been the largest and most stable federation member&lt;/li&gt;
&lt;li&gt;We are currently looking at reducing the total capacity of Binder by 60%, so you may get rate limit or capacity errors&lt;/li&gt;
&lt;li&gt;We will start more aggressively deleting older cached builds, as storage costs have increased.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We are still working out the details of the shutdown and deploying new federation members, but mybinder.org users should expect disruption to the mybinder.org service and to see an increase in messages that the service is at capacity in the short term.&lt;/p&gt;
&lt;p&gt;The plan:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Thursday: gke.mybinder.org will be removed from the federation (user sessions not disrupted, but no new sessions will start there)&lt;/li&gt;
&lt;li&gt;Friday: gke.mybinder.org will be shutdown, and mybinder.org migrated to a smaller cluster&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can help us keep mybinder.org running by &lt;a href="https://numfocus.salsalabs.org/donate-to-binder"&gt;donating to Binder&lt;/a&gt; or encouraging your organization to &lt;a href="https://mybinder.readthedocs.io/en/latest/about/federation.html"&gt;join the BinderHub Federation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are grateful to the Google Open Source Program for their funding thus far, and appreciate the continued support of continuing federation members, OVHCloud and GESIS, which enable us to keep mybinder.org going without shutting down completely when one funding source goes away.&lt;/p&gt;
</content><category term="Binder"/></entry><entry><title>Updating defaults on mybinder.org</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2023/updating-defaults-on-mybinder-org/" rel="alternate"/><published>2023-03-09T08:31:00+00:00</published><updated>2023-03-10T15:53:00+00:00</updated><author><name>Min RK</name></author><id>tag:jasongrout.github.io,2023-03-09:/medium-archive/pelican/posts/2023/updating-defaults-on-mybinder-org/</id><summary type="html">&lt;p&gt;This week, we are deploying some updates to repo2docker, the image-building tool that underpins mybinder.org. This may affect your repos…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2023/updating-defaults-on-mybinder-org/images/001-1_0dd02RZZwHXDo-Fr3tdB5w.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;This week, we are deploying some updates to &lt;a href="http://repo2docker.readthedocs.io"&gt;repo2docker&lt;/a&gt;, the image-building tool that underpins &lt;a href="https://mybinder.org/"&gt;mybinder.org&lt;/a&gt;. This may affect your repos. Please &lt;a href="https://discourse.jupyter.org/c/binder/12"&gt;get in touch&lt;/a&gt; if you have problems! Hopefully this will make things better, more stable, and &lt;em&gt;less&lt;/em&gt; surprising overall, but change always breaks &lt;em&gt;something&lt;/em&gt;, however hard we work to keep things working.&lt;/p&gt;
&lt;p&gt;To highlight the changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.10 is now the default Python version&lt;/li&gt;
&lt;li&gt;Python 3.11 is now supported, and new versions of Python should be supported more quickly&lt;/li&gt;
&lt;li&gt;If a repo requests an old version of Python (≤ 3.6), it will be installed in a separate environment, as we’ve been doing with Python 2.7 for a long time.&lt;/li&gt;
&lt;li&gt;The server implementation is switched from &lt;code&gt;jupyter-notebook&lt;/code&gt; to &lt;code&gt;jupyter-server&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More detail on each change, the reasons behind them, and their consequences below.&lt;/p&gt;
&lt;h2 id="python-311-and-separate-envs-for-legacy-python-support"&gt;Python 3.11 and separate envs for legacy Python support&lt;/h2&gt;
&lt;p&gt;When building an image, repo2docker installs packages in one or two environments — the &lt;strong&gt;kernel&lt;/strong&gt; environment where your code runs, and the &lt;strong&gt;server&lt;/strong&gt; environment, which runs the Jupyter server. If you’re using a reasonably supported version of Python, these are actually the same environment. This is the vast majority of repositories on mybinder.org. In order to function properly, we have certain requirements of what goes in the ‘server’ environment. Eventually, those requirements start making it difficult to setup the server environment with an outdated version of Python, as packages march ahead with their minimum required Python (The widely adopted &lt;a href="https://numpy.org/neps/nep-0029-deprecation_policy.html#support-table"&gt;NEP 29&lt;/a&gt; suggested dropping Python 3.7 support in December, 2021). Our solution for this has been to separate the kernel environment from the server environment, so they don’t create a conflict. Until recently, only Python 2 was handled this way (most packages dropped Python 2 support years ago). As part of adding support for Python 3.11, we have expanded this behavior to include Python ≤3.6, so if you are using a ‘legacy Python’, currently defined to be Python ≤3.6, your requested packages will be installed in the kernel environment instead of the server environment. This &lt;em&gt;should&lt;/em&gt; only have a noticeable effect if you are installing something with server extension components , which includes anything modifying the JupyterLab or notebook interfaces— those will not be available in the server environment. To address this, you will have to upgrade Python &lt;em&gt;or&lt;/em&gt; handle the server extension installation in &lt;code&gt;postBuild&lt;/code&gt; . &lt;a href="https://github.com/jupyterhub/repo2docker/pull/1239"&gt;PR adding Python 3.11 and adding Python ≤3.6 to legacy Python versions&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="default-python-is-now-310"&gt;Default Python is now 3.10&lt;/h2&gt;
&lt;p&gt;The default Python for repo2docker and thereby mybinder.org is now Python 3.10, upgraded from 3.7. 3.10 will be used when a repository does not specify which version of Python to use. Following Python’s own annual release cadence, we plan to update this more regularly in the future, lagging behind Python itself by a version or two. This has no effect on your repos if they specify a Python version, which is why we &lt;a href="https://repo2docker.readthedocs.io/en/latest/howto/languages.html#specifying-a-version-of-python"&gt;&lt;strong&gt;encourage you to specify your Python version&lt;/strong&gt;&lt;/a&gt;! If you don’t, then your Python version &lt;em&gt;will&lt;/em&gt; change over time, probably about once a year. &lt;a href="https://github.com/jupyterhub/repo2docker/pull/1219"&gt;PR switching the default Python&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="now-launching-jupyter-server"&gt;Now launching Jupyter Server&lt;/h2&gt;
&lt;p&gt;The default UI for mybinder.org has been JupyterLab for some time, with the classic notebook still available if you specify a url of &lt;code&gt;/tree/&lt;/code&gt;or &lt;code&gt;/notebooks/mynb.ipynb&lt;/code&gt;. When we rolled out that change, we kept the default &lt;em&gt;server&lt;/em&gt; as the &lt;code&gt;jupyter-notebook&lt;/code&gt; server, for improved compatibility with existing server extensions. As the newer Jupyter Server has taken over, the situation is becoming reversed — using the older &lt;code&gt;notebook&lt;/code&gt; server is now the &lt;em&gt;cause&lt;/em&gt; of compatibility issues with server extensions, so we are switching the server to launch &lt;code&gt;jupyter-server&lt;/code&gt; instead of &lt;code&gt;jupyter-notebook&lt;/code&gt;. The classic UI is still available at the same URLs, thanks to &lt;a href="https://nbclassic.readthedocs.io"&gt;nbclassic&lt;/a&gt;. This &lt;em&gt;should&lt;/em&gt; have no visible effects, as &lt;code&gt;jupyter-server&lt;/code&gt; and &lt;code&gt;nbclassic&lt;/code&gt; make a great deal of effort to keep classic notebook extensions working, but some extensions may need an update for jupyter-server compatibility if they haven’t been updated already. Because of where the server is specified, there is no supported way for images to express a preference for the deprecated &lt;code&gt;notebook&lt;/code&gt; server (&lt;a href="https://github.com/jupyterhub/binderhub/pull/1635"&gt;PR switching the default server command&lt;/a&gt;.&lt;/p&gt;
</content><category term="Binder"/><category term="Docker"/><category term="JupyterHub"/><category term="reproducibility"/></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>A 2019 retrospective from the Binder Project</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-2019-retrospective-from-the-binder-project/" rel="alternate"/><published>2020-01-15T17:48:00+00:00</published><updated>2020-01-15T18:10:00+00:00</updated><author><name>Chris Holdgraf</name></author><id>tag:jasongrout.github.io,2020-01-15:/medium-archive/pelican/posts/2020/a-2019-retrospective-from-the-binder-project/</id><summary type="html">&lt;p&gt;2019 was a busy year for the Binder and JupyterHub projects — each saw growth in both their community and technology. Now that the year…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;2019 was a busy year for the Binder and JupyterHub projects — each saw growth in both their community and technology. Now that the year has wrapped up, it is a good time to reflect on some of the highlights from the year.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-2019-retrospective-from-the-binder-project/images/001-1_ZeTyAGGLPlXs0UlQfKsr6g.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Overall, 2019 was about improving the robustness, stability, and team dynamics around the JupyterHub and Binder projects, as well as connecting these projects with other tools and services in the open source community. Here are a few things that we are most-excited about.&lt;/p&gt;
&lt;h2 id="more-people-are-using-mybinderorg"&gt;More people are using mybinder.org&lt;/h2&gt;
&lt;p&gt;The Binder Federation is a collection of BinderHubs accessible from mybinder.org. This deployment is run as a public service and a demonstration of BinderHub, the underlying technology of the Binder project. This deployment is run on a volunteer basis by Binder community members, and is supported through grants and donations in infrastructure from project stakeholders. In 2019, the user base of mybinder.org grew from around 70,000 users per week to around 100,000 users (a growth of nearly 40%). mybinder.org is being used for teaching classes, sharing reproducible analyses, creating interactive documentation and narratives, and much more. We’re astonished at the rapid growth of Binder-ready repositories, and we’re excited to see what the community creates next.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Weekly user sessions at mybinder.org. Here you can see a typical pattern of activity over the course of a year. There are dips in activity over the summer and winter months, reflecting reduced activity from academic institutions." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-2019-retrospective-from-the-binder-project/images/002-0_0_V6rIgF_oAW5VS-.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Weekly user sessions at mybinder.org. Here you can see a typical pattern of activity over the course of a year. There are dips in activity over the summer and winter months, reflecting reduced activity from academic institutions.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="jupyterhub-reaches-10"&gt;JupyterHub reaches 1.0&lt;/h2&gt;
&lt;p&gt;JupyterHub, the underlying technology that provides interactive computing sessions to multiple users, &lt;a href="/posts/2019/announcing-jupyterhub-1-0/"&gt;is now at 1.0 status&lt;/a&gt;. The JupyterHub Python application was written several years ago, and reaching 1.0 reflects the work of dozens of open source contributors over time. JupyterHub is now a robust and stable application, having been used at smaller scales (think 5–10 people running on a single VM) as well as much larger scales (think 5,000 students running Jupyter sessions for a class).&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The JupyterHub logo" src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-2019-retrospective-from-the-binder-project/images/003-1_m2PN2PR-a6X_J3M602tgog.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterHub logo&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="binderhub-is-out-of-beta"&gt;BinderHub is out of beta&lt;/h2&gt;
&lt;p&gt;BinderHub, the kubernetes-based technology that powers mybinder.org, also came out of Beta this year. This reflects the fact that BinderHub is a battle-hardened application that can provide a stable service over time. mybinder.org runs nearly 100,000 sessions a week, and requires minimal maintenance time from the Binder’s projects team of volunteer operators.&lt;/p&gt;
&lt;h2 id="the-binderhub-federation-is-launched"&gt;The BinderHub federation is launched&lt;/h2&gt;
&lt;p&gt;The Binder Project envisions a world in which technology can be used in vendor-agnostic and decentralized ways. BinderHub runs on Kubernetes, which can be deployed on a variety of cloud and local infrastructure. While the Binder team runs one BinderHub deployment at mybinder.org, our goal has always been to see &lt;em&gt;other&lt;/em&gt; organizations running their own BinderHubs. This year, we went one step beyond this by &lt;a href="/posts/2019/the-international-binder-federation/"&gt;launching the &lt;strong&gt;BinderHub Federation&lt;/strong&gt;&lt;/a&gt;. This is a collection of research and technology organizations that combine their expertise and computational resources to power mybinder.org. When users visit mybinder.org, they are now directed to one of several BinderHub instances. This makes mybinder.org more robust, and grows the number of organizations that utilize the project’s technology for their communities. A BIG THANKS goes out to Google, OVH, GESIS, and the Turing Institute for supporting the Binder Federation.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The (rough) location of each BinderHub deployment in the mybinder.org federation" src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-2019-retrospective-from-the-binder-project/images/004-1_KU35naJhl1LSDxKY8gog4g.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The (rough) location of each BinderHub deployment in the mybinder.org federation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="binder-connects-with-open-science-services"&gt;Binder connects with open science services&lt;/h2&gt;
&lt;p&gt;Another goal of Binder is to be a &lt;em&gt;part&lt;/em&gt; of the solution to more transparent, sharable, reproducible computational work. This means &lt;a href="/posts/2019/binder-with-zenodo/"&gt;plugging in to other ecosystems and projects&lt;/a&gt; in order to leverage the broader open science community. This year we saw a number of new connections with other services. BinderHub now supports links that point directly to Zenodo and Dataverse repositores, and we are working on a few other integrations in the coming months. This means that projects utilizing these resources will be able to share reproducible and interactive links to their work out-of-the-box.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Binder now works with Zenodo repositories!" src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-2019-retrospective-from-the-binder-project/images/005-1_WVSV4_bwWlGWnT0k8xrlWg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Binder now works with Zenodo repositories!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="the-binder-community-grows"&gt;The Binder community grows&lt;/h2&gt;
&lt;p&gt;The Binder project’s most important asset is its people — this is a collection of volunteers spread across the world and from a variety of organizations. Binder community members do a variety of things — from working on technology, to teaching others how to make their work more reproducible, to participating in community discussions, to maintaining and debugging Binder tech. There is also a “core team” of Binder members that dedicates a significant part of their time to supporting the project. In 2019, we saw several new members join the core team, as well as a general growth in the Binder community. Welcome to all of our new team members! You can find a &lt;a href="https://jupyterhub-team-compass.readthedocs.io/en/latest/team.html"&gt;list of our current team members here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="we-welcome-our-first-contributor-in-residence"&gt;We welcome our first Contributor in Residence&lt;/h2&gt;
&lt;p&gt;One challenge with running large, open projects is that resources tend to be scarce. The Binder Project has no formal project funding, and must find ways to both grow its technology as well as run mybinder.org on resources that are donated from its community. One thing that often suffers as a result is the maintenance and general improvement of our open source technology. This work is often under-appreciated, difficult, and unlikely to happen with purely volunteer labor.&lt;/p&gt;
&lt;p&gt;For this reason, the Binder project decided to &lt;a href="/posts/2019/the-jupyterhub-and-binder-contributor-in-residence/"&gt;apply for the CZI Essential Open Source grant series&lt;/a&gt;. We proposed the creation of the “Binder Contributor in Residence” position — an annual contractor position that pays a member of the Binder community to do many of the daily things that are crucial for the project’s growth. We are excited to have &lt;a href="https://github.com/GeorgianaElena"&gt;Georgiana Dolocan&lt;/a&gt; as our first contributor in residence, and look forward to where this project will go in 2020.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Many thanks to CZI for their support of the Binder and JupyterHub projects in 2020!" src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/a-2019-retrospective-from-the-binder-project/images/006-0_pzbKC79Svh5Xrtev.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Many thanks to CZI for their support of the Binder and JupyterHub projects in 2020!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="there-are-more-binderhub-deployments"&gt;There are more BinderHub deployments&lt;/h2&gt;
&lt;p&gt;The Binder Project aims to create technology that is deployable anywhere so that other organizations can support their communities with Binder infrastructure. In 2019 we ran a number of training sessions for how other groups can run their own BinderHub. In particular, the Turing Institute ran several workshops that had attendees up-and-running with their own functioning BinderHubs.&lt;/p&gt;
&lt;h2 id="thanks-to-our-community"&gt;Thanks to our community&lt;/h2&gt;
&lt;p&gt;As you can see, 2019 was a busy and exciting year for the Binder community. As a final note, we want to say thanks to all of you who have supported Binder in one form or another over the years. Binder is a project run by the community, for the community. It wouldn’t be possible without all of your hard work and friendly faces, thanks! We look forward to what’s coming next in 2020!&lt;/p&gt;
</content><category term="Binder"/><category term="Kubernetes"/><category term="reproducibility"/></entry><entry><title>The JupyterHub and Binder Contributor in Residence!</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/the-jupyterhub-and-binder-contributor-in-residence/" rel="alternate"/><published>2019-11-26T19:52:00+00:00</published><updated>2019-11-26T19:52:00+00:00</updated><author><name>Tim Head</name></author><id>tag:jasongrout.github.io,2019-11-26:/medium-archive/pelican/posts/2019/the-jupyterhub-and-binder-contributor-in-residence/</id><summary type="html">&lt;p&gt;Thanks to funding from the CZI Essential Open Source Software for Science initiative we are welcoming Georgiana Elena as our first…&lt;/p&gt;
</summary><content type="html">&lt;figure&gt;
&lt;img alt="The Chan Zuckerberg Initiative and Project Jupyter are teaming up to pilot a new role in the Jupyter community: the JupyterHub Contributor in Residence" src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/the-jupyterhub-and-binder-contributor-in-residence/images/001-1_guy_H5cSnar8-qnscfVuzw_2x.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The Chan Zuckerberg Initiative and Project Jupyter are teaming up to pilot a new role in the Jupyter community: the JupyterHub Contributor in Residence&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Thanks to funding from the &lt;a href="https://medium.com/@cziscience/essential-open-source-software-for-science-72faec2c38c1"&gt;CZI Essential Open Source Software for Science&lt;/a&gt; initiative we are welcoming &lt;a href="https://github.com/GeorgianaElena"&gt;Georgiana Elena&lt;/a&gt; as our first Contributor in Residence!&lt;/p&gt;
&lt;p&gt;Managing a codebase that spans many repositories and sub-projects as well as operating &lt;a href="https://mybinder.org"&gt;mybinder.org&lt;/a&gt; is a significant effort. Over time we have identified a need for dedicated support to ensure that activity and communication within these repositories is efficient and productive. Driven by this need and inspired by the &lt;a href="https://www.djangoproject.com/fundraising/"&gt;Django Fellowship model&lt;/a&gt;, we shaped the idea of a JupyterHub/Binder Contributor in Residence (CIR).&lt;/p&gt;
&lt;p&gt;Thanks to the Chan Zuckerberg Initiative, a Contributor in Residence within the community is now possible. Starting this year, CZI launched the &lt;a href="https://chanzuckerberg.com/rfa/essential-open-source-software-for-science/"&gt;Essential Open Source Software for Science&lt;/a&gt; grant program. It is aimed at helping open source communities that make up the core foundation of the scientific stack. We applaud CZI in providing support for core infrastructure across the sciences, and we’re honored to be part of CZI’s vision of funding maintenance, growth, development, and community engagement for open-source projects.&lt;/p&gt;
&lt;p&gt;In this post we’ll introduce the community to our first Contributor in Residence (Georgiana) and her mentor (Tim)! The rest of this post is in the form of a conversation between Georgiana and Tim. We hope you enjoy it and that it let’s you get to know the team a bit better.&lt;/p&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Tim:&lt;/em&gt; Hello Georgiana. Congrats on becoming the inaugural CIR. We’ve been lucky to have you already as a contributor on JupyterHub especially &lt;a href="/posts/2019/introducing-traefikproxy-a-new-jupyterhub-proxy-based/"&gt;your work adding support for using Traefik as a proxy&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo&lt;/em&gt;: Hey Tim! Thank you, it’s been a really amazing experience to work on JupyterHub. I’m really excited for this next year’s journey.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tim:&lt;/em&gt; You are the very first Contributor in Residence. Can you explain a little what this means?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo:&lt;/em&gt; The CIR role is about helping make the little things around the projects be amazing. Little things like answering newly opened issues, guide people towards the right place for discussion, improve bits of documentation or code, helping with releases, give people the right tools to make great contributions. And I have a great team of existing contributors to work with.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tim:&lt;/em&gt; That’s right! My role in all this is to be a mentor and guide. JupyterHub and Binder have a small team that does a good job looking after the main repositories, but the universe of JupyterHub and Binder repositories is huge. So sometimes things get overlooked or missed. For example Pull Requests or Issues in one of the less-popular repositories can go for a long time without getting attention. This may hold up progress somewhere else, and people have a bad experience contributing to the project.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo:&lt;/em&gt; Hopefully we can improve on this a bit so that more people have a great experience when contributing.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Tim&lt;/em&gt;: Let’s find out a bit more about you. What did you do before getting involved with JupyterHub?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo&lt;/em&gt;: I studied computer science in Bucharest spending the last semester developing my bachelor’s project as an Erasmus exchange student in Madrid. During summers I worked in the industry, doing a few internships abroad. I tried to gain as much practical experience as possible, to get in touch with different people and cultures, and interning seemed like the right move.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tim&lt;/em&gt;: How did you get involved with JupyterHub?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo&lt;/em&gt;: I got involved with JupyterHub thanks to the amazing &lt;a href="https://www.outreachy.org/"&gt;Outreachy community&lt;/a&gt;. The Outreachy program introduced me to the world of opensource and guided me through my first steps. I now feel very lucky to have applied for the Outreachy internship &lt;a href="/posts/2018/outreachy-jupyter-supporting-diversity-in-open/"&gt;at the same time that JupyterHub came up with two amazing projects&lt;/a&gt;. I chose JupyterHub because I “clicked” with the TraefikProxy project and I was happy to find a very welcoming community that made contributing a very pleasant and not at all a scary experience.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tim&lt;/em&gt;: Have you turned into someone who spends all their time contributing or do you still have other hobbies?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Georgiana&lt;/em&gt;: Because I currently live in the busiest/loudest city of Romania, I love to escape it at the end of the week and spend some time in nature. My favorite place to be is the village I grew up in, where I recharge my batteries walking my dogs and cooking with my mother and sister. I like painting and photography and sometimes I do both using the photos I take as an inspiration for my paintings.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Tim&lt;/em&gt;: Moving on to the things you will be doing as CIR, have you already picked out something to get started with?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo&lt;/em&gt;: At first, I will be focusing on trying to get an overview of what issues are feature requests, support questions and which have been solved already. I will also spend some time getting familiar with more of the JH/Binder projects. And what better way to learn about a project than to try and use it, and to be a first time contributor.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tim&lt;/em&gt;: If you had to name the top three goals you hope to achieve while being contributor in residence, what would those be?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo&lt;/em&gt;: From the perspective of someone with still a lot to learn and figure out, I would be extremely happy if during this year I will grow to be the CIR this community needs. I would love to help improve the contributing experience, increase the overall productivity of the projects and become a better contributor myself.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Tim&lt;/em&gt;: How can people interact with you?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo&lt;/em&gt;: People can use the usual community communication channels, GitHub, Gitter and Discourse to provide feedback or ask questions and I’ll do my best to help out.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tim&lt;/em&gt;: Now that we have a CIR, do people still need to contribute to the projects?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo&lt;/em&gt;: Definitely! People are always welcome to contribute. The CIR role wasn’t created to replace anything, but to be an extra pair of hands helping the daily activities around the community become more efficient.&lt;/li&gt;
&lt;li&gt;Tim: How can people stay engaged with the CIR program or the broader JupyterHub community moving forward?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Geo:&lt;/em&gt; As the CIR, I am a team member just like anyone else, and the best way to stay connected is to connect is through our team channels — we have team discussions in the &lt;a href="https://discourse.jupyter.org/"&gt;Jupyter Community Forum&lt;/a&gt;, and team information in the &lt;a href="https://jupyterhub-team-compass.readthedocs.io/en/latest/"&gt;JupyterHub Team Compass repository&lt;/a&gt; (including &lt;a href="https://jupyterhub-team-compass.readthedocs.io/en/latest/meetings.html"&gt;monthly team meetings&lt;/a&gt; that anyone is welcome to join).&lt;/li&gt;
&lt;/ul&gt;
</content><category term="Binder"/><category term="community"/><category term="diversity"/><category term="JupyterHub"/><category term="sustainability"/></entry><entry><title>How we automated mybinder.org dependency upgrades in 10 steps</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/automating-mybinder-org-dependency-upgrades-in-10-steps/" rel="alternate"/><published>2019-07-17T15:34:00+00:00</published><updated>2019-07-17T15:34:00+00:00</updated><author><name>Chris Hench</name></author><id>tag:jasongrout.github.io,2019-07-17:/medium-archive/pelican/posts/2019/automating-mybinder-org-dependency-upgrades-in-10-steps/</id><summary type="html">&lt;p&gt;BinderHub and repo2docker are key components of the service mybinder.org; depending on them for the latest functionality demands that…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;a href="https://github.com/jupyterhub/binderhub"&gt;BinderHub&lt;/a&gt; and &lt;a href="https://github.com/jupyter/repo2docker"&gt;repo2docker&lt;/a&gt; are key components of the service at &lt;a href="https://mybinder.org/"&gt;mybinder.org&lt;/a&gt;. In order to give Binder users the best experience, the Binder SRE team must continuously upgrade the version of these tools that mybinder.org uses. To avoid merging in massive updates at irregular intervals, it is desirable to merge updates in frequent intervals of smaller changes in order to more easily identify any breaking changes from the dependency upgrades.&lt;/p&gt;
&lt;p&gt;While this process only takes a few minutes following processes outlined in the “&lt;a href="https://mybinder-sre.readthedocs.io/en/latest/"&gt;Site Reliability Guide&lt;/a&gt;,” it is prone to human error (e.g., remembering to use the right SHA in upgrading the packages), and the team must remember to regularly do it in the first place. In the interest of automation, the Binder team decided to use a bot to relieve this burden, and we’ve decided to highlight its functionality in this blog post!&lt;/p&gt;
&lt;h2 id="what-does-the-mybinderorg-upgrade-bot-do"&gt;What does the mybinder.org upgrade bot do?&lt;/h2&gt;
&lt;p&gt;The upgrade bot should automatically update the versions of BinderHub and repo2docker that are deployed on mybinder.org. These are defined &lt;a href="https://github.com/jupyterhub/mybinder.org-deploy/blob/master/mybinder/values.yaml#L64"&gt;in the mybinder.org helm chart&lt;/a&gt;. To check whether an upgrade is needed, we want the bot to first “diff” the latest commit hash for both repo2docker and BinderHub repos against the deployed versions in the &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; repo. If either or both are different, the upgrade bot does the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fork the &lt;a href="https://github.com/jupyterhub/mybinder.org-deploy"&gt;mybinder.org-deploy&lt;/a&gt; repo&lt;/li&gt;
&lt;li&gt;Clone the fork locally&lt;/li&gt;
&lt;li&gt;Checkout a new branch for the bump&lt;/li&gt;
&lt;li&gt;Make the appropriate edit to update the commit hash in the &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; fork repo&lt;/li&gt;
&lt;li&gt;Add and commit the change&lt;/li&gt;
&lt;li&gt;Push to the branch in the forked repo&lt;/li&gt;
&lt;li&gt;Create a PR to the main &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; repo&lt;/li&gt;
&lt;li&gt;Remove the locally cloned repo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, it would be ideal if the bot could update an existing PR instead of creating new ones for the version bumps. We’d also like to provide some information in the comments of the PR as to what high level changes were made so we have some idea about what we’re merging in.&lt;/p&gt;
&lt;p&gt;Here’s what we’re aiming for. The PR body:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/automating-mybinder-org-dependency-upgrades-in-10-steps/images/001-0_Q2M1l10DYVxDsTsl.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;The PR diff:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/automating-mybinder-org-dependency-upgrades-in-10-steps/images/002-0_eMFYBJMC-Rktt1T3.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Now that we’ve broken it down a bit, let’s write up some Python code. Once we have a functioning script, we can worry about how we will run this in the cloud (cron job vs. web app).&lt;/p&gt;
&lt;h2 id="writing-the-bot"&gt;Writing the bot&lt;/h2&gt;
&lt;p&gt;If you don’t care about the step-by-step, you can skip to the &lt;a href="https://github.com/henchbot/mybinder.org-upgrades/blob/master/henchbot.py"&gt;final version of the code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the interest of linear understanding and simplicity for a bot-writing tutorial, the step-by-step below will not write functions or classes but just list the raw code necessary to carry out the tasks. The final version of the code linked above is one way to refactor it.&lt;/p&gt;
&lt;h2 id="step-1-retrieve-current-deployed-mybinderorg-dependency-versions"&gt;Step 1: Retrieve current deployed &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; dependency versions&lt;/h2&gt;
&lt;p&gt;The first step is to see if any changes are necessary in the first place. Fortunately, &lt;a href="https://github.com/choldgraf"&gt;@choldgraf&lt;/a&gt; had already made a &lt;a href="https://github.com/jupyterhub/mybinder.org-deploy/blob/master/scripts/list_new_commits.py"&gt;script&lt;/a&gt; to do this.&lt;/p&gt;
&lt;p&gt;To find the current live commit SHA for BinderHub in &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt;, we simply check the &lt;a href="https://raw.githubusercontent.com/jupyterhub/mybinder.org-deploy/master/mybinder/requirements.yaml"&gt;&lt;code&gt;requirements.yaml&lt;/code&gt;&lt;/a&gt; file. We’ll need Python’s &lt;code&gt;yaml&lt;/code&gt; and &lt;code&gt;requests&lt;/code&gt; modules to make the GET request and parse the yaml in the response. Note that this is also conveniently the file we’d want to change to upgrade the version.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;yaml&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;safe_load&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;load&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;url_requirements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;https://raw.githubusercontent.com/jupyterhub/mybinder.org-deploy/master/mybinder/requirements.yaml&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;requirements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url_requirements&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;binderhub_dep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ii&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ii&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;requirements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dependencies&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ii&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;bhub_live&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;binderhub_dep&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;version&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bhub_live&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Similarly, for repo2docker, we check the &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; &lt;a href="https://raw.githubusercontent.com/jupyterhub/mybinder.org-deploy/master/mybinder/values.yaml"&gt;&lt;code&gt;values.yaml&lt;/code&gt;&lt;/a&gt; file:&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;url_helm_chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;https://raw.githubusercontent.com/jupyterhub/mybinder.org-deploy/master/mybinder/values.yaml&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;helm_chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url_helm_chart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;helm_chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;helm_chart&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;r2d_live&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;helm_chart&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;config&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BinderHub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;build_image&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r2d_live&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s store these SHAs in a dictionary we can use for later reference:&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;commit_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
               &lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bhub_live&lt;/span&gt;
&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r2d_live&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="step-2-retrieve-latest-commits-from-the-dependency-repos"&gt;Step 2: Retrieve latest commits from the dependency repos&lt;/h2&gt;
&lt;p&gt;When we get the latest commit SHAs for repo2docker and BinderHub, we need to be careful and make sure we don’t automatically grab the latest one from GitHub. The travis build for &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; looks for the repo2docker Docker image from &lt;a href="https://hub.docker.com/v2/repositories/jupyter/repo2docker/tags/"&gt;DockerHub&lt;/a&gt;, and the latest BinderHub from the &lt;a href="https://raw.githubusercontent.com/jupyterhub/helm-chart/gh-pages/index.yaml"&gt;JupyterHub helm chart&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let’s get the repo2docker version first:&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;https://hub.docker.com/v2/repositories/jupyter/repo2docker/tags/&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;r2d_master&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;results&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r2d_master&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can do BinderHub:&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;url_helm_chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;https://raw.githubusercontent.com/jupyterhub/helm-chart/gh-pages/index.yaml&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;helm_chart_yaml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url_helm_chart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# sort by date created&lt;/span&gt;
&lt;span class="n"&gt;updates_sorted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;helm_chart_yaml&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;entries&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;created&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;bh_master&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;updates_sorted&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;version&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bh_master&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s add these to our dictionary too:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# add to commit_info dictionary&lt;/span&gt;
&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r2d_master&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bh_master&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Great, now we should have all the information we need to determine &lt;em&gt;whether&lt;/em&gt; an update needs to be made or not, &lt;em&gt;and&lt;/em&gt; what the new commit SHA should be!&lt;/p&gt;
&lt;h2 id="step-3-fork-mybinderorg-repo"&gt;Step 3: Fork &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; repo&lt;/h2&gt;
&lt;p&gt;If we determine an upgrade for the repo is necessary, we need to fork the &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; &lt;a href="https://github.com/jupyterhub/mybinder.org-deploy"&gt;repository&lt;/a&gt;, make the change, commit, push, and make a PR. Fortunately, the GitHub API has all the functionality we need! Let’s just make a fork first.&lt;/p&gt;
&lt;p&gt;If you have permissions to a bunch of repos and organizations on GitHub, you may want to &lt;a href="https://help.github.com/en/articles/signing-up-for-a-new-github-account"&gt;create a new account or organization&lt;/a&gt; so that you don’t accidentally start automating git commands through an account that has write access to so much, especially while developing and testing the bot. I created the &lt;a href="https://github.com/henchbot"&gt;henchbot&lt;/a&gt; account for this.&lt;/p&gt;
&lt;p&gt;Once you know which account you want to be making the PRs with, you’ll need to &lt;a href="https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line"&gt;create a personal access token&lt;/a&gt; from within that account. I’ve set this as an environment variable so it isn’t hard-coded in the script.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="n"&gt;TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;HENCHBOT_TOKEN&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://api.github.com/repos/jupyterhub/mybinder.org-deploy/forks&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
			    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Authorization&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;token &lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TOKEN&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using the API for a post request to the &lt;code&gt;forks&lt;/code&gt; endpoint will fork the repo to your account. That’s it!&lt;/p&gt;
&lt;h2 id="step-4-clone-your-fork"&gt;Step 4: Clone your fork&lt;/h2&gt;
&lt;p&gt;You should be quite used to this! We’ll use Python’s &lt;code&gt;subprocess&lt;/code&gt; module to run all of our &lt;code&gt;bash&lt;/code&gt; commands. We’ll need to run these within the for-loop above.&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;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;check_call&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;clone&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;https://github.com/henchbot/mybinder.org-deploy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s also &lt;code&gt;cd&lt;/code&gt; into it and check out a new branch.&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;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mybinder.org-deploy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;check_call&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;checkout&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;-b&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;_bump&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="step-5-make-the-file-changes"&gt;Step 5: Make the file changes&lt;/h2&gt;
&lt;p&gt;Now we need to edit the file like we would for an upgrade.&lt;/p&gt;
&lt;p&gt;For repo2docker, we edit the same &lt;code&gt;values.yaml&lt;/code&gt; file we checked above and replace the old SHA (“live”) with the “latest”.&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;if&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mybinder/values.yaml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
	        &lt;span class="n"&gt;values_yaml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;updated_yaml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;values_yaml&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
			   &lt;span class="s2"&gt;&amp;quot;jupyter/repo2docker:&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
			   &lt;span class="s2"&gt;&amp;quot;jupyter/repo2docker:&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;   
	    &lt;span class="n"&gt;fname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;mybinder/values.yaml&amp;#39;&lt;/span&gt;
	    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
	        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;updated_yaml&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For BinderHub, we edit the same &lt;code&gt;requirements.yaml&lt;/code&gt; file we checked above and replace the old SHA (“live”) with the “latest”.&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;elif&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mybinder/requirements.yaml&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;requirements_yaml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;updated_yaml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requirements_yaml&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                           &lt;span class="s2"&gt;&amp;quot;version: 0.2.0-&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
                           &lt;span class="s2"&gt;&amp;quot;version: 0.2.0-&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;upgrade&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;   
            &lt;span class="n"&gt;fname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;mybinder/requirements.yaml&amp;#39;&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;updated_yaml&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="step-6-stage-commit-push"&gt;Step 6: Stage, commit, push&lt;/h2&gt;
&lt;p&gt;Now that we’ve edited the correct files, we can stage and commit the changes. We’ll make the commit message the name of the repo and the compare URL for the commit changes so people can see what has changed between versions for the dependency.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;        &lt;span class="c1"&gt;# use var fname from editing step&lt;/span&gt;
        &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;check_call&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;add&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fname&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;commit_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;repo2docker: https://github.com/jupyter/repo2docker/compare/&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                              &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;commit_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;binderhub: https://github.com/jupyterhub/binderhub/compare/&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                              &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;check_call&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;config&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;user.name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;henchbot&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;check_call&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;config&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;user.email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;henchbot.github@gmail.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;check_call&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;commit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;-m&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;commit_message&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;check_call&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;git&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;push&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;https://henchbot:&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;@github.com/henchbot/mybinder.org-deploy&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TOKEN&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;_bump&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Awesome, we now have a fully updated fork ready to make a PR to the main repo!&lt;/p&gt;
&lt;h2 id="step-7-make-the-body-for-the-pr"&gt;Step 7: Make the body for the PR&lt;/h2&gt;
&lt;p&gt;We want the PR to have a nice comment explaining what’s happening and linking any helpful information so that the merger knows what they’re doing. We’ll note that this is a version bump and link the URL diff so it can be clicked to see what has changed.&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;if&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;compare_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;https://github.com/jupyter/repo2docker/compare/&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                           &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
                           &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;repo2docker&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;This is a repo2docker version bump. See the link below for a diff of new changes:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compare_url&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;compare_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;https://github.com/jupyterhub/binderhub/compare/&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                           &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
                           &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;binderhub&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;This is a binderhub version bump. See the link below for a diff of new changes:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compare_url&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="step-8-make-the-pr"&gt;Step 8: Make the PR&lt;/h2&gt;
&lt;p&gt;We can use the GitHub API to make a pull request by calling the &lt;code&gt;pulls&lt;/code&gt; endpoint with the &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;body&lt;/code&gt;, &lt;code&gt;base&lt;/code&gt;, and &lt;code&gt;head&lt;/code&gt;. We’ll use the nice body we formatted above, call the title the same as the commit message we made with the repo name and the two SHAs, and put the &lt;code&gt;base&lt;/code&gt; as &lt;code&gt;master&lt;/code&gt; and the &lt;code&gt;head&lt;/code&gt; the name of our fork. Then we just make a POST request to the &lt;code&gt;pulls&lt;/code&gt; endpoint of the main repo.&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;pr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="s1"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                            &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;live&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                                            &lt;span class="n"&gt;commit_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;latest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
              &lt;span class="s1"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s1"&gt;&amp;#39;base&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;master&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s1"&gt;&amp;#39;head&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;henchbot:&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;_bump&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://api.github.com/repos/jupyterhub/mybinder.org-deploy/pulls&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Authorization&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;token &lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TOKEN&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="step-9-confirm-and-merge"&gt;Step 9: Confirm and merge!&lt;/h2&gt;
&lt;p&gt;If we check the &lt;a href="https://github.com/jupyterhub/mybinder.org-deploy/pulls"&gt;mybinder.org PRs&lt;/a&gt;, we would now see the automated PR from our account!&lt;/p&gt;
&lt;h2 id="step-10-automating-the-script-cron"&gt;Step 10: Automating the script (cron)&lt;/h2&gt;
&lt;p&gt;Now that we have a script we can simply execute to create a PR (&lt;code&gt;$ python henchbot.py&lt;/code&gt;), we want to make this as hands-off as possible. Generally we have two options: (1) set this script to be run as a &lt;a href="https://en.wikipedia.org/wiki/Cron"&gt;cron job&lt;/a&gt;; (2) have a web app listener that gets pinged whenever a change is made and executes your script as a reaction to the ping.&lt;/p&gt;
&lt;p&gt;Given that these aren’t super urgent updates that need to be made seconds or minutes after a repository update, we will go for the easier and less computationally-expensive option of cron.&lt;/p&gt;
&lt;p&gt;If you aren’t familiar with cron, it’s simply a system program that will run whatever command you want at whatever time or time interval you want. For now, we’ve decided that we want to execute this script every hour.&lt;/p&gt;
&lt;p&gt;Cron can be run on your local computer (though it would need to be continuously running) or a remote server. I’ve elected to throw it on my raspberry pi, which is always running. Since I have a few projects going on, I like to keep the cron jobs in a file.&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;vim&lt;span class="w"&gt; &lt;/span&gt;crontab-jobs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can define your cron jobs here with the correct syntax (space-separated). Check out &lt;a href="https://crontab.guru/every-1-hour"&gt;this site&lt;/a&gt; for help with the crontab syntax. Since we want to run this every hour, we will set it to run on the 0 minutes, for every hour, every day, every month, every year. We also need to make sure it has the correct environment variable with the GitHub personal access token we created, so we’ll add that to the command.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;0&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="o"&gt;*&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="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;projects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mybinder&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;upgrades&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HENCHBOT_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="n"&gt;XXXXX&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;miniconda3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;henchbot&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we point our cron to the file we’ve created to load the jobs.&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;crontab&lt;span class="w"&gt; &lt;/span&gt;crontab-jobs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To see our active crontab, we can list it:&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;crontab&lt;span class="w"&gt; &lt;/span&gt;-l
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s it! At the top of every hour, our bot will check to see if an update needs to be made, and if so, create a PR. To clean up files and handle existing PRs, in addition to some other details, I’ve written a few other functions. It is also implemented as a class with appropriate methods. You can check out the final code &lt;a href="https://github.com/henchbot/mybinder.org-upgrades/blob/master/henchbot.py"&gt;here&lt;/a&gt;.&lt;/p&gt;
</content><category term="Binder"/><category term="DevOps"/><category term="JupyterHub"/><category term="repo2docker"/></entry><entry><title>The International Binder Federation</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/the-international-binder-federation/" rel="alternate"/><published>2019-07-01T09:11:00+00:00</published><updated>2019-07-01T09:11:00+00:00</updated><author><name>Chris Holdgraf</name></author><id>tag:jasongrout.github.io,2019-07-01:/medium-archive/pelican/posts/2019/the-international-binder-federation/</id><summary type="html">&lt;p&gt;We are happy to announce that mybinder.org is now backed by two clusters hosted by two different cloud providers: Google Cloud and OVH.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;About two years ago, the Binder project evolved into the community led project that it is today. The deployment at &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; was upgraded to use&lt;br&gt;
BinderHub, a scalable open-source web application that runs on Kubernetes and provides free, sharable, interactive computing environments to people&lt;br&gt;
all around the world.&lt;/p&gt;
&lt;p&gt;In the ensuing years, the Binder community has grown considerably.&lt;br&gt;
Now people use the public deployment at &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; around 100,000 times each week, and there are around &lt;a href="https://github.com/betatim/binderlyzer/blob/master/binder-launches.ipynb"&gt;8,000 unique repositories&lt;/a&gt; compatible with Binder. Binder links now work with multiple repository providers, such as GitHub, GitLab, BitBucket, and even Zenodo! This means that providing enough compute power for everyone is a challenge.&lt;/p&gt;
&lt;p&gt;This is why today we are happy to announce that mybinder.org is now backed by two clusters hosted by two different cloud providers: Google Cloud and &lt;a href="https://www.ovh.com"&gt;OVH&lt;/a&gt;. This is the beginning of the International Binder Federation.&lt;/p&gt;
&lt;p&gt;How did we get here? Alongside mybinder.org’s growth we’ve seen growth in another part of the Binder ecosystem: people deploying a BinderHub for their own groups. In the last year, we have seen BinderHubs deployed &lt;a href="http://pangeo.io/"&gt;for large-scale earth analytics with the Pangeo project&lt;/a&gt;, for &lt;a href="https://the-turing-way.netlify.com/introduction/introduction"&gt;communities of best-practices in open science with The Turing Way&lt;/a&gt;, and for &lt;a href="https://notebooks.gesis.org/binder/"&gt;specific domains such as the social sciences like GESIS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As more BinderHubs are deployed, we realized that there was an opportunity to leverage the strengths and resources of the community to improve the large, public BinderHub deployment at &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt;. Instead of a single BinderHub run by the Binder team, we could build a &lt;strong&gt;network&lt;/strong&gt; of BinderHubs that shares the load and keeps &lt;code&gt;mybinder.org&lt;/code&gt; stable and quick.&lt;/p&gt;
&lt;h2 id="ovh-joins-the-mybinderorg-federation"&gt;OVH Joins the &lt;a href="http://mybinder.org/"&gt;mybinder.org&lt;/a&gt; Federation&lt;/h2&gt;
&lt;p&gt;Today, we are thrilled to announce that the Binder Project now has &lt;strong&gt;a world-wide federation of BinderHubs powering&lt;/strong&gt; &lt;a href="http://mybinder.org/"&gt;&lt;strong&gt;mybinder.org&lt;/strong&gt;&lt;/a&gt;. We’ve partnered with OVH, a cloud hosting company based in Europe that is supportive of open projects such as Jupyter and Binder.&lt;/p&gt;
&lt;p&gt;Through the partnership with OVH, all traffic to &lt;code&gt;mybinder.org&lt;/code&gt; will now be split between &lt;strong&gt;two&lt;/strong&gt; BinderHubs - one run by the Binder team, and another run by a team of open-source advocates at OVH. They have generously offered their resources and computing time to allow Binder to serve the scientific and educational communities.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The mybinder.org federation currently has two BinderHubs, but this network can (and will!) grow as more groups offer to connect their own BinderHubs to the network." src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/the-international-binder-federation/images/001-1_D0lhgUpJeWhb6K7igl4DvQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The mybinder.org federation currently has two BinderHubs, but this network can (and will!) grow as more groups offer to connect their own BinderHubs to the network.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="what-does-this-mean"&gt;What does this mean?&lt;/h2&gt;
&lt;p&gt;So what has changed for you, the user? Probably not much. The&lt;br&gt;
biggest difference you’ll notice is that landing at &lt;code&gt;mybinder.org&lt;/code&gt;&lt;br&gt;
will now &lt;em&gt;redirect&lt;/em&gt; you to one of two places:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gke.mybinder.org&lt;/code&gt; is the BinderHub hosted on the Google Cloud Platform&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ovh.mybinder.org&lt;/code&gt; is the BinderHub hosted on the OVH platform in France.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other than this, your experience should be the same. You might even notice an improvement in speed and load times because the BinderHub you’re using has a little bit less traffic on it 😀.&lt;/p&gt;
&lt;p&gt;As always, we are pushing this out as soon as we think it is useful. You can help us to scale this model and make it rock solid by reporting weird things you notice. Expect tweaks over the next few weeks based on feedback from users. Let us know about the things you like, dislike or have questions about at &lt;a href="https://discourse.jupyter.org/t/the-binder-federation/1286"&gt;https://discourse.jupyter.org/t/the-binder-federation/1286&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="why-is-this-a-big-deal"&gt;Why is this a big deal?&lt;/h2&gt;
&lt;p&gt;We think that having a federation of BinderHubs behind mybinder.org is pretty cool, for a few different reasons. First, it demonstrates the dedication that the Binder community has towards building tools that anybody can deploy — we certainly don’t want to be the only ones running a BinderHub, and having other BinderHubs behind mybinder.org is a great example of this. Second, a network of BinderHubs for mybinder.org means that we can eventually do some clever things like use geolocation to distribute users, which should improve the performance that you all experience. Third, having fewer users per BinderHub means that we can optimize the resources available to each hub — resulting in improvements in speed and stability. Finally, having a federation of BinderHubs makes the mybinder.org service significantly more robust, and less-dependent on a single team, deployment, platform, and funding source. We are now more confident than ever that mybinder.org will continue to be available as a stable, free, public service that keeps growing.&lt;/p&gt;
&lt;h2 id="whats-next"&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;Now that we’ve reached N=2 BinderHubs powering &lt;code&gt;mybinder.org&lt;/code&gt;,&lt;br&gt;
it is straightforward for us to grow this network to N=3 and beyond. Over the summer we will continue our work on approaching universities, research councils, and cloud hosting companies.&lt;/p&gt;
&lt;p&gt;If you are interested in helping out: we’d love to see other community members come forward to offer their time or resources to provide more nodes in the international BinderHub federation. If you’re interested in doing so, please &lt;a href="https://github.com/jupyterhub/team-compass/issues"&gt;open an issue in the JupyterHub team compass repository&lt;/a&gt;&lt;br&gt;
to discuss the possibilities of working together!&lt;/p&gt;
&lt;p&gt;We’re excited about the ability for the Binder community continuing&lt;br&gt;
to grow, and to build more tools for distributed, community-run&lt;br&gt;
infrastructure for open science and education. This is all possible&lt;br&gt;
because of the hard work of many people in the community, so a big&lt;br&gt;
thank you to those who spend their time working on open tools in&lt;br&gt;
the Jupyter and Binder ecosystems. We’re excited to see what comes&lt;br&gt;
next!&lt;/p&gt;
</content><category term="Binder"/><category term="cloud computing"/><category term="Kubernetes"/></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>BinderHub is out of Beta!</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/binderhub-is-out-of-beta/" rel="alternate"/><published>2019-04-26T16:49:00+00:00</published><updated>2019-04-26T18:41:00+00:00</updated><author><name>Tim Head</name></author><id>tag:jasongrout.github.io,2019-04-26:/medium-archive/pelican/posts/2019/binderhub-is-out-of-beta/</id><summary type="html">&lt;p&gt;Today we are proud to announce that we now consider BinderHub a stable tool with a track record of operating in production.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Nearly two years ago, the Binder Project &lt;a href="/posts/2017/binder-2-0-a-tech-guide-2017/"&gt;released the beta version&lt;/a&gt;&lt;br&gt;
of &lt;a href="https://binderhub.readthedocs.io/"&gt;BinderHub&lt;/a&gt;, the technology behind &lt;a href="https://mybinder.org"&gt;mybinder.org&lt;/a&gt;. Since then, mybinder.org has grown to serve nearly 90,000 launches each week and hit the &lt;a href="/posts/2018/mybinder-org-serves-two-million-launches/"&gt;two million launches in a year milestone last year&lt;/a&gt;. Over these two years BinderHub has matured as technology and community. Several new organizations now run their own BinderHubs and have joined the community of maintainers.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A year of Binder sessions served from mybinder.org. Darker colors show users in countries that have launched more Binder sessions. The pins show the approximate locations of public BinderHubs that we know of. Where is mybinder.org? It is a global effort so there is no one location associated with it or the team that runs it." src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/binderhub-is-out-of-beta/images/001-1_zGQcuph2mrh7ry_tH_QJYQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A year of Binder sessions served from mybinder.org. Darker colors show users in countries that have launched more Binder sessions. The pins show the approximate locations of public BinderHubs that we know of. Where is mybinder.org? It is a global effort so there is no one location associated with it or the team that runs it.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Today we are proud to announce that we’ve removed the “beta” label from all pages served by BinderHub. BinderHub is now a tool with a track record of working well in production (both at mybinder.org and in other deployments), its general features and API have stabilized, and &lt;a href="https://jupyterhub.readthedocs.io/en/stable/"&gt;JupyterHub&lt;/a&gt;, the underlying technology that BinderHub uses, is close to its 1.0 release.&lt;/p&gt;
&lt;p&gt;A big thank you to all those who have used, commented, advocated, advertised, contributed, maintained and funded this journey. The deployment at mybinder.org is funded with grants from the &lt;a href="https://www.moore.org/grant-detail?grantId=GBMF6865"&gt;Moore Foundation&lt;/a&gt; and the Google Cloud Platform.&lt;/p&gt;
&lt;h3 id="who-else-has-deployed-a-binderhub"&gt;Who else has deployed a BinderHub?&lt;/h3&gt;
&lt;p&gt;A goal of Project Binder is to build modular, open-source tools that&lt;br&gt;
others can deploy for their own communities. BinderHub, the core technology behind mybinder.org, runs on Kubernetes this means it can be deployed on many cloud providers or even on your own hardware. Over the years, we have seen many new organizations deploy their own BinderHubs. Here are our highlights of other organizations who have joined the BinderHub community.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GESIS&lt;/strong&gt; were the first to deploy a public BinderHub that is operated independently of mybinder.org. The &lt;a href="https://notebooks.gesis.org/binder/"&gt;GESIS BinderHub instance&lt;/a&gt; went live&lt;br&gt;
in December 2017 and has been running ever since. They are frequent&lt;br&gt;
contributors to the upstream project. Their BinderHub runs on a bare metal&lt;br&gt;
Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Pangeo Project&lt;/strong&gt; instance was the next to come online, launching &lt;a href="https://binder.pangeo.org"&gt;their&lt;br&gt;
public BinderHub instance&lt;/a&gt; in September 2018 (more details in their &lt;a href="https://medium.com/pangeo/pangeo-meets-binder-2ea923feb34f"&gt;blog post&lt;/a&gt;). They provide additional compute resources and have customized their setup to provide on-demand &lt;a href="https://dask.org/"&gt;dask&lt;/a&gt; clusters to users. Try out &lt;a href="http://binder.pangeo.io/v2/gh/pangeo-data/pangeo_ocean_examples/master"&gt;one&lt;br&gt;
of their examples using ocean data&lt;/a&gt;. The Pangeo cluster is hosted on Google Kubernetes Engine.&lt;/p&gt;
&lt;p&gt;Recently, the &lt;a href="https://www.turing.ac.uk/research/research-projects/turing-way-handbook-reproducible-data-science"&gt;&lt;strong&gt;Turing Way project&lt;/strong&gt;&lt;/a&gt; has been working on deploying a BinderHub at the &lt;a href="https://www.turing.ac.uk/"&gt;Turing Institute&lt;/a&gt; in the UK. This BinderHub will serve both internal and external users with the goal of making it easier to share data science projects. They have run several workshops including one that teaches scientists and research software engineers how to deploy their own BinderHub instance. Recently they led a workshop in which ten academics and IT staff deployed their own BinderHub on the Microsoft Azure cloud! Sarah Gibson from their team has recently joined the team that operates mybinder.org.&lt;/p&gt;
&lt;p&gt;Finally, the &lt;a href="https://www.pims.math.ca/"&gt;&lt;strong&gt;Pacific Institute for the Mathematical Sciences&lt;/strong&gt;&lt;/a&gt; (PIMS) runs a service &lt;a href="https://intro.syzygy.ca/"&gt;called Syzygy&lt;/a&gt;. It deploys several JupyterHubs and BinderHubs for scientific organizations around Canada. A Binder team recently held a tutorial on deploying Binder and JupyterHub at the PEARC (&lt;a href="https://docs.google.com/presentation/d/1ELYepgptS7LcpBwjrotPRcQENr_WlxX0eQaBvzZonxs/edit?usp=sharing"&gt;you can find slides for the talk here&lt;/a&gt;). They have also &lt;a href="https://github.com/etiennedub/terraform-binderhub"&gt;provided a script for deploying JupyterHub&lt;/a&gt; (and Binder) on Terraform.&lt;/p&gt;
&lt;h3 id="whats-next"&gt;What’s next?&lt;/h3&gt;
&lt;p&gt;Now that BinderHub is not in beta anymore, what is next? As Project Binder we will focus on adoption, training, and growing the Binder community. This means growing the creation of &lt;strong&gt;Binder-ready repositories&lt;/strong&gt; (repositories that have the necessary structure for Binder to create the environment needed to run the repository’s code). We will increase our outreach and marketing efforts to make sure a diverse audience everywhere around the world knows about Binder.&lt;/p&gt;
&lt;p&gt;We will also work on making it easier to setup and operate a public BinderHub no matter what cloud vendor you are using. We are excited to see more organizations deploy their own BinderHubs for their communities. In the coming months, our goal is to create a &lt;strong&gt;federation of public BinderHubs&lt;/strong&gt;&lt;br&gt;
that operate in unison to serve the global user base of mybinder.org.&lt;/p&gt;
&lt;p&gt;If this caught your attention consider joining the Binder community, or contributing to Project Binder! A good place to start is the &lt;a href="https://discourse.jupyter.org"&gt;Jupyter Community Forum&lt;/a&gt; or dive straight into &lt;a href="http://github.com/jupyterhub/"&gt;the code on GitHub&lt;/a&gt;.&lt;/p&gt;
</content><category term="Binder"/><category term="Kubernetes"/><category term="releases"/></entry><entry><title>elife sprint: Integrating Stencila and Binder</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2018/elife-sprint-integrating-stencila-and-binder/" rel="alternate"/><published>2018-12-10T10:15:00+00:00</published><updated>2018-12-10T10:15:00+00:00</updated><author><name>Daniel Nüst</name></author><id>tag:jasongrout.github.io,2018-12-10:/medium-archive/pelican/posts/2018/elife-sprint-integrating-stencila-and-binder/</id><summary type="html">&lt;p&gt;Short report on the project nbstencilaproxy for integrating Stencila and Binder.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;em&gt;This article reports on a project, integrating Stencila and Binder, which started at the eLife Innovation Sprint 2018 (&lt;/em&gt;&lt;a href="https://twitter.com/hashtag/eLifeSprint?src=hash"&gt;&lt;code&gt;#eLifeSprint&lt;/code&gt;&lt;/a&gt;&lt;em&gt;). A longer version has been cross-posted on multiple blogs (&lt;/em&gt;&lt;a href="https://elifesciences.org/labs/d42fe2b9/integrating-binder-and-stencila-the-building-blocks-to-increased-open-communication-and-transparency"&gt;&lt;em&gt;eLife Labs&lt;/em&gt;&lt;/a&gt;, &lt;a href="https://stenci.la/blog/2018-11-20-stencila-binder/"&gt;&lt;em&gt;Stencila,&lt;/em&gt;&lt;/a&gt; &lt;a href="https://o2r.info/2018/11/21/elife-sprint-integrating-stencila-and-binder/"&gt;&lt;em&gt;o2r&lt;/em&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;a href="https://elifesciences.org/"&gt;eLife&lt;/a&gt;, an open science journal published by the non-profit organisation eLife Sciences Publications from the UK, hosted the first &lt;a href="https://elifesciences.org/labs/bdd4c9aa/elife-innovation-sprint-2018-project-roundup"&gt;eLife Innovation Sprint 2018&lt;/a&gt; as part of their &lt;a href="https://elifesciences.org/about/innovation"&gt;Innovation Initiative&lt;/a&gt; in Cambridge, UK: &lt;em&gt;“[…] a two-day gathering of 62 researchers, designers, developers, technologists, science communicators and more, with the goal of developing prototypes of innovations that bring cutting-edge technology to open research communication.”&lt;/em&gt; One of the &lt;a href="https://elifesciences.org/labs/bdd4c9aa/elife-innovation-sprint-2018-project-roundup"&gt;13&lt;/a&gt; projects at the &lt;a href="https://elifesciences.org/inside-elife/b4ed92e1/innovation-collaboration-and-creativity-at-the-heart-of-the-elife-innovation-sprint-2018"&gt;excellently organised event&lt;/a&gt; was an &lt;strong&gt;integration of&lt;/strong&gt; &lt;a href="https://mybinder.readthedocs.io/"&gt;&lt;strong&gt;Binder&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;a href="https://stenci.la/"&gt;&lt;strong&gt;Stencila&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This article reports on the project’s results and changes made to Binder-related tools. &lt;strong&gt;Today, Binder has first class Stencila support.&lt;/strong&gt; Read the full story at the &lt;a href="https://elifesciences.org/labs/d42fe2b9/integrating-binder-and-stencila-the-building-blocks-to-increased-open-communication-and-transparency"&gt;eLife Labs blog post&lt;/a&gt; or try out to open Stencila documents from any online code repository on &lt;a href="https://mybinder.org/"&gt;mybinder.org&lt;/a&gt; with the click of a single button:&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://mybinder.org/v2/gh/binder-examples/stencila-py/master?urlpath=stencila"&gt;&lt;img alt="Click the Binder badge to open a Stencila document on mybinder.org" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/elife-sprint-integrating-stencila-and-binder/images/001-1_H28MLVCxQzhuXzKzbMyiZA.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;Click the Binder badge to open a Stencila document on mybinder.org&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This project is a collaboration between &lt;a href="https://github.com/minrk"&gt;Min&lt;/a&gt; from the &lt;a href="https://www.simula.no/people/benjaminrk"&gt;Simula Research Laboratory&lt;/a&gt;, Norway, a core developer of &lt;a href="https://mybinder.readthedocs.io/en/latest/"&gt;Binder&lt;/a&gt; and related tools, &lt;a href="https://github.com/nuest"&gt;Daniel&lt;/a&gt; from the &lt;a href="https://o2r.info"&gt;o2r&lt;/a&gt; project at the &lt;a href="https://www.uni-muenster.de/Geoinformatics/"&gt;Institute for Geoinformatics&lt;/a&gt;, Germany, &lt;a href="https://github.com/nokome"&gt;and Nokome&lt;/a&gt;, initiator and developer of Stencila. The final changes were made with the help of &lt;a href="https://github.com/betatim"&gt;Tim&lt;/a&gt;. Thanks! The project was also part of the &lt;a href="https://mozilla.github.io/global-sprint/"&gt;Mozilla Global Sprint 2018&lt;/a&gt;, see &lt;a href="https://github.com/mozilla/global-sprint/issues/317"&gt;mozilla/global-sprint#317&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="the-building-blocks-and-a-challenge"&gt;The building blocks and a challenge&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Stencila Desktop&lt;/strong&gt; is an &lt;a href="https://elifesciences.org/labs/c496b8bb/stencila-an-office-suite-for-reproducible-research"&gt;office suite for reproducible research documents&lt;/a&gt;. It allows scientists to use languages like R and Python within familiar and intuitive word processor and spreadsheet user interfaces to lower the barriers to reproducible research for those with little or no software development skills. &lt;strong&gt;Binder&lt;/strong&gt; (a part of &lt;a href="https://jupyter.org/"&gt;Project Jupyter&lt;/a&gt;) makes it simple to generate reproducible computing environments from code repositories (e.g. GitHub or GitLab, see &lt;a href="https://github.com/binder-examples/"&gt;binder examples&lt;/a&gt;) and &lt;a href="https://mybinder.org/"&gt;mybinder.org&lt;/a&gt; is the most prominent example. Binder uses &lt;a href="https://repo2docker.readthedocs.io/"&gt;repo2docker&lt;/a&gt;, for generating &lt;code&gt;Dockerfile&lt;/code&gt;s (a human- and machine-readable recipe for setting up a computational environmentt used by the popular &lt;a href="https://en.wikipedia.org/wiki/Docker_(software)"&gt;Docker&lt;/a&gt; container software) and building Docker images from software projects. While containers have become a commodity for developers, researchers still struggle to grasp and control the complexity of computational environments. This is where the two building blocks join: &lt;strong&gt;Running Stencila as part of a Binder helps researchers to communicate their work openly, to collaborate effectively with other scientists, and to ensure a high quality and transparency of their workflow and findings.&lt;/strong&gt; Min and Daniel &lt;a href="https://docs.google.com/document/d/1WPMY-Al7WMdjlepKvvLiIxFrQPHFbADMNuwszs8xMHk/edit"&gt;formulated their goal in the sprint project form&lt;/a&gt;: &lt;em&gt;“[…] to connect them so that users can edit reproducible documents (DAR files) as part of a Binder project”.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="connecting-stencila-and-jupyter-nbstencilaproxy"&gt;Connecting Stencila and Jupyter: &lt;code&gt;nbstencilaproxy&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Stencila has “execution contexts”, an equivalent to Jupyter’s “kernels”. The contexts use code dependency analysis and return execution results as data values to enable a reactive, functional execution model. To open Stencila documents on binder, these execution contexts must be installed and configured in the environment created by &lt;code&gt;repo2docker&lt;/code&gt;. This is achieved with a new software project initiated at the sprint: &lt;code&gt;nbstencilaproxy&lt;/code&gt; - a Jupyter notebook server extension and proxy for Stencila.&lt;/p&gt;
&lt;p&gt;The projects consists of a &lt;strong&gt;Python module&lt;/strong&gt; with the Jupyter notebook server and “non-server” extensions of the same name, and a &lt;a href="https://github.com/minrk/nbstencilaproxy/commit/93dabbd890397aaad0d8efb316f7e1f2129e52f3"&gt;bundled&lt;/a&gt; &lt;strong&gt;JavaScript module&lt;/strong&gt; (of the same name). The Python module allows proper versioned installation, dependency management, and installation from an established software repository. It takes care of the plumbing between the user interface and the services in the background, so that the binder is viewable over one port in the browser, while the many different background components run on their own ports. The “no server” extension adds a “Stencila session” menu entry and conveniently lives in the same directory structure as the server extension. The JavaScript module manages the required JavaScript dependencies and provides an well-defined structure for the code files. It serves the Dar document and provides access to the Stencila host.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;repo2docker&lt;/code&gt; was extended with &lt;a href="https://github.com/jupyter/repo2docker/pull/309/commits/eaa29ef3343442419df8cdd022f3e91ae9262926"&gt;automatic detection of Dar documents&lt;/a&gt;, including the &lt;a href="https://github.com/jupyter/repo2docker/pull/457"&gt;languages and execution context&lt;/a&gt;s. As with most Binder repositories, a no configuration is needed for most common user cases: users can open a Dar document on Binder and trust the required environment to provide all required software. Daniel created a few &lt;strong&gt;example repositories&lt;/strong&gt; to provide a starting point for users. The binder team generously welcomed &lt;a href="https://o2r.info/2018/11/21/elife-sprint-integrating-stencila-and-binder/"&gt;the changes to mybinder.org&lt;/a&gt; and and the examples to the &lt;a href="https://github.com/binder-examples/"&gt;binder examples organisation&lt;/a&gt; on GitHub:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/binder-examples/stencila-py"&gt;&lt;strong&gt;https://github.com/binder-examples/stencila-py&lt;/strong&gt;&lt;/a&gt; contains Python code cells, using both the Jupyter and plain Python execution contexts:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/elife-sprint-integrating-stencila-and-binder/images/002-0_BHjQbPTLV3XHoNqG.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://mybinder.org/v2/gh/binder-examples/stencila-py/master?urlpath=stencila"&gt;&lt;img alt="Click the Binder badge to open a Stencila document with Python code on mybinder.org" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/elife-sprint-integrating-stencila-and-binder/images/001-1_H28MLVCxQzhuXzKzbMyiZA.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;Click the Binder badge to open a Stencila document with Python code on mybinder.org&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href="https://github.com/binder-examples/stencila-r"&gt;&lt;strong&gt;https://github.com/binder-examples/stencila-r&lt;/strong&gt;&lt;/a&gt; contains R code cells and two plots:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/elife-sprint-integrating-stencila-and-binder/images/003-0_osOwhBZGwlnr5FNk.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://mybinder.org/v2/gh/binder-examples/stencila-r/master?urlpath=stencila"&gt;&lt;img alt="Click the Binder badge to open a Stencila document with R code on mybinder.org" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/elife-sprint-integrating-stencila-and-binder/images/001-1_H28MLVCxQzhuXzKzbMyiZA.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;Click the Binder badge to open a Stencila document with R code on mybinder.org&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;One of the cool features of Stencila are the reactive cells, as demonstrated in a tweet following the feature release:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thanks to @nordholmen working on &lt;a href="https://x.com/stencila"&gt;@stencila&lt;/a&gt; support for &lt;a href="https://t.co/Zlj6FrYgBw"&gt;https://t.co/Zlj6FrYgBw&lt;/a&gt; you now have reactive cells with Python code on &lt;a href="https://x.com/mybinderteam"&gt;@mybinderteam&lt;/a&gt;! Give it a go &lt;a href="https://t.co/ToIuQPq0Fy"&gt;https://t.co/ToIuQPq0Fy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://x.com/betatim/status/1062004432806785024"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/elife-sprint-integrating-stencila-and-binder/images/004-Drz_AZeXQAAdMmn.jpg" alt="Video" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;— &lt;a href="https://x.com/betatim"&gt;Tim Head, @betatim on the internet (@betatim)&lt;/a&gt;, &lt;a href="https://x.com/betatim/status/1062004432806785024"&gt;November 12, 2018&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;Binder + Stencila is a demonstration of the power that the Open Source and Open Science community can foster. Many people are working together on the organisational and technological challenges of science today towards full research transparency and reproducibility, even if we use computers to an unprecedented level. Many small contributions on “side projects” such as these can make a difference, and connecting these two great projects hopefully helps to solve some problem in science down the road.&lt;/p&gt;
&lt;p&gt;Join the public &lt;a href="https://gitter.im/stencila/stencila"&gt;Stencila&lt;/a&gt; and &lt;a href="https://gitter.im/jupyterhub/binder"&gt;binder&lt;/a&gt; chats to stay in touch or get help. We look forward to see scientists using &lt;code&gt;nbstencilaproxy&lt;/code&gt; for communicating their work and new challenges that come with it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://x.com/hashtag/eLifeSprint?src=hash"&gt;#eLifeSprint&lt;/a&gt;-ers &lt;a href="https://x.com/minrk"&gt;@minrk&lt;/a&gt; and @nordholmen are working to connect &lt;a href="https://x.com/hashtag/JupyterNotebooks?src=hash"&gt;#JupyterNotebooks&lt;/a&gt; / &lt;a href="https://x.com/hashtag/Binder?src=hash"&gt;#Binder&lt;/a&gt; with DAR / &lt;a href="https://x.com/hashtag/Texture?src=hash"&gt;#Texture&lt;/a&gt; / &lt;a href="https://x.com/stencila"&gt;@Stencila&lt;/a&gt;, so that users can edit reproducible documents as part of a Binder project &lt;a href="https://t.co/2GoGNydsmX"&gt;https://t.co/2GoGNydsmX&lt;/a&gt; (&lt;a href="https://x.com/mybinderteam"&gt;@mybinderteam&lt;/a&gt; &lt;a href="https://x.com/ProjectJupyter"&gt;@ProjectJupyter&lt;/a&gt; &lt;a href="https://x.com/_SUBSTANCE"&gt;@_substance&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/elife-sprint-integrating-stencila-and-binder/images/005-Dc14Uo1W0AEwdk9.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;— &lt;a href="https://x.com/eLifeInnovation"&gt;eLife Innovation (@eLifeInnovation)&lt;/a&gt;, &lt;a href="https://x.com/eLifeInnovation/status/994583390895697920"&gt;May 10, 2018&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content><category term="Binder"/><category term="open science"/><category term="reproducibility"/></entry><entry><title>MyBinder.org serves two million launches</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2018/mybinder-org-serves-two-million-launches/" rel="alternate"/><published>2018-11-13T12:35:00+00:00</published><updated>2018-11-13T12:35:00+00:00</updated><author><name>Tim Head</name></author><id>tag:jasongrout.github.io,2018-11-13:/medium-archive/pelican/posts/2018/mybinder-org-serves-two-million-launches/</id><summary type="html">&lt;p&gt;by the Binder Team&lt;/p&gt;
</summary><content type="html">&lt;p&gt;by the &lt;a href="https://twitter.com/mybinderteam"&gt;Binder Team&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since the beginning of 2018, the Binder community has been hosting a &lt;a href="https://github.com/jupyterhub/binderhub"&gt;BinderHub&lt;/a&gt; at &lt;a href="https://mybinder.org"&gt;https://mybinder.org&lt;/a&gt; as a free public service. Today, we are proud to announce that this hub has served over two million &lt;a href="https://mybinder.readthedocs.io/en/latest/introduction.html"&gt;Binders&lt;/a&gt;. To mark this milestone we would like to say a huge Thank You! to the large community of people who use, &lt;a href="https://github.com/jupyterhub/binder#binder"&gt;build&lt;/a&gt;, and &lt;a href="https://www.moore.org/"&gt;fund&lt;/a&gt; the project. Without you this important public infrastructure would not be the user-friendly, reliable, well-supported and documented resource that we enjoy today. mybinder.org has enabled people from almost every country in the world to learn, participate and share countless projects, ideas and stories. Here’s to two million more!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A huge thank you to all those who help with building, using, and operating ." src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/mybinder-org-serves-two-million-launches/images/001-1_Rs3YZOC_GtnOO37TRI7pQA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A huge thank you to all those who help with building, using, and operating &lt;a href="https://mybinder.org"&gt;https://mybinder.org&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="what-is-mybinderorg"&gt;What is mybinder.org?&lt;/h2&gt;
&lt;p&gt;mybinder.org let’s you take a repository full of Jupyter notebooks or RMarkdown and turn it into a collection of interactive notebooks. You can share your work with anyone by sending them a simple link (&lt;a href="https://mybinder.org/v2/gh/norvig/pytudes/master?filepath=ipynb%2FMaze.ipynb"&gt;like this one&lt;/a&gt;). All they have to do is open the link in a web browser and they can run those notebooks from anywhere in the world without having to install anything.&lt;/p&gt;
&lt;h2 id="who-is-using-mybinderorg"&gt;Who is using mybinder.org?&lt;/h2&gt;
&lt;p&gt;Currently about 70–80,000 &lt;a href="https://mybinder.readthedocs.io/en/latest/introduction.html"&gt;Binders&lt;/a&gt; are launched every week. A lot of those are people who are looking for a quick and easy way to launch a &lt;a href="https://mybinder.org/v2/gh/ipython/ipython-in-depth/master?filepath=binder/Index.ipynb"&gt;Python&lt;/a&gt; or &lt;a href="http://beta.mybinder.org/v2/gh/binder-examples/r/master?urlpath=rstudio"&gt;RStudio&lt;/a&gt; environment. However in the last week a notebook showing off &lt;a href="https://mybinder.org/v2/gh/quasiben/fiftyfizzbuzzes/master?filepath=Fifty%20Fizzbuzzes.ipynb"&gt;fifty ways to solve Fizz Buzz&lt;/a&gt; has been getting a lot of love. Beyond those heavy hitters and short-lived audience favorites there is a long tail of over 400 unique repositories that get launched every week. It would take the rest of the post to list them all!&lt;/p&gt;
&lt;p&gt;One last statistic that we are particularly proud of: over the last 80 days we have had users from almost all around the globe! Binder was started as a way to make computational research easier to share and reuse. We have been amazed at how many people around the world have used Binder for teaching classes, reproducing results, sharing interactive analyses, and making their work more accessible to others. We are particularly proud that this includes people from around the entire world.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Countries from which has received visitors between 22 August 2018 and 10 November 2018." src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/mybinder-org-serves-two-million-launches/images/002-1_t6_W35g1Kl1Yr8oGPVlyIA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Countries from which &lt;a href="https://mybinder.org"&gt;https://mybinder.org&lt;/a&gt; has received visitors between 22 August 2018 and 10 November 2018.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="data-set-of-all-launches-on-mybinderorg"&gt;Data set of all launches on mybinder.org&lt;/h2&gt;
&lt;p&gt;mybinder.org is operated as a public infrastructure that is transparent, open, and inclusive. We &lt;a href="https://gitter.im/jupyterhub/binder"&gt;chat&lt;/a&gt;, &lt;a href="https://discourse.jupyter.org/"&gt;discuss&lt;/a&gt;, and &lt;a href="https://github.com/jupyterhub/binder"&gt;work&lt;/a&gt; in the open. This is why we are now publishing a new data set: a continuously updated log of every launch that happens on mybinder.org!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://archive.analytics.mybinder.org/"&gt;MyBinder.org Events Archive&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We would love to see people explore this data set as a public resource that describes the kinds of repositories being shared and launched on the public mybinder.org deployment.&lt;/p&gt;
&lt;h2 id="a-new-badge"&gt;A new badge!&lt;/h2&gt;
&lt;p&gt;One more thing … we thought now is a good time to give the trusty “Launch Binder” badge an overhaul. To improve the badge we put together some suggestions, &lt;a href="https://discourse.jupyter.org/t/help-us-choose-an-updated-launch-binder-badge/100"&gt;reached out to the community&lt;/a&gt;, and within a few days received a lot of feedback and new ideas. After combining all the inputs, our new badge went live earlier this week. We present to you our new badge:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The new “Launch Binder” badge. Binder blue instead of bright red!" src="https://jasongrout.github.io/medium-archive/pelican/posts/2018/mybinder-org-serves-two-million-launches/images/003-1_gHu0NhZgTuRlvnD7eDI6Og.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The new “Launch Binder” badge. Binder blue instead of bright red!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We hope you like it as much as we do. If you are in love with the old design or not quite ready to switch yet, do not worry! The old badge is not going anywhere. If you are using the old badge in your README it will continue to look the same as it always has.&lt;/p&gt;
&lt;p&gt;If you do want to change a previously generated link to the new badge, edit the name of the SVG in the link from the old:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;![Binder&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;mybinder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;badge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;mybinder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gh&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;binder&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to the new:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;![Binder&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;mybinder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;badge_logo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;mybinder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gh&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;binder&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;examples&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;master&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;Outro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="open-infrastructure-in-the-cloud"&gt;Open infrastructure in the cloud&lt;/h2&gt;
&lt;p&gt;The Binder project is a community-driven experiment in radically-open infrastructure. BinderHub, the underlying technology that powers a Binder deployment, is an open project and can be deployed in many other cloud environments. For example, see the &lt;a href="http://binder.pangeo.io/"&gt;Pangeo Binder deployment&lt;/a&gt; for geospatial analytics, or the &lt;a href="https://notebooks.gesis.org/binder/"&gt;Gesis Binder deployment for social sciences&lt;/a&gt;. We are excited to see the project head in new directions as we continue to grow the technology and the community around Binder.&lt;/p&gt;
&lt;p&gt;Finally, we could not have done any of this without a ton of support from the Binder community. First, many thanks to &lt;a href="https://www.moore.org/"&gt;the Moore Foundation&lt;/a&gt; for funding initial development of Binder’s underlying tech, and for helping us finance running the deployment at mybinder.org. Second, many thanks to the &lt;a href="https://jupyterhub-team-compass.readthedocs.io/en/latest/team.html"&gt;Binder project core team&lt;/a&gt; for fostering excellent technology and a great community. Finally, thanks to everybody in the Binder community — whether you’ve launched repositories, shared your Binders, participated in discussions, built features, &lt;a href="https://github.com/jupyterhub/team-compass/issues/67"&gt;helped design this post’s banner image&lt;/a&gt; (❤), or gave us some critical feedback. Binder’s purpose is to serve the community, and you all have made it so worth it!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;If you’d like to get involved in the Binder project, here are a few helpful links:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;To learn about Binder, see the Binder documentation:&lt;/em&gt; &lt;a href="http://docs.mybinder.org"&gt;&lt;em&gt;docs.mybinder.org&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;For information on how to deploy your own BinderHub, see the BinderHub deployment docs:&lt;/em&gt; &lt;a href="http://binderhub.readthedocs.io"&gt;&lt;em&gt;binderhub.readthedocs.io&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;To participate in conversations with the Binder community, say hello on the Binder gitter channel (&lt;/em&gt;&lt;a href="https://gitter.im/jupyterhub/binder"&gt;&lt;em&gt;https://gitter.im/jupyterhub/binder&lt;/em&gt;&lt;/a&gt;&lt;em&gt;) or the JupyterHub/Binder Discourse forum (&lt;/em&gt;&lt;a href="https://discourse.jupyter.org"&gt;&lt;em&gt;discourse.jupyter.org&lt;/em&gt;&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;If you’d like to see the code itself, see the three main open projects that make up a Binder deployment: BinderHub (&lt;/em&gt;&lt;a href="http://github.com/jupyterhub/binderhub"&gt;&lt;em&gt;github.com/jupyterhub/binderhub&lt;/em&gt;&lt;/a&gt;&lt;em&gt;), repo2docker (&lt;/em&gt;&lt;a href="http://github.com/jupyter/repo2docker"&gt;&lt;em&gt;github.com/jupyter/repo2docker&lt;/em&gt;&lt;/a&gt;&lt;em&gt;), and JupyterHub (&lt;/em&gt;&lt;a href="http://github.com/jupyterhub/jupyterhub"&gt;&lt;em&gt;github.com/jupyterhub/jupyterhub&lt;/em&gt;&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
</content><category term="Binder"/><category term="Kubernetes"/></entry><entry><title>Binder 2.0, a Tech Guide</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2017/binder-2-0-a-tech-guide-2017/" rel="alternate"/><published>2017-11-30T16:01:00+00:00</published><updated>2017-11-30T19:25:00+00:00</updated><author><name>Chris Holdgraf</name></author><id>tag:jasongrout.github.io,2017-11-30:/medium-archive/pelican/posts/2017/binder-2-0-a-tech-guide-2017/</id><summary type="html">&lt;p&gt;Authors: The Binder project is comprised of many individuals within and outside of the core Jupyter team. A list of members that…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/binder-2-0-a-tech-guide-2017/images/001-1_cWQj_YdmY_p14eh628N_Kg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Authors: The Binder project is comprised of many individuals within and outside of the core Jupyter team. A list of members that contributed to this post is at the end of this article.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: this post focuses more on technical changes in the Binder 2.0 reboot. For a post about user-facing features and future plans, see&lt;/em&gt; &lt;a href="https://elifesciences.org/labs/8653a61d"&gt;&lt;em&gt;this eLife blog post&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are undergoing a dramatic increase in the complexity of techniques for analyzing data, doing scientific research, and sharing our work with others. In early 2016, the &lt;a href="https://mybinder.org"&gt;Binder project&lt;/a&gt; was announced, attempting to connect these three components. A &lt;a href="https://elifesciences.org/labs/a7d53a88/toward-publishing-reproducible-computation-with-binder"&gt;blogpost in eLife&lt;/a&gt; described a vision where scientists could specify dependencies along with a collection of Jupyter notebooks. Binder builds a Docker image from these dependencies, and provides a URL where any user in the world can instantly recreate this environment.&lt;/p&gt;
&lt;p&gt;Want to see it in action? Click the button below.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mybinder.org/v2/gh/wildtreetech/explore-open-data/binder20-elife?filepath=bikes-per-week.ipynb"&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/binder-2-0-a-tech-guide-2017/images/002-1_IA00K8fa8FvXedoBBDh2fg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With this post we are proud to announce the next version of Binder. It aims to be more modular, more flexible, more stable, faster, and more extensible than its predecessor. Powering this version of Binder is a collection of tools in the Jupyter ecosystem. Since being released, the Binder project has learned many things about implementing fast, flexible online deployments. In addition, its vision has expanded to include not only Jupyter notebooks, but many other computational workflows. You can access an open beta version of this deployment here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mybinder.org"&gt;mybinder.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can find a list of sample repositories to learn how to create “Binder”-ready repositories here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/binder-examples"&gt;github.com/binder-examples&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can also see what the Binder community has been up to in creating their own repositories by checking the GitHub Binder topic:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://github.com/topics/binder
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Give it a shot, build some repositories, and importantly, tell us what could be improved on our &lt;a href="https://github.com/jupyterhub/binderhub"&gt;GitHub repo&lt;/a&gt;. Below we’ll describe a bit about what’s new.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The new Binder UI. Users input a URL to a git repository (or specify a specific branch/tag/commit). Upon clicking “launch”, you will be directed to a live environment where you can interact with the code." src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/binder-2-0-a-tech-guide-2017/images/003-1_lWcoBaRvNzXxzGPqV_3vew.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The new Binder UI. Users input a URL to a git repository (or specify a specific branch/tag/commit). Upon clicking “launch”, you will be directed to a live environment where you can interact with the code.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="whats-new"&gt;What’s new?&lt;/h2&gt;
&lt;p&gt;First off we’ll describe how the experience will change for users. The short answer is: not much. The goal of Binder is still enabling you to intantly create interactive and shareable repositories. We’ve completely rebuilt the backend of Binder, but we’ve made minimal changes to the front-end user experience.&lt;/p&gt;
&lt;p&gt;The biggest difference you should notice is that Binder is both faster and more stable. You’ll still be able to generate Binder links from a git URL from a single web-page. However, there are a few key differences:&lt;/p&gt;
&lt;h3 id="new-default-environment"&gt;New Default Environment&lt;/h3&gt;
&lt;p&gt;Old versions of Binder were based off of a Docker image that contained a fairly heavy computational environment. The new Binder deployment makes minimal assumptions about what environment you want installed, by default the only thing that will be installed is the Jupyter Notebook and Python 3. This means you’ll need to be more expressive in the dependencies you include in your dependency files. For example, if you want &lt;code&gt;numpy&lt;/code&gt; or &lt;code&gt;matplotlib&lt;/code&gt;, you should specify them in a &lt;code&gt;requirements.txt&lt;/code&gt; or &lt;code&gt;environment.yml&lt;/code&gt; file. Since you’re explicitly listing your requirements it makes reproducing your work more reliable, and allows the Binder infrastructure to change more freely without breaking your repository code.&lt;/p&gt;
&lt;h3 id="new-url-structure"&gt;New URL structure&lt;/h3&gt;
&lt;p&gt;The new URL structure for Binder follows the following convention:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://mybinder.org/v2/gh/&amp;lt;org-name&amp;gt;/&amp;lt;repo-name&amp;gt;/&amp;lt;branch|tag|hash-name&amp;gt;?filepath=&amp;lt;path-to-file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For example, below is the URL for a basic Binder-ready Python 3 repository, it includes basic information about the repository:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://mybinder.org/v2/gh/binder-examples/requirements/master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can also specify parameters that do things like point users to a particular file or initialize a user-interface. For example, the following URL starts JupyterLab once users click the link:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://mybinder.org/v2/gh/binder-examples/jupyterlab/master?urlpath=lab
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In each case, note the &lt;code&gt;gh&lt;/code&gt; at the very beginning — this specifies that the git URL exists on github.com. It is possible to build new URL parsers for other online repositories such as BitBucket, osf.io, or any other provider. We are currently focusing on Git and GitHub, but nothing prevents Binder from being compatible with other kinds of content providers. Shortly before this blog post we added support for arbitrary git URLs to binderhub, so watch this space.&lt;/p&gt;
&lt;h3 id="specify-a-specific-branch-tag-commit"&gt;Specify a specific branch / tag / commit&lt;/h3&gt;
&lt;p&gt;Also notice that in the URL above you can specify a branch, tag, or commit hash for the Binder image. This allows you to ensure that a Binder image will &lt;strong&gt;always&lt;/strong&gt; remain the same (if you specify package versions properly). This is a crucial step for reproducibility and maintaining consistency in how users experience the files in your repository.&lt;/p&gt;
&lt;p&gt;Notice that in the URL above you can specify a commit hash or git tag for the Binder image. This hash is unique to the state of the code at the moment that the commit was made, ensuring that Binder can rebuild the exact same environment any time. Note that if authors don’t want to guarantee the same reproducible environment, they can specify a branch and BinderHub will resolve it to the latest commit hash before building the environment.&lt;/p&gt;
&lt;h3 id="binder-auto-building"&gt;Binder auto-building&lt;/h3&gt;
&lt;p&gt;When a git repository is launched, Binder will now check whether an image has already been built for that repository at the same commit hash. If it has, then Binder will skip the building process and take you straight to a JupyterHub instance that serves this image.&lt;/p&gt;
&lt;p&gt;If the image hasn’t been built, then it will automatically be generated before sending the user to JupyterHub. The only difference will be the amount of time it takes before entering the JupyterHub environment. This means that authors no longer need to explicitly build their Binder images when they update a branch. The next time someone clicks a Binder link, it will happen automatically. If you don’t want this behavior, be sure to point Binder to a specific tag or commit hash, rather than a branch name or tag. For example, here’s a Binder URL that will always point to the same commit hash:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://mybinder.org/v2/gh/wildtreetech/explore-open-data/binder20-elife
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While this URL points to a branch, and will thus be re-built each time a new commit is made to that branch:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://mybinder.org/v2/gh/wildtreetech/explore-open-data/master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="more-options-for-dependency-files"&gt;More options for dependency files&lt;/h3&gt;
&lt;p&gt;Users often want to specify a computational environment that is more complex than a simple list of Python requirements. While this is possible by specifying a Dockerfile, it’s often an overly-complicated solution to this problem. Binder now uses &lt;a href="https://github.com/jupyter/repo2docker"&gt;repo2docker&lt;/a&gt; to build a Docker image from your repository. This makes it possible to specify a more complex environment with text files. For example, you can use an &lt;code&gt;apt.txt&lt;/code&gt; file to install packages with &lt;code&gt;apt-get&lt;/code&gt;, or use a file called &lt;code&gt;postBuild&lt;/code&gt; to define shell commands that are run before generating the Docker image (e.g. for downloading some data or running scripts). See the &lt;a href="https://repo2docker.readthedocs.io/en/latest/samples.html"&gt;repo2docker documentation&lt;/a&gt; for a list of files that are supported with Binder.&lt;/p&gt;
&lt;p&gt;For a selection of examples that show off how to specify dependencies take a look at the example gallery: &lt;a href="https://github.com/binder-examples"&gt;https://github.com/binder-examples&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="more-user-interfaces"&gt;More user interfaces&lt;/h3&gt;
&lt;figure&gt;
&lt;img alt="The JupyterLab interface running on Binder. You can access the JupyterLab demo repository at mybinder.org/v2/gh/binder-examples/jupyterlab/master?urlpath=lab" src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/binder-2-0-a-tech-guide-2017/images/004-1_TW7Gnwl-02cejzgs1nnX2Q.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterLab interface running on Binder. You can access the JupyterLab demo repository at ``mybinder&lt;code&gt;.org/v2/gh/binder-examples/jupyterlab/master?urlpath=lab&lt;/code&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The previous iteration of Binder only supported the classic Jupyter Notebook user interface, while the new deployment will additionally support &lt;a href="https://github.com/binder-examples/dockerfile-rstudio"&gt;RStudio&lt;/a&gt; and &lt;a href="https://github.com/binder-examples/jupyterlab"&gt;JupyterLab&lt;/a&gt;. Because of the extra build configuration files specified above, you can also utilize more tools in the Jupyter widgets ecosystem, such as the &lt;a href="https://github.com/binder-examples/jupyter-rise"&gt;RISE plugin for interactive presentations&lt;/a&gt; or the &lt;a href="https://github.com/oschuett/appmode"&gt;appmode plugin&lt;/a&gt; to generate interactive apps from your repository. We also welcome contributions to add support for other user interfaces.&lt;/p&gt;
&lt;h3 id="more-online-repository-providers"&gt;More online repository providers&lt;/h3&gt;
&lt;p&gt;While GitHub is a fantastic repository of open-source code, it’s not the only repository. The new Binder deployment makes it straightforward to adding support for new sources of code (for example, GitLab, the OSF, or even non-git codebases). Currently GitHub is the only supported source for code, but we welcome contributions enabling support for new sources.&lt;/p&gt;
&lt;p&gt;We’re excited about this next step in Binder’s development, and hopeful that we can build a community around this powerful set of tools. Don’t hesitate to open an issue or pull request on our &lt;a href="https://github.com/jupyterhub/binderhub"&gt;GitHub repository&lt;/a&gt;, or to reach out via &lt;a href="https://gitter.im/jupyterhub/binder"&gt;our Gitter channel&lt;/a&gt;. We look forward to seeing what comes next, and to continue enabling reproducible and open workflows in data science and research.&lt;/p&gt;
&lt;h2 id="for-developers"&gt;For developers&lt;/h2&gt;
&lt;p&gt;The next few sections are meant for developers interested in deploying their own Binder, or for those interested in the technical details behind the new deployment.&lt;/p&gt;
&lt;h3 id="tech-components"&gt;Tech components&lt;/h3&gt;
&lt;p&gt;The three main technical components behind the new Binder backend are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://binderhub.readthedocs.io/"&gt;BinderHub&lt;/a&gt;, currently on display at &lt;a href="https://mybinder.org"&gt;mybinder.org&lt;/a&gt; and contained in the &lt;a href="https://github.com/jupyterhub/binderhub"&gt;binderhub repository&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://repo2docker.readthedocs.io/"&gt;repo2docker&lt;/a&gt;, a tool that converts a code repository into a Docker image with an environment specified via dependency files (e.g., &lt;code&gt;requirements.txt&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jupyterhub.readthedocs.io/en/latest/"&gt;JupyterHub&lt;/a&gt;, which hosts user instances with a server in the cloud. We use a distribution of JupyterHub that runs on top of Kubernetes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more information on the infrastructure behind Binder, &lt;a href="https://binderhub.readthedocs.io/en/latest/"&gt;see the documentation&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A prototype of RStudio running in a Binder. This is currently support with a Dockerfile, and we are working on supporting R build files natively. You can access this repository at:" src="https://jasongrout.github.io/medium-archive/pelican/posts/2017/binder-2-0-a-tech-guide-2017/images/005-1_EgMk1PYMl6ouIP_XQ5G5Fg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A prototype of RStudio running in a Binder. This is currently support with a Dockerfile, and we are working on supporting R build files natively. You can access this repository at: &lt;code&gt;&amp;lt;https://mybinder.org/v2/gh/binder-examples/dockerfile-rstudio/master&amp;gt;&lt;/code&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="kubernetes"&gt;Kubernetes&lt;/h3&gt;
&lt;p&gt;Binder now also heavily relies on &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; for scaling our image building service and the JupyterHub. Kubernetes is massively scalable and has a strong community of developers behind it. Moreover, Kubernetes is cloud-agnostic. It can be run on Google Cloud, Microsoft Azure, and AWS among others, as well as on your own bare metal hardware if needed. Because BinderHub is built to run on top of Kubernetes, you can deploy Binder off of any of these resources as well (see below).&lt;/p&gt;
&lt;h3 id="deploying-your-own-binder-server"&gt;Deploying your own Binder server&lt;/h3&gt;
&lt;p&gt;While mybinder.org will continue to exist as a public service, we hope to see new Binder deployments for many different use cases in the wild. One of our primary goals is to make it easier for users to deploy their own Binder servers. This is relatively straightforward by following the instructions on the &lt;a href="https://binderhub.readthedocs.io/en/latest/"&gt;BinderHub documentation&lt;/a&gt;, which are currently under active development to make ongoing improvements as the Kubernetes technology evolves. We’re continuously updating these steps to make them as clear as possible, so please don’t hesitate to open an issue or a pull request on our &lt;a href="https://github.com/jupyterhub/binderhub"&gt;github repository&lt;/a&gt; and make suggestions.&lt;/p&gt;
&lt;p&gt;We would love to see others deploy their own BinderHub servers, either for their own communities, or as part of a federated public service of BinderHubs.&lt;/p&gt;
&lt;h2 id="future-development"&gt;Future development&lt;/h2&gt;
&lt;p&gt;This is the just the beginning of new features and improvements to Binder. We’re working hard to grow an open-source community around these tools, and we encourage issues, comments, and PRs on the &lt;a href="https://github.com/jupyterhub/binderhub"&gt;BinderHub&lt;/a&gt;, &lt;a href="https://github.com/jupyter/repo2docker"&gt;repo2docker&lt;/a&gt;, and &lt;a href="https://github.com/jupyterhub/jupyterhub"&gt;JupyterHub&lt;/a&gt; repositories. We look forward to growing the Binder ecosystem, and we’re excited to see all of the Binders that people design.&lt;/p&gt;
&lt;h2 id="acknowledgements-alphabetical-order"&gt;Acknowledgements (alphabetical order)&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;C. Titus Brown (UC Davis), Matthias Bussonnier (UC Berkeley), Jessica Forde (UC Berkeley), Brian Granger (Cal Poly), Tim Head (Wild Tree Tech), Chris Holdgraf (UC Berkeley), Andrew Osheroff (Google), Naomi Penfold (eLife Sciences), M Pacer (UC Berkeley), Yuvi Panda (UC Berkeley), Fernando Perez (UC Berkeley), Min Ragan-Kelley (Simula Research Laboratory), and Carol Willing (Cal Poly). The Binder project is currently being funded from a grant from the Moore Foundation.&lt;/em&gt;&lt;/p&gt;
</content><category term="Binder"/><category term="Docker"/><category term="Kubernetes"/><category term="open science"/></entry></feed>