<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Jupyter Blog - Georgiana Dolocan</title><link href="https://jasongrout.github.io/medium-archive/pelican/" rel="alternate"/><link href="https://jasongrout.github.io/medium-archive/pelican/feeds/author-georgiana-dolocan.atom.xml" rel="self"/><id>https://jasongrout.github.io/medium-archive/pelican/</id><updated>2023-06-19T08:02:00+00:00</updated><subtitle>The Project Jupyter blog: news, releases, and community stories, archived from blog.jupyter.org.</subtitle><entry><title>From intern to mentor</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2023/from-intern-to-mentor/" rel="alternate"/><published>2023-06-19T08:02:00+00:00</published><updated>2023-06-19T08:02:00+00:00</updated><author><name>Georgiana Dolocan</name></author><id>tag:jasongrout.github.io,2023-06-19:/medium-archive/pelican/posts/2023/from-intern-to-mentor/</id><summary type="html">&lt;p&gt;Four years ago, Project Jupyter participated for the first time in the Outreachy program. And at the end of last year, during the December…&lt;/p&gt;
</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;Four years ago, Project Jupyter participated for &lt;a href="/posts/2018/outreachy-jupyter-supporting-diversity-in-open/"&gt;the first time in the Outreachy program&lt;/a&gt;. And at the end of last year, during the December round, t&lt;a href="/posts/2022/introducing-jupyterhubs-outreachy-interns-december-2022/"&gt;hree more awesome interns joined the project&lt;/a&gt;. Because I was lucky enough to be part of this program both times, first time as an intern and second time as a mentor, in this post I will share the parts that were the most impactful and contributed the most to my growth as both mentor and engineer. I hope this will inspire other interns, to start their journey, but also other community members into becoming mentors.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;When I first interacted with the Jupyter community, I remember I was impressed by how welcoming everyone was, how well organized they seemed, how promptly questions got answered and how fast code got reviewed. This was especially impressive during the &lt;a href="https://www.outreachy.org/docs/applicant/#make-contributions"&gt;contribution phase&lt;/a&gt; when prospect interns were everywhere at the same time, we were generating crazy amount of work for mentors and the community when asking for guidance and tackling tasks.&lt;/p&gt;
&lt;p&gt;When the internship ended I realized how much I appreciated this process compared to other internships. The contribution phase made me feel very motivated because of the opportunity to work on &lt;strong&gt;real&lt;/strong&gt; tasks, with &lt;strong&gt;impact&lt;/strong&gt; for the entire community.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;All the work traffic, immense quantity of GitHub notifications, emails, questions, etc., were totally opaque to me as an intern, they seemed to just be magically handled by mentors. I now know this seamless interaction is made of some very special ingredients like team work, time commitment and hard work, nothing magic about it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scoping the project, the most challenging part&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I believe scoping the project was the part that I found the most challenging as a first time mentor.&lt;/p&gt;
&lt;p&gt;The plan I had in mind for how to create the project roadmap, was to &lt;strong&gt;define a few tasks&lt;/strong&gt; that were not very tightly scoped, &lt;strong&gt;choose one&lt;/strong&gt; to start with, allocate time for the intern to &lt;strong&gt;research&lt;/strong&gt; about it, have synchronous meetings to &lt;strong&gt;collaboratively refine&lt;/strong&gt; it, then &lt;strong&gt;implement&lt;/strong&gt; it, &lt;strong&gt;review&lt;/strong&gt;, and then &lt;strong&gt;repeat&lt;/strong&gt; for next task. And although this was a good first plan, I failed to recognize when it stopped working and didn’t realize it’s important to pause and adapt the plan.&lt;/p&gt;
&lt;p&gt;It took me some time and guidance from others in the community, to realize that sometimes, &lt;strong&gt;constraints are beneficial&lt;/strong&gt; and allowing complete implementation freedom over a task, can be overwhelming. For finding the appropriate &lt;em&gt;[freedom — constraint]&lt;/em&gt; balance I needed to experimented with different task sizes, until tasks had a less overwhelming learning curve. This fosters and grows confidence and improves time management skills.&lt;/p&gt;
&lt;p&gt;I found this to be particularly tricky because this balance can be hard to achieve when creating a project roadmap. The hidden complexities of a project, existing skills, or any prior experience managing a project from scratch, are hard to know and plan around in the very first iteration.&lt;/p&gt;
&lt;p&gt;Another challenge of being a mentor that is usually hidden is the &lt;strong&gt;context switch penalty&lt;/strong&gt; between mentor time and daily job responsibilities. A mentor needs to fine tune the amount of intern interaction and involvement in the project implementation so that context switches from daily responsibilities are as soft as possible. It’s also critical that a mentor has full support and transparent communication with the daily job management so that work responsibilities don’t spill over into mentoring time, otherwise this can lead to stress and a sub-optimal experience for the intern.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Asking questions publicly, the biggest achievement&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The open source comes with a challenge attached to it by default, which is &lt;strong&gt;being comfortable communicating in the open and asking questions publicly&lt;/strong&gt;. The time and work that needs to go into fostering this skill needs to be taken into account from the very beginning and it’s extremely important to consider it from the project proposal and roadmap definition phase. It will help set the correct project expectations, and expose an otherwise hidden complexity of open source project maintainability.&lt;/p&gt;
&lt;p&gt;This was a challenge that was more difficult to overcome than expected, because in our case it involved, &lt;strong&gt;a first time mentor, a first time intern&lt;/strong&gt;, and a project that required diving into the codebase of lots of other different projects in the ecosystem, so &lt;strong&gt;guidance from the entire community&lt;/strong&gt; and asking questions was crucial.&lt;/p&gt;
&lt;p&gt;My intern, Sheila was very determined and courageous and she received great care and support from the entire community in overcoming this obstacle. She is now a key maintainer &lt;a href="https://github.com/jupyterhub/pytest-jupyterhub"&gt;of the internship project&lt;/a&gt; she worked on, asking and answering questions without issues. Checkout out her many achievements captured in &lt;a href="https://hackmd.io/cvqPq6XVQbaYVndwFvJ0Kw?view"&gt;this list (not complete)&lt;/a&gt; and &lt;a href="https://cfp.jupytercon.com/2023/talk/HNTKXF/"&gt;her presentation&lt;/a&gt; about the Reusable JupyterHub Pytest Plugin at JupyterCon. A recording of her talk should soon be available on &lt;a href="https://www.youtube.com/@JupyterCon"&gt;JupyterCon’s YouTube channel.&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Mentor training, mentor shadowing, co-mentoring, the best allies&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I am extremely grateful to have had the support of the other mentors and the community during theses three mentoring months.&lt;/p&gt;
&lt;p&gt;In particular, I am very grateful for Sarah Gibson, &lt;a href="/posts/2021/czi-awards-three-eoss-grants-to-jupyter-community/"&gt;the Jupyter strategic lead&lt;/a&gt; and our Community Coordinator with Outreachy, for organizing for us to get &lt;strong&gt;mentor training&lt;/strong&gt; beforehand through the &lt;a href="https://openlifesci.org/"&gt;OLS community&lt;/a&gt;. I found that to be very helping and ground setting and it made me feel more empowered.&lt;/p&gt;
&lt;p&gt;I also appreciated and found really useful the &lt;strong&gt;mentor shadowing sessions&lt;/strong&gt; that I did with Sarah and the &lt;strong&gt;demo session&lt;/strong&gt; that Min RK hold with all the interns and mentors. They were both great opportunities for me to observe and learn from the other mentors and get feedback from them.&lt;/p&gt;
&lt;p&gt;Co-mentoring was something that was considered during this round, but because we wanted to select all these great interns we ended up not mentoring in teams. But this appears as a great approach of introducing first-time mentors.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It was all worth it, the takeway&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The JupyterHub project got to improve its documentation, accessibility and testing thanks to this program and to the three amazing interns that worked with us during this round ❤️. In addition, this internship round helped us create &lt;a href="https://jupyterhub-outreachy.readthedocs.io/en/latest/"&gt;a place where people can learn about JupyterHub’s experience with Outreachy&lt;/a&gt; and &lt;a href="https://github.com/jupyterhub/jupyterhub-python-repo-template"&gt;a template repository&lt;/a&gt; to be used for quickly generating other JupyterHub Python sub-repositories that follow the standards of the organization.&lt;/p&gt;
&lt;p&gt;On the personal side now that the internship is over, I can happily say that it was very enlightening and humbling to be on the mentoring side as well. Even if it’s challenging, you get an amazing feeling when you give back and channel all the effort and kindness that shaped you and that you received as a mentee from other people.&lt;/p&gt;
</content><category term="community"/><category term="JupyterHub"/><category term="Outreachy"/></entry><entry><title>Lessons learned from Jupyter’s Contributor in Residence pilot</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2021/lessons-learned-from-jupyters-contributor-in-residence/" rel="alternate"/><published>2021-03-11T20:22:00+00:00</published><updated>2021-03-11T20:22:00+00:00</updated><author><name>Georgiana Dolocan</name></author><id>tag:jasongrout.github.io,2021-03-11:/medium-archive/pelican/posts/2021/lessons-learned-from-jupyters-contributor-in-residence/</id><summary type="html">&lt;p&gt;By Chris Holdgraf and Georgiana Dolocan&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;em&gt;By Georgiana Dolocan and Chris Holdgraf&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Project Jupyter, like most open source communities, often lacks the time and people power to maintain existing projects. Existing maintainers are often overloaded with work, while new volunteer contributions are often driven by the excitement of new feature development. Although on-boarding new maintainers is a sustained long-term team effort, it is something necessary and beneficial not only for the project, but also for existing maintainers and new contributors alike.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;For this reason, we decided to &lt;a href="/posts/2019/the-jupyterhub-and-binder-contributor-in-residence/"&gt;pilot a Contributor in Residence&lt;/a&gt; program that was generously funded for a year through CZI’s &lt;a href="https://chanzuckerberg.com/eoss/"&gt;Essential Open Source Science program&lt;/a&gt;. Last year we ran the first iteration of the JupyterHub Contributor in Residence role. This post is a short report about what we learned, in the hopes that it guides other projects in pursuing similar programs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="tldr"&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;The Contributor in Residence program is a great way to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduce new members into your community&lt;/li&gt;
&lt;li&gt;Create pathways for others to get more experience, and grow in their role and leadership&lt;/li&gt;
&lt;li&gt;Get a lot of work done that is hard to motivate volunteers to do&lt;/li&gt;
&lt;li&gt;Spend time thinking at a “meta” level about how to improve dynamics in the community&lt;/li&gt;
&lt;li&gt;Have a paid opportunity to support individuals who can’t contribute via volunteerism alone&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, doing this well requires planning ahead of time and attention throughout the program. It is crucial that you develop a plan and pathways for integrating the CIR into your community, and ensuring that they have the right perspective to support the community. If you do this, the CIR program can be a fantastic win-win situation for everyone involved.&lt;/p&gt;
&lt;h2 id="what-is-the-contributor-in-residence"&gt;What is the Contributor in Residence?&lt;/h2&gt;
&lt;p&gt;The Contributor in Residence (CIR) carries out a variety of technical and community-focused actions, looking for opportunities to keep momentum moving forward in conversations, improving infrastructure to minimize human toil and streamline information, and making improvements to the codebase that are focused more around sustainability, stability, and understandability.&lt;/p&gt;
&lt;p&gt;For more information about our CIR program, check out these blog posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/posts/2019/the-jupyterhub-and-binder-contributor-in-residence/"&gt;CIR announcement post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/posts/2020/cir-report-i/"&gt;CIR update post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=n07NDPbwdk8&amp;amp;t=1620s"&gt;Here’s a video of Georgiana talking about her experience&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="The JupyterHub welcome bot image, hand-drawn by our first Contributor in Residence, Georgiana" src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/lessons-learned-from-jupyters-contributor-in-residence/images/001-0_6hQJEAS34fJRY65r.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterHub welcome bot image, hand-drawn by our first Contributor in Residence, Georgiana&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="how-management-and-planning-worked"&gt;How management and planning worked&lt;/h2&gt;
&lt;p&gt;We didn’t define explicit “metrics-based” outcomes for this Contributor in Residence pilot, as we were not sure the behaviors that would be most beneficial in the long-run. Instead, Georgiana kept track of the activities that she worked on throughout the year, and reflected with us often in identifying challenges to overcome, and opportunities to improve the work she was doing.&lt;/p&gt;
&lt;p&gt;In practice, Georgiana did not have a sole formal ongoing mentor providing her regular guidance throughout the project. She received mentorship from a variety of JupyterHub Team members across the repositories, and via participation in issues in GitHub (more on that later).&lt;/p&gt;
&lt;p&gt;Georgiana kept track of her actions &lt;a href="https://github.com/users/GeorgianaElena/projects/1"&gt;at this GitHub project.&lt;/a&gt; This contains a collection of issues, to-do items, and pull-requests throughout the JupyterHub community, and is a public record of much of the work that she focused on. While we scoped the CIR to cover all of the JupyterHub repositories, these efforts had a general focus on &lt;a href="https://github.com/jupyterhub/the-littlest-jupyterhub"&gt;The Littlest JupyterHub&lt;/a&gt;, where she is now the primary maintainer and community liaison for the project. In addition to these development-focused efforts, Georgiana also spent a lot of time improving infrastructure and team processes at the JupyterHub-wide level, generally via the &lt;a href="https://github.com/jupyterhub/team-compass"&gt;JupyterHub Team Compass&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="tips-for-running-a-cir-program"&gt;Tips for running a CIR program&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The following are a few best-practices that we picked up during our pilot.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="define-an-explicit-work-plan-and-system-for-managing-tasks"&gt;Define an explicit work plan and system for managing tasks&lt;/h3&gt;
&lt;p&gt;The biggest challenge Georgiana faced was in identifying specific projects to work on, and working through the ambiguity of a position that explicitly had no single clear workstream. To get around this, Georgiana sought out guidance and advice from others in the community, and over time gained an understanding of ways that she could contribute. This will be a challenge for any Contributor in Residence moving forward, and we will need to think of new ways to support this role with concrete suggestions. Georgiana wrote a bit about this experience &lt;a href="/posts/2020/cir-report-i/"&gt;in her CIR update blog post&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="dedicate-management-and-mentorship"&gt;Dedicate management and mentorship&lt;/h3&gt;
&lt;p&gt;A related challenge was in ensuring that the CIR felt like they had a clear idea of their expectations, to-do items, and progress. In future iterations, we would like to dedicate more resources towards providing mentorship and management of the person. This role shouldn’t be a “task giver,” but rather someone to help guide, triage, and prioritize for the benefit of the community. They should have regular touch-points with the CIR to make sure they are supported in their role.&lt;/p&gt;
&lt;h3 id="have-an-onboarding-session-to-help-them-navigate-your-project"&gt;Have an onboarding session to help them navigate your project&lt;/h3&gt;
&lt;p&gt;Regardless of ongoing mentorship, you should definitely have an onboarding session. Many open source communities have multiple projects, varying stages of contributor documentation, different spaces for conversation and interaction. Moreover, the technical infrastructure may have underlying architectures and organization that is hard to learn on your own. Have a core maintainer (or the mentor if you’re using one) go over your technology’s structure and layout, and double-check the things the CIR is unsure of, and introduce them to various discussions and action points to learn from. This may require multiple meetings in the first few weeks/months.&lt;/p&gt;
&lt;h3 id="assess-your-current-strategy-every-3-months-and-adjust-based-on-current-needs"&gt;Assess your current strategy every 3 months and adjust based on current needs&lt;/h3&gt;
&lt;p&gt;Choose a time interval when you revisit your plan. Project needs, community dynamics, and time availability will change over time, so take the time to think about what parts of the plan need to be modified to fit the situation at hand. An option could be bringing this up during team meetings to brainstorm ideas and get feedback, then write it down to put everything in order and make it real. Consider writing 3-month blog posts of your progress and status — these become public records of the experience gained from the program, and are good opportunities to reflect on how things are going.&lt;/p&gt;
&lt;h3 id="actively-invite-them-into-the-community"&gt;Actively invite them into the community&lt;/h3&gt;
&lt;p&gt;Remember that most open source communities are just that — communities. Take time to make sure others in the community know who the CIR is, invite them to participate in community conversations, welcome them in gitter/slack/issues/etc. Anything you can do to make them feel welcome is great. Make sure that you keep doing this over time, not just once at the beginning of their fellowship. When someone feels that they are welcome and a part of a community, they will be much more comfortable at navigating how to support it themselves.&lt;/p&gt;
&lt;h3 id="tailor-the-role-to-fit-the-cir-as-a-person-too"&gt;Tailor the role to fit the CIR as a person too&lt;/h3&gt;
&lt;p&gt;The CIR responsibilities are usually already sketched up before actually having a person to fill the role. Having an overall plan is an awesome idea and a very useful program compass. However, once the CIR is identified, it is important to re-address the overall focus and goals of the role to ensure that it aligns with the interests and skillsets of the incoming CIR. This includes things like familiarity with the project, future career directions for the CIR, and working styles for people involved.&lt;/p&gt;
&lt;h3 id="start-slower"&gt;Start slower&lt;/h3&gt;
&lt;p&gt;Jumping directly into a new project with a lot of complexity and many sub-projects is not sustainable. In our initial plan, we decided to track about 10 main repositories in the first three months of the CIR pilot. This was not sustainable, and led to an overwhelming feeling because of the constant influx of new issues, questions, etc. Especially for someone new to the community and their new role, this led to a feeling of “I’m not learning fast enough,” and difficulty concentrating on the plan. So please, start slow, take the time to acclimate to the project and go repository-by-repository.&lt;/p&gt;
&lt;h3 id="remember-that-knowing-everything-was-never-part-of-the-role"&gt;Remember that knowing everything was never part of the role&lt;/h3&gt;
&lt;p&gt;Being a CIR for a complex project can be very overwhelming. There may be different sub-projects, technology stacks, and team processes across a community. It is crucial to consider the CIR program as a two-way street — it is primarily a learning experience and a chance to grow for the CIR, as well as an opportunity for the project to get some much-needed assistance. The CIR &lt;strong&gt;should not be expected to know or do everything&lt;/strong&gt; either at the beginning or the end of their tenure — instead, celebrate the process and the learning that has come from it.&lt;/p&gt;
&lt;h2 id="ideas-for-things-the-cir-can-work-on"&gt;Ideas for things the CIR can work on&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Here are a few things that we found particularly useful for the CIR’s workstream, that will likely be portable across other communities as well.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="identify-automation-and-standardization-action-points"&gt;Identify automation and standardization action points&lt;/h3&gt;
&lt;p&gt;Observe whether a repetitive task could be performed by an automated system like a bot or a CI system, as this has the potential to ease the workload for maintainers.&lt;/p&gt;
&lt;p&gt;For example, the JupyterHub GitHub org has about 60 repositories. Some of them had issue and pull requests templates, but most of them didn’t. Some had instructions of how to make a new release of the project, others didn’t. Some had their instructions written in a &lt;em&gt;README&lt;/em&gt; and others had documentation, etc.&lt;/p&gt;
&lt;p&gt;When the CIR project took off, the JupyterHub and Binder team already started the quest of automating and standardizing its sub-projects. The CIR’s job was to help the other team members propagate the changes (bots setup, templates, badges, docs) to as many repositories as possible.&lt;/p&gt;
&lt;h3 id="research-and-discover-best-practices-from-other-communities"&gt;Research and discover best-practices from other communities&lt;/h3&gt;
&lt;p&gt;CIRs can also act as helpful eyes and ears to watch other communities and understand the practices that they adopt. Many practices are useful across projects, and a person serving in this “meta” role is in a good position to think at a high level about opportunities.&lt;/p&gt;
&lt;p&gt;For example — a simple “thank you” to a contributor can boost their experience a lot, especially when it is their first time contributing to a project. GitHub has a mechanism of letting you know when someone opens an issue or a PR to a project for the first time, but that little notification can be missed when under a huge load of work. For this, there is “the welcome bot” that can be set up to express the community’s gratitude towards their first time contributors.&lt;/p&gt;
&lt;p&gt;Our CIR noticed that “&lt;a href="https://the-turing-way.netlify.app/welcome"&gt;The Turing Way&lt;/a&gt;” — an open source community-driven guide to reproducible, ethical, inclusive and collaborative data science — made excellent use of GitHub’s welcome bot, including illustrations to make the message even more pleasant and celebratory. Georgiana was inspired by this, which led to adding welcome bots across the JupyterHub repository (including our own hand-drawn images!). Every time a contributor reacts with a ❤ to the bot’s message reinforces the feeling that the bot has its desired, positive effect.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Welcome images that Georgiana drew for the “welcome bots” that she deployed across the JupyterHub repositories." src="https://jasongrout.github.io/medium-archive/pelican/posts/2021/lessons-learned-from-jupyters-contributor-in-residence/images/002-0_WUb7phui0cNKOuL8.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Welcome images that Georgiana drew for the “welcome bots” that she deployed across the JupyterHub repositories.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="spend-time-on-fixing-bugs-and-improving-testing-infrastructure"&gt;Spend time on fixing bugs and improving testing infrastructure&lt;/h3&gt;
&lt;p&gt;Having a working testing infrastructure helps maintainers and contributors alike. Various updates to the underlying infrastructure of the CI system, or even something as simple as a dependency version bump, can break it. So keeping an eye on the health of the testing infrastructure is something that should concern a CIR. This is particularly useful as the world of “maintenance automation” changes very rapidly, with new frameworks, plugins, and standards. Having a pair of eyes constantly thinking about how to improve this process is very helpful.&lt;/p&gt;
&lt;h3 id="share-maintainer-knowledge-by-improving-the-docs"&gt;Share maintainer knowledge by improving the docs&lt;/h3&gt;
&lt;p&gt;Having just a handful of people knowing how to to release a new version of a project is not scalable and puts an enormous pressure on that group. Instead, each project should have public instructions on how to do this, so that other contributors that have the permissions can cut a new project release.&lt;/p&gt;
&lt;p&gt;The process of creating &lt;em&gt;RELEASE.md&lt;/em&gt; files with these instructions for JupyterHub sub-projects, just like the standardization process, had already been started inside the JupyterHub org by the team members before the CIR started. The CIR’s job was to extend this idea to as many sub-projects as possible. This standardization and improvement quest continues to move forward thanks to the CIR and to Erik’s and Simon’s coordination efforts!&lt;/p&gt;
&lt;p&gt;More generally — the CIR is often someone relatively new to a project, which makes them a valuable perspective to understand where team documentation is unclear to newcomers. Use the fresh eyes of the CIR to understand how to make the project more welcoming and easy to navigate, and it will clear a pathway for more to join the project in the future.&lt;/p&gt;
&lt;h2 id="what-we-still-havent-figured-out"&gt;What we still haven’t figured out&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;While we learned a lot during this pilot phase, there are a few things we still haven’t figured out.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="how-to-define-a-pipeline-for-new-cirs"&gt;How to define a pipeline for new CIRs&lt;/h3&gt;
&lt;p&gt;The tenure of a CIR seems like it will be relatively short — maybe one to two years on average. This means that we need a pipeline of new individuals that are ready to learn and take on this role once a previous CIR moves on. Being effective as a CIR was only possible for someone with some context for the JupyterHub repositories and team processes, and we likely would not have had success hiring someone on a one-year contract who had never worked in the JupyterHub community before. In future iterations we will need a reliable pipeline of newcomers to the project to potentially serve as CIRs. Programs like Outreachy and Google Summer of Code are excellent sources of future CIRs, but we need to think about the “pipeline” for gracefully using them to power the CIR project.&lt;/p&gt;
&lt;h3 id="find-mentorship-that-isnt-nights-and-weekends"&gt;Find mentorship that isn’t “nights and weekends”&lt;/h3&gt;
&lt;p&gt;While we may be able to find funding for mentorship and management, many people in the JupyterHub community already had full-time jobs. Having funding to pay for a part of someone’s time is helpful, but this is only possible if you can actually buy out part of somebody’s time (often not possible in certain careers and roles). It may be possible to spend extra time on mentorship in the evenings and weekends, but a sustainable model for this program will require somebody dedicating part of their “FTE time” on mentorship. We need to identify certain kinds of roles / individuals that have this flexibility in their work-load, and bake it into the strategy of the program.&lt;/p&gt;
&lt;h3 id="define-a-funding-mechanism-for-cirs"&gt;Define a funding mechanism for CIRs&lt;/h3&gt;
&lt;p&gt;Finally, this CIR pilot was funded by a one-year grant from CZI. In future iterations we will need to have a strategy for funding this position in a reliable manner (or at least, in a repeatable manner). To make this sustainable, we must define a pattern to follow and require resources to do a good job. This will both reduce the amount of effort needed to plan a new round for the CIR, and will make it easier for other organizations to understand how their financial contributions could help fund another round of the program. Perhaps this can be an ongoing fundraising effort, similar to how other programs have “target funding levels” in their annual giving strategy, or perhaps it can be a coordinated effort across projects to join resources together for these positions. Either way, it will be important to have reliable funding to ensure that the CIR program isn’t in a constant state of sputtering and jumpstarting.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We hope that this post was an informative and useful set of lessons-learned from the JupyterHub team. If you’ve got any suggestions, comments, or questions for us, we’d love to chat. Feel free to open up an issue in &lt;a href="http://discourse.jupyter.org"&gt;the Jupyter Community Forum&lt;/a&gt;! We look forward to continuing this experiment, and hope to see other communities experimenting with the same model in the future.&lt;/p&gt;
&lt;/blockquote&gt;
</content><category term="community"/><category term="diversity"/></entry><entry><title>The Jupyter Contributor In Residence, update 1</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2020/cir-report-i/" rel="alternate"/><published>2020-05-07T15:22:00+00:00</published><updated>2020-05-07T15:22:00+00:00</updated><author><name>Georgiana Dolocan</name></author><id>tag:jasongrout.github.io,2020-05-07:/medium-archive/pelican/posts/2020/cir-report-i/</id><summary type="html">&lt;p&gt;JupyterHub and Binder Contributor in Residence. The first keepalive message.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;em&gt;This year Jupyter was awarded a one-year “&lt;/em&gt;&lt;a href="https://chanzuckerberg.com/eoss/"&gt;&lt;em&gt;Essential Open Source Software for Science&lt;/em&gt;&lt;/a&gt;&lt;em&gt;” grant from the&lt;/em&gt; &lt;a href="https://chanzuckerberg.com/"&gt;&lt;em&gt;Chan Zuckerberg Initiative&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, which we are using to bring on our first “Contributor in Residence” (many thanks, CZI&lt;/em&gt; ❤&lt;em&gt;). This is a short report back from Jupyter’s first “&lt;/em&gt;&lt;a href="/posts/2019/the-jupyterhub-and-binder-contributor-in-residence/"&gt;&lt;em&gt;Contributor in Residence&lt;/em&gt;&lt;/a&gt;”, &lt;a href="https://github.com/GeorgianaElena"&gt;&lt;em&gt;Georgiana Dolocan&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. We are now about one third of the way through her tenure as CIR. Editor’s note: Georgiana has also made all of her own GIFs, because she’s just awesome like that ;-)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/cir-report-i/images/001-1_vCYZLSCYhI4XGm8pZG-okw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;h2 id="the-jupyterhub-and-binder-contributor-in-residence-the-first-keepalive-message"&gt;The JupyterHub and Binder Contributor in Residence. The first &lt;a href="https://en.wikipedia.org/wiki/Keepalive"&gt;keepalive message&lt;/a&gt;.&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;At the end of last year, I found out that the &lt;a href="/posts/2019/the-jupyterhub-and-binder-contributor-in-residence/"&gt;CZI grant&lt;/a&gt; (so nicely put together by Chris Holdgraf), was accepted. I was very happy to have gotten the chance to continue working alongside an amazing community that I grew very fond of from day one that I started contributing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="plan-10"&gt;Plan 1.0&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/cir-report-i/images/002-1__GNG9croNBQjsCLGO-riNA.mp4" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Being the first project of its kind, we had millions of ideas about what the Contributor in Residence (CIR) project should be about. We discussed and converged towards a common plan, then we decided to continuously iterate once we got some real life feedback.&lt;/p&gt;
&lt;p&gt;See &lt;a href="https://github.com/jupyterhub/team-compass/issues/237"&gt;this GitHub issue&lt;/a&gt; with the end result of the brainstorming, and with various milestones set in place. In short, the purpose of the CIR is to work on the little day-to-day tasks that occur across a project (respond to questions, review PRs, fix bugs, write documentation, maintain infrastructure), nothing fancy, no big projects.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="the-biggest-little-achievements"&gt;The biggest little achievements&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Among the little day-to-day tasks, there are a few achievements that are more noticeable and worthwhile to mention, that will potentially have a bigger impact than others.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="the-first-blog-post-about-the-littlest-jupyterhub-is-out"&gt;🚩 The first blog post about The-Littlest-JupyterHub is out&lt;/h3&gt;
&lt;p&gt;&lt;a href="/posts/2020/the-superheros-and-the-magic-wand/"&gt;&lt;em&gt;The superheroes and the magic wand&lt;/em&gt;&lt;/a&gt; is the first blog post about TLJH on the Jupyter Blog. It first started as a technical blog post but while writing and constantly relating to TLJH as having superpowers to explain how it works, it turned rapidly into a superhero story.&lt;/p&gt;
&lt;p&gt;TLJH is an important project in the Jupyter ecosystem and one that I care about a lot, so stay tuned as there are more blog posts to come about it, and although technical this time, I won’t restrain myself from talking about its superpowers.&lt;/p&gt;
&lt;h3 id="the-tljh-ci-tests-were-refactored-and-an-upgrade-test-was-added"&gt;🚩 The TLJH CI tests were refactored and an upgrade test was added&lt;/h3&gt;
&lt;p&gt;Are you familiar with that feeling when a pull request looks OK, it passes all tests and all the bots are happy, so you hit that merge button? Yet, soon after, the unexpected happens and bug reports start showing up. 🙈&lt;/p&gt;
&lt;p&gt;Even though you manage to find the issue and solve it, one question remains: “Why did the checks pass?” The answer isn’t easy to hear: “The tests need to be improved”.&lt;/p&gt;
&lt;p&gt;TLJH operates on a “rolling release” model, where people just install from master, so it’s very important to have strong tests. However, our issue wasn’t exactly with the tests themselves, but rather our &lt;a href="https://github.com/jupyterhub/the-littlest-jupyterhub/issues/503"&gt;CI didn’t match the production installation workflow&lt;/a&gt;, and that small difference between the workflows left TLJH in an uninstallable state. Merging that PR in the first place along with finding the divergence point was the key to solve the problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bonus point&lt;/strong&gt;: whenever someone wants to upgrade TLJH, they do it by running the installer again. Thus, the changes we’re adding by merging a PR, don’t just need to pass the tests, but also they must not break the upgrade process. So, we also added an &lt;a href="https://github.com/jupyterhub/the-littlest-jupyterhub/pull/511"&gt;upgrade test to our CI&lt;/a&gt; to solve any potential future upgrade problems.&lt;/p&gt;
&lt;h3 id="three-repositories-in-the-jupyterhub-organization-are-now-being-watched-by-a-support-bot"&gt;🚩 Three repositories in the JupyterHub organization are now being watched by a support bot&lt;/h3&gt;
&lt;p&gt;The Jupyter community currently uses GitHub, &lt;a href="https://gitter.im/jupyterhub/jupyterhub"&gt;Gitter&lt;/a&gt; and &lt;a href="https://discourse.jupyter.org/"&gt;Discourse&lt;/a&gt; (the newest of them) to connect to one another. Having three communication channels might be confusing if there isn’t any clear distinction between them in terms of their scope. So we needed to find a way to organize our discussion to make the contributing experience better for everyone (users, core developers, and everyone in between).&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://discourse.jupyter.org"&gt;Discourse forum&lt;/a&gt; was already the place where most of our general discussions happened. So why not make this place even more popular and encourage everybody to share their ideas and questions there? This way, the forum becomes the place where we can help and inspire each-other, and GitHub issues are where we talk about cool new features, find bugs, and figure out how to solve the issues.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/apps/support"&gt;support bot&lt;/a&gt; will help spread the word about the forum and will make the transition easier. Currently, it is plugged into the &lt;a href="https://github.com/jupyterhub/jupyterhub"&gt;jupyterhub&lt;/a&gt;, &lt;a href="https://github.com/jupyterhub/binderhub"&gt;binderhub&lt;/a&gt; and &lt;a href="https://github.com/jupyterhub/the-littlest-jupyterhub"&gt;tljh&lt;/a&gt; repositories and will act each time the “support” label is added to a GitHub issue that should be on Discourse.&lt;/p&gt;
&lt;p&gt;We kindly encourage everybody to use Discourse to start or participate in awesome discussions or ask questions of any kind. A great place to start is the &lt;a href="https://discourse.jupyter.org/t/introduce-yourself/17/131"&gt;&lt;em&gt;Introduce yourself&lt;/em&gt; thread&lt;/a&gt; where you can just stop by and say “Hi”.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="struggles-and-solutions"&gt;Struggles and solutions&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Working on little tasks sounds simpler and easier than starting a big, complex project from scratch. Well, this is not entirely true… Those small tasks are happening around big projects that are used by a lot of people and are constantly evolving. So, even a small, not very complicated task, can be hard when you’re still figuring out the “hows” and “wheres” of a project.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/cir-report-i/images/003-1_qaJ2OXcIQc9qeHDhH4ZUyw.mp4" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;h3 id="struggle-distributing-focus-across-multiple-repositories-and-issues"&gt;Struggle: distributing focus across multiple repositories and issues&lt;/h3&gt;
&lt;p&gt;When working on a bigger project, I used to switch between tasks as a means to unwind when running out of ideas and things seemed impossible. I guess one could call this multitasking. However, switching between tasks of different projects that you know little about is challenging enough to cause stress, resuscitate that impostor syndrome, and ultimately turn into burnout.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Although I don’t have a solution to this and I’m still having troubles mastering this skill, I find inspiration and hope among the people in the Jupyter community. Even if maintaining lots of projects at once, they manage to successfully juggle between tasks, sometimes even when this isn’t their main job, so they deserve a huge shout out ❤️&lt;/p&gt;
&lt;h3 id="struggle-keeping-track-of-little-things"&gt;Struggle: keeping track of little things&lt;/h3&gt;
&lt;p&gt;The difference between working on a big project and solving small tasks here and there (besides the obvious size distinction) is that solving smaller tasks makes you prone to loosing a sense of progress. Though not a project in the traditional way, the CIR is a concept that would be worth extending if successful, so evaluating its progress is a must and can help determine and improve those weak points — and why not — even point out when it’s time to stop. But keeping track of little things is tricky.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: GitHub issues, comments or PRs can automatically be retrieved through GitHub’s API (Chris Holdgraf has a great tool for this called &lt;a href="https://github.com/choldgraf/github-activity"&gt;github-activity&lt;/a&gt;). However, to get a sense of accomplishment and progress at the end of the day, I tried to keep my own list of todos and tasks done. I experimented with two approaches in this sense: keeping a HackMD “journal” and creating a &lt;a href="https://github.com/users/GeorgianaElena/projects/1"&gt;GitHub project&lt;/a&gt;. After these three months I think I like the GitHub project better because it allows me to keep a todo list with small enhancements I’d like to work when that notification bell doesn’t ring that often and it’s less copy and pasting links.&lt;/p&gt;
&lt;h3 id="struggle-getting-out-of-the-comfort-zone"&gt;Struggle: getting out of the comfort zone&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/cir-report-i/images/004-1_7IYmviNQrZQtsDBcx95-9Q.mp4" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Implementing that cool new feature or solving that annoying bug when feeling adventurous are part of the fun of software development. However, being a CIR is more than writing code. Things like writing blog posts and reviewing PRs are core responsibilities as well. But these are all new territory, so much that, I think up until last year I could count on the fingers of one hand the number of blog posts I had written or the number of PRs I had reviewed. So, the only thing left to say is “Hello new challenges! Farewell comfort zone 👋”.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Accept the challenge and practice every day until things don’t feel that scary anymore. Patience is key.&lt;/p&gt;
&lt;h2 id="plan-20"&gt;Plan 2.0&lt;/h2&gt;
&lt;p&gt;Version 1 of the plan was solid enough not to have to modify it completely.&lt;br&gt;
So, things like tracking down the bugs and failing tests won’t be halted.&lt;br&gt;
Instead, during these next two months, the plan will only suffer some little focus-related adjustments.&lt;/p&gt;
&lt;p&gt;Specifically, I want to focus more on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Getting more familiar with some of the repositories that didn’t get enough attention during the first phase of the project (&lt;a href="http://github.com/jupyterhub/zero-to-jupyterhub-k8s"&gt;zero-to-jupyterhub-k8s&lt;/a&gt;, &lt;a href="http://github.com/jupyterhub/jupyterhub-deploy-docker"&gt;jupyterhub-deploy-docker&lt;/a&gt;, &lt;a href="http://github.com/jupyterhub/binderhub"&gt;binderhub&lt;/a&gt;, &lt;a href="http://github.com/jupyterhub/dockerspawner"&gt;dockerspawner&lt;/a&gt;, &lt;a href="http://github.com/jupyterhub/kubespawner"&gt;kubespawner&lt;/a&gt;, &lt;a href="http://github.com/jupyter/repo2docker"&gt;repo2docker&lt;/a&gt;), potentially improving the documentation along the way. No more dipping the toes in the water, just dive in 🌊.&lt;/li&gt;
&lt;li&gt;Writing more blog posts about the superpowers of TLJH.&lt;/li&gt;
&lt;li&gt;Have more bots 🤖 helping the community.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the process, I hope I can check the boxes for some of the items on my “learn and improve” wish-list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;technical writing&lt;/li&gt;
&lt;li&gt;Kubernetes&lt;/li&gt;
&lt;li&gt;UI/UX&lt;/li&gt;
&lt;li&gt;courage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stay tuned, because the next blog post about the JupyterHub and Binder Contributor in Residence adventures should be out in two months time.&lt;/p&gt;
</content><category term="community"/><category term="Outreachy"/></entry><entry><title>The superheroes and the magic wand</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2020/the-superheros-and-the-magic-wand/" rel="alternate"/><published>2020-03-19T18:23:00+00:00</published><updated>2020-03-19T18:26:00+00:00</updated><author><name>Georgiana Dolocan</name></author><id>tag:jasongrout.github.io,2020-03-19:/medium-archive/pelican/posts/2020/the-superheros-and-the-magic-wand/</id><summary type="html">&lt;p&gt;In a place far, far away, on a planet called Jupyter, magic happens every day. This land is special because it’s full of magical tools…&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/the-superheros-and-the-magic-wand/images/001-1_v9JBClFvN4V-YZOQgwNxig.mp4" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is the first of a series of posts describing tools in the JupyterHub ecosystem, written by our wonderful &lt;em&gt;Contributor in Residence&lt;/em&gt;, Georgiana. For our first post, we’ll share some lore of JupyterHub, and tell you a story of how it all began…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In a place far, far away, on a planet called Jupyter, magic happens every day. This land is special because it’s full of magical tools with all kind of powers, devoted to one common purpose: to help people. Everyone sympathizing with this goal either advocates, uses, or cares for these tools. So, in the blink of an eye, these people with sometimes nothing else in common than the same drive to help others, gathered together and formed a community.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This special group is known in the galaxy as “&lt;em&gt;&lt;strong&gt;&lt;/em&gt;The Jovyans&lt;/strong&gt;&lt;/em&gt;*” and new recruits join every day.* 🚀&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;
&lt;img alt="This image was created by Scriberia for The Turing Way community and is used under a CC-BY licence. Zenodo record." src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/the-superheros-and-the-magic-wand/images/002-1_lz2yH1jyAlILFF9hZNtFPg.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;This image was created by &lt;a href="http://www.scriberia.co.uk/"&gt;Scriberia&lt;/a&gt; for &lt;a href="https://github.com/alan-turing-institute/the-turing-way"&gt;&lt;strong&gt;The Turing Way&lt;/strong&gt;&lt;/a&gt; community and is used under a CC-BY licence. &lt;a href="https://zenodo.org/record/3695300"&gt;Zenodo record&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;But somebody needed to take care of these magical tools. So, the first Jovyans decided that from then on, they will become tool-keepers. Because their greatest responsibility was to teach new Jovyans how to use the magic, shortly after, they created a set of guiding laws. Some call this &lt;em&gt;“the&lt;/em&gt; &lt;em&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/em&gt;”.&lt;/p&gt;
&lt;h2 id="the-magic-wand"&gt;The magic wand&lt;/h2&gt;
&lt;p&gt;One greatly cherished tool on planet Jupyter is the magical wand. This wand’s very special power is to help people work together as a team and find solutions to important problems.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The wand is called “&lt;em&gt;&lt;strong&gt;&lt;/em&gt;JupyterHub&lt;/strong&gt;&lt;/em&gt;”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/the-superheros-and-the-magic-wand/images/003-1_3nDwvUQiUfa54OsDPqKNag.mp4" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;But the wand is of vast complexity and because of this, so are the guiding laws that control it.&lt;/p&gt;
&lt;p&gt;As a consequence, people trying to benefit from the magic of JupyterHub, spent a lot of time reading and understanding the instructions.&lt;/p&gt;
&lt;h2 id="the-superheros"&gt;The superheros&lt;/h2&gt;
&lt;p&gt;The tool-keepers noticed that most of the people coming to planet Jupyter to become Jovyans were from a big city in the cloud 🌤 called &lt;em&gt;Kubernetes&lt;/em&gt;. So they gathered together and debated what is the best way to help the people of Kubernetes.&lt;/p&gt;
&lt;p&gt;After 3 days and 3 nights of intense discussions (also lots of pizza breaks of course) they decided that one of them needed to get special training, rent a house in Kubernetes and teach the people there the wonders of the JupyterHub magic wand.&lt;/p&gt;
&lt;p&gt;The Chosen One gained the people’s trust, and it got better and better at anticipating and understanding their needs. So the locals started seeing it as a superhero and they even gave it a name, “&lt;strong&gt;Z2JH&lt;/strong&gt;”. 👓&lt;/p&gt;
&lt;p&gt;The news of these events started to spread far and wide, and people living in little towns outside of Kubernetes felt that they deserved the support of a superhero too. They also had great ideas and little time and needed to use the wand’s magic to do good.&lt;/p&gt;
&lt;p&gt;The tool-keepers were inspired by the magnificent accomplishments of these little towns, taking place even without a superhero around. So the littlest of them all, volunteered to go into superhero training to help the people of the little towns do good, faster. Though it was little, in no time, it grew to become the helper these small groups needed.&lt;/p&gt;
&lt;p&gt;The residents called it “&lt;strong&gt;The Littlest JupyterHub” or “TLJH”&lt;/strong&gt; because of its stature. But everybody knew that its stature didn’t reflect its enormous tenacity, speed and ability to do great things. This ended up inspiring people all over to believe that not all superheros wear capes, nor do they need to know how to fly in the cloud to be cool.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2020/the-superheros-and-the-magic-wand/images/004-1_egrzbBcwyaxm7-793O7uiQ.mp4" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nowadays, people from all over join their forces and help the superheros learn new skills. Thanks to them, TLJH and Z2JH get stronger and better and have more special powers than they had when first created by the tool-keepers. Join them, become a Jovyan! ツ&lt;/p&gt;
&lt;/blockquote&gt;
</content><category term="JupyterHub"/><category term="Kubernetes"/></entry><entry><title>Introducing TraefikProxy — a scalable and highly available proxy for JupyterHub</title><link href="https://jasongrout.github.io/medium-archive/pelican/posts/2019/introducing-traefikproxy-a-new-jupyterhub-proxy-based/" rel="alternate"/><published>2019-03-06T11:58:00+00:00</published><updated>2019-03-06T11:58:00+00:00</updated><author><name>Georgiana Dolocan</name></author><id>tag:jasongrout.github.io,2019-03-06:/medium-archive/pelican/posts/2019/introducing-traefikproxy-a-new-jupyterhub-proxy-based/</id><summary type="html">&lt;p&gt;Removing the single point of failure from your JupyterHub infrastructure with traefik, etcd and Outreachy&lt;/p&gt;
</summary><content type="html">&lt;p&gt;In the JupyterHub context, the proxy is the unit in charge of directing the user requests to their notebook servers.&lt;/p&gt;
&lt;p&gt;The proxy manages a list of &lt;strong&gt;[user : notebook]&lt;/strong&gt; mappings (the proxy routing table) in order to decide which request is sent where. The routing table must be continuously updated as users start and stop their servers without disrupting the requests being processed. The following drawing illustrates the proxy functionality in a JupyterHub deployment.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/introducing-traefikproxy-a-new-jupyterhub-proxy-based/images/001-1_cy9fESaJhd0iDhH2v-LySQ.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Why the need for a new proxy?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Currently, the &lt;strong&gt;default&lt;/strong&gt; proxy implementation for JupyterHub is &lt;a href="https://github.com/jupyterhub/configurable-http-proxy"&gt;&lt;em&gt;configurable-http-proxy&lt;/em&gt;&lt;/a&gt; &lt;em&gt;(CHP)&lt;/em&gt;, which is a single-process nodejs proxy, that stores the routing table in-memory. &lt;em&gt;CHP&lt;/em&gt; is easy to install and run, and thus in most of the cases it’s a fine option. However, because you can only run a single copy of the proxy at a time, it has its limitations when used in dynamic, large scale systems.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;What makes this new proxy special?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;JupyterHub 0.8.&lt;/strong&gt; opened the way towards allowing users to &lt;a href="https://jupyterhub.readthedocs.io/en/stable/reference/proxy.html"&gt;create custom proxy implementations&lt;/a&gt; based on their deployment needs. &lt;a href="https://github.com/jupyterhub/traefik-proxy"&gt;&lt;em&gt;JupyterHub Traefik Proxy&lt;/em&gt;&lt;/a&gt; leverages this feature to offer an alternative to the default proxy. It is an implementation of the JupyterHub Proxy API based on &lt;a href="https://traefik.io"&gt;traefik&lt;/a&gt;, an extremely lightweight, portable reverse proxy implementation, that supports load balancing and can configure itself automatically and dynamically. JupyterHub Traefik Proxy comes in two flavors, depending on how traefik stores the routing table:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TraefikTomlProxy&lt;/strong&gt; — &lt;em&gt;for&lt;/em&gt; smaller, &lt;em&gt;single-node deployments&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TraefikEtcdProxy&lt;/strong&gt; — &lt;em&gt;for&lt;/em&gt; distributed &lt;em&gt;setups&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;How does it work?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Both &lt;em&gt;TraefikTomlProxy&lt;/em&gt; and &lt;em&gt;TraefikEtcdProxy&lt;/em&gt; use a &lt;em&gt;toml&lt;/em&gt; file for the global configuration. This file contains information about how to set up the connections to the routing table provider (the unit that stores the routing rules like “/user/mary” should be sent to Mary’s server at http://10.0.1.5:12345) and to the network entry points into Traefik (listening port, SSL, traffic redirection). However, the two proxies go in different directions when it comes to the provider used for storing the routing table.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;TraefikTomlProxy&lt;/strong&gt;&lt;/em&gt; uses a &lt;em&gt;toml&lt;/em&gt; file to store the routes and keeps an in-memory copy of it for a faster access to the routes. This is appropriate for smaller-scale deployments. For example, &lt;a href="https://github.com/jupyterhub/the-littlest-jupyterhub"&gt;&lt;em&gt;the Littlest Jupyterhub&lt;/em&gt;&lt;/a&gt; (the single-node JupyterHub distribution, for a small number of users) just switched from using two proxies (traefik as an edge proxy with letsencrypt support and CHP for routing) to a configuration with just &lt;em&gt;TraefikTomlProxy&lt;/em&gt; that serves both requirements. ❤&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;TraefikEtcdProxy&lt;/strong&gt;&lt;/em&gt; uses &lt;a href="https://coreos.com/etcd/"&gt;&lt;em&gt;etcd&lt;/em&gt;&lt;/a&gt;, a distributed key-value store to persist the routing table. This implementation aims to benefit &lt;a href="http://z2jh.jupyter.org/en/stable/"&gt;&lt;em&gt;Zero to JupyterHub with Kubernetes&lt;/em&gt;&lt;/a&gt; because it allows having multiple proxy replicas, making the proxy highly available and thus improving the scalability and stability of the system.&lt;/p&gt;
&lt;p&gt;Adding the information about TraefikProxy to the first diagram , the drawing below presents the two proxy flavors with their &lt;strong&gt;common&lt;/strong&gt; parts (the global configuration file — &lt;em&gt;traefik.toml&lt;/em&gt;) and their &lt;strong&gt;differences&lt;/strong&gt; (the mechanism used for storing the routing table — a toml file vs. etcd)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/introducing-traefikproxy-a-new-jupyterhub-proxy-based/images/002-1_A--P2mM21Cj6gfWImInnww.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Another cool Traefik feature is the &lt;em&gt;&lt;strong&gt;Web UI dashboard&lt;/strong&gt;&lt;/em&gt; which lists all of the registered frontends (the set of rules that determine how incoming requests are forwarded) and backends (the notebooks), the routing rules, some useful metrics, and other configuration elements. The port on which TraefikProxy’s api will run, as well as the username and password used for authenticating, are all configurable.&lt;/p&gt;
&lt;p&gt;Here’s what the dashboard looks like:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jasongrout.github.io/medium-archive/pelican/posts/2019/introducing-traefikproxy-a-new-jupyterhub-proxy-based/images/003-1_DQjZmUX2a6nzPJzFdZJqTw.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;How to enable Traefik Proxy?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These instructions help you enable one of the Traefik proxies on your JupyterHub.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install it:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python3 -m pip install jupyterhub-traefik-proxy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Install traefik and etcd:&lt;/li&gt;
&lt;/ol&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;python3&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;jupyterhub_traefik_proxy.install&lt;span class="w"&gt; &lt;/span&gt;--output&lt;span class="o"&gt;=&lt;/span&gt;/usr/local/bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will install the default versions of traefik and etcd, namely &lt;code&gt;traefik-1.7.5&lt;/code&gt; and &lt;code&gt;etcd-3.3.10&lt;/code&gt; to &lt;code&gt;/usr/local/bin&lt;/code&gt; specified through the &lt;code&gt;--output&lt;/code&gt; option.&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Configure JupyterHub to run with TraefikProxy through &lt;em&gt;jupyterhub_config.py,&lt;/em&gt; using the &lt;em&gt;proxy_class&lt;/em&gt; config option.&lt;/li&gt;
&lt;/ol&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;jupyterhub_traefik_proxy&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;TraefikEtcdlProxy&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JupyterHub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;proxy_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TraefikEtcdProxy&lt;/span&gt;
&lt;span class="c1"&gt;# will configure JupyterHub to run with TraefikEtcdProxy&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;jupyterhub_traefik_proxy&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;TraefikTomlProxy&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JupyterHub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;proxy_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TraefikTomlProxy&lt;/span&gt;
&lt;span class="c1"&gt;# will configure JupyterHub to run with TraefikTomlProxy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As there are many other proxy configuration options, please check out the project &lt;a href="https://jupyterhub-traefik-proxy.readthedocs.io/en/latest/"&gt;documentation&lt;/a&gt; for more info and some example configurations.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What’s next?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;TraefikEtcdProxy is soon to be integrated into &lt;a href="https://github.com/jupyterhub/zero-to-jupyterhub-k8s"&gt;&lt;strong&gt;zero-to-jupyterhub-k8s&lt;/strong&gt;&lt;/a&gt;, the Helm Chart for deploying JupyterHub on Kubernetes. By using the Traefik proxy with etcd, we can eliminate the downtime while the proxy restarts or upgrades, as well as have an all-in-one proxy that can be used for both routing and &lt;em&gt;HTTPS (Let’s Encrypt)&lt;/em&gt; support.&lt;/p&gt;
&lt;p&gt;Also, there’s a performance analysis of all the three proxies on the way that will help us understand the advantages and limitations of this new JupyterHub Proxy implementation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The story behind&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;JupyterHub Traefik Proxy was developed as part of my &lt;a href="https://www.outreachy.org/"&gt;Outreachy&lt;/a&gt; internship. I am very grateful to have had the chance to work with the Jupyter community and I’m happy and proud to say that I’ve learned a lot and the experience has been invaluable. There were a lot of questions and a ton of fears along the way, but the encouragements and guidance I received, helped me move forward and finish this great project. So, a big &lt;strong&gt;thank you to&lt;/strong&gt; everyone for their support and to &lt;a href="https://numfocus.org/"&gt;&lt;em&gt;NumFocus&lt;/em&gt;&lt;/a&gt; &lt;em&gt;and&lt;/em&gt; &lt;a href="https://bids.berkeley.edu/"&gt;&lt;em&gt;Berkeley Institute for Data Science&lt;/em&gt;&lt;/a&gt; &lt;em&gt;for sponsoring this Outreachy round&lt;/em&gt;! ❤&lt;/p&gt;
&lt;/blockquote&gt;
</content><category term="JupyterHub"/><category term="Kubernetes"/><category term="Outreachy"/></entry></feed>