<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Chris Holdgraf's blog</title>
    <link>http://chrisholdgraf.com/rss.xml</link>
    <description>Chris' personal blog!</description>
    <atom:link href="http://chrisholdgraf.com/rss.xml" rel="self"/>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <image>
      <url>http://chrisholdgraf.com/_static/profile.jpg</url>
      <title>Chris Holdgraf's blog</title>
      <link>http://chrisholdgraf.com/rss.xml</link>
    </image>
    <language>en</language>
    <lastBuildDate>Tue, 21 Oct 2025 16:44:51 +0000</lastBuildDate>
    <item>
      <title>An academic scientist goes to DevOps Days</title>
      <link>http://chrisholdgraf.com/blog/2018/devopsdays-sv-2018</link>
      <description>


Last week I took a few days to attend [DevOpsDays Silicon Valley](https://www.devopsdays.org/events/2018-silicon-valley/program/). My goal
was to learn a bit about how the DevOps culture works, what are the things
people are excited about and discuss in this community. I'm also interested in
learning a thing or two that could be brought back into</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/devopsdays-sv-2018</guid>
      <pubDate>Fri, 18 May 2018 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Blogging with Jupyter Notebooks and Jekyll using nbconvert templates</title>
      <link>http://chrisholdgraf.com/blog/2018/jekyllmarkdown</link>
      <description>


Here's a quick (and hopefully helpful) post for those wishing to blog in
Jekyll using Jupyter notebooks. As some of you may know, `nbconvert` can
easily convert your `.ipynb` files to markdown, which Jekyll can easily
turn into blog posts for you.

```
nbconvert --to markdown myfile.ipynb
```

However, an annoying part of this is that Markdown</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/jekyllmarkdown</guid>
      <pubDate>Wed, 23 May 2018 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Adding copy buttons to code blocks in Sphinx</title>
      <link>http://chrisholdgraf.com/blog/2018/sphinx-copy-buttons</link>
      <description>


&gt; **NOTE: This is now a sphinx extension!** Thanks to some friendly suggestions, I've written
&gt; this up as a super tiny sphinx extension. Check it out here: https://github.com/choldgraf/sphinx-copybutton

[Sphinx](http://www.sphinx-doc.org/en/master/) is a fantastic way to build
documentation for your Python package. On the Jupyter project, we use it
for almost all of our repositories.

A</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/sphinx-copy-buttons</guid>
      <pubDate>Thu, 05 Jul 2018 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Summer conference report back</title>
      <link>http://chrisholdgraf.com/blog/2018/conferences-summer-2018</link>
      <description>


This is a short update on several of the conferences and workshops over the
summer of this year. There's all kinds of exciting things going on in open
source and open communities, so this is a quick way for me to collect my
thoughts on some things I've learned this summer.



Pangeo is a</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/conferences-summer-2018</guid>
      <pubDate>Wed, 01 Aug 2018 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Using CircleCI to preview documentation in Pull Requests</title>
      <link>http://chrisholdgraf.com/blog/2018/circle-docs</link>
      <description>


Writing documentation is important - it's the first point of contact between many users and your
project, and can be a pivotal moment in whether they decide to adopt your tech or become a contributor.

However, it can be a pain to iterate on documentation, as it is often involves a lot</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/circle-docs</guid>
      <pubDate>Tue, 16 Oct 2018 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>I like Rust's governance structure</title>
      <link>http://chrisholdgraf.com/blog/2018/rust_governance</link>
      <description>


Recently I've been reading up on governance models for several large-ish open
source projects. This is partially because I'm involved in a bunch of
these projects myself, and partially because it's fascinating to see distributed groups
of people organizing themselves in effective (or not) ways on the internet.


Governance is tricky, because there is</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/rust_governance</guid>
      <pubDate>Thu, 18 Oct 2018 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>My weekly workflow</title>
      <link>http://chrisholdgraf.com/blog/2018/my-workflow</link>
      <description>


I've had a bunch of conversations with friends who were interested in how to
keep track of the various projects they're working on, and to prioritize their
time over the course of a week. I thought it might be helpful to post my own
approach to planning time throughout the week in case</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/my-workflow</guid>
      <pubDate>Fri, 26 Oct 2018 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>How do projects signal how "open" they are?</title>
      <link>http://chrisholdgraf.com/blog/2018/kinds-of-openness</link>
      <description>


How do open projects signal their "openness" to the outside community? This is
a really hard question, particularly because nowadays "open" has become a buzzword
that doesn't just signal a project's position to the community, but is also used
as a marketing term to increase support, users, or resources.

I was thinking about this</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/kinds-of-openness</guid>
      <pubDate>Fri, 26 Oct 2018 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Open communities need to be partners, not sources of free labor</title>
      <link>http://chrisholdgraf.com/blog/2018/free-labor-partners</link>
      <description>


In the last couple of years, we've seen an increasing number of organizations start to
spawn products that take a largely open stack (e.g., the SciPy ecosystem) and wrap
it in a thin layer of proprietary/custom interface + infrastructure.
On the face of it, this isn't a problem - I really want people</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/free-labor-partners</guid>
      <pubDate>Wed, 05 Dec 2018 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Automatically mirror a github repository with CircleCI</title>
      <link>http://chrisholdgraf.com/blog/2018/circlci-github</link>
      <description>


&gt; tl;dr: you can automatically mirror the contents of one repository to another by
  using CI/CD services like CircleCI. This post shows you one way to do it using
  secrets that let you push to a GitHub repository from a CircleCI process.

We recently ran into an issue with</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2018/circlci-github</guid>
      <pubDate>Tue, 18 Dec 2018 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Three things I love about CircleCI</title>
      <link>http://chrisholdgraf.com/blog/2019/2019-01-29-three-things-circleci</link>
      <description>


I recently had to beef up the continuous deployment of Jupyter Book, and used
it as an opportunity to learn a bit more about CircleCI's features. It turns out,
they're pretty cool! Here are a few of the things that I learned this time around.

For those who aren't familiar with CircleCI, it</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2019/2019-01-29-three-things-circleci</guid>
      <pubDate>Tue, 29 Jan 2019 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Thoughts from the Jupyter team meeting 2019</title>
      <link>http://chrisholdgraf.com/blog/2019/2019-03-16-jupyter-dev</link>
      <description>

I just got back from a week-long Jupyter team meeting that was somehow both
very tiring and energizing at the same time. In the spirit of openness, I'd
like to share some of my experience. While it's still fresh in my mind,
here are a few takeaways that occurred to me throughout the</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2019/2019-03-16-jupyter-dev</guid>
      <pubDate>Sat, 30 Mar 2019 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>A few recent talks</title>
      <link>http://chrisholdgraf.com/blog/2019/2019-06-25-a-few-talks</link>
      <description>


Lately I've given quite a number of talks about the Jupyter and Binder
ecosystems for various purposes. Before each of the talks, I make the
slides available at a public address in case others are interested in
following up with the material. For those who missed the talks (or the
subsequent tweets about them),</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2019/2019-06-25-a-few-talks</guid>
      <pubDate>Tue, 25 Jun 2019 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Automating Jupyter Book deployments with CI/CD</title>
      <link>http://chrisholdgraf.com/blog/2019/2019-10-11-automating-jb</link>
      <description>


Lately I've spent a lot of time trying to reduce the friction involved
in deploying Jupyter Book as well as contributing to the project.
Features are a great carrot, but ultimately getting engagement is also
about lowering barriers to entry and showing people a path forward.
Jupyter Book is a relatively straightforward project, but</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2019/2019-10-11-automating-jb</guid>
      <pubDate>Fri, 11 Oct 2019 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>What would Rust-style governance look like in Jupyter?</title>
      <link>http://chrisholdgraf.com/blog/2019/2019-10-13-rust-jupyter-governance</link>
      <description>


As I've written about before, I [like Rust's governance structure](https://chrisholdgraf.com/rust-governance).
I mean, who can't get behind a community that
[lists governance as a top-level page on its website](https://www.rust-lang.org/governance)?

Jupyter is currently in the middle of
[figuring out the next phase of its governance structure](https://discourse.jupyter.org/t/governance-office-hours-meeting-minutes/1480/26),
and so I have been thinking about
what this might look like.</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2019/2019-10-13-rust-jupyter-governance</guid>
      <pubDate>Sun, 13 Oct 2019 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>What would Python-style governance look like in Jupyter?</title>
      <link>http://chrisholdgraf.com/blog/2019/2019-10-27-jupyter-governance-python</link>
      <description>


This is the second in a series of blog posts that explores what it'd look like to
directly port the governance model of other communities into the Jupyter project.
You can find the [first post about Rust here](https://chrisholdgraf.com/rust-jupyter-governance).

**Note**: These posts are meant as a thought experiment rather than a proposal. Moreover,
all the</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2019/2019-10-27-jupyter-governance-python</guid>
      <pubDate>Sun, 27 Oct 2019 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Build a simple timeline with `sphinx-design`</title>
      <link>http://chrisholdgraf.com/blog/2020/sphinx-design-timeline</link>
      <description>


:::{warning} This probably doesn't work anymore
I'm building my blog with the [MyST Markdown engine](https://mystmd.org) now, which means that all of this sphinx-specific stuff probably doesn't work anymore :-)

If you want to see a version of this page that worked, [check out this file in GitHub](https://github.com/choldgraf/choldgraf.github.io/blob/ae8ee9792c74aac72f46c645d19352abc439d572/blog/2020/sphinx-design-timeline.md).
:::</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2020/sphinx-design-timeline</guid>
      <pubDate>Wed, 22 Jan 2020 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>What do people think about rST?</title>
      <link>http://chrisholdgraf.com/blog/2020/2020-01-22-rst-thoughts</link>
      <description>


Publishing computational narratives has always been a dream of the Jupyter Project,
and there is still a lot of work to be done in improving these use-cases. We've made
a lot of progress in providing open infrastructure for reproducible science with
[JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) and
[the Binder Project](https://mybinder.org/), but what about the documents themselves?
We've recently been</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2020/2020-01-22-rst-thoughts</guid>
      <pubDate>Wed, 22 Jan 2020 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>A new blog with Sphinx</title>
      <link>http://chrisholdgraf.com/blog/2020/sphinx-blogging</link>
      <description>


I recently re-wrote all of the infrastructure for my blog so that it now builds on top of the Sphinx ecosystem! This is a short post to describe the reasons for doing so, and a bit about the implementation.

````{image} images/sphinx-logo.png
:class: bg-dark
````


This is a great question. The answer to "should you</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2020/sphinx-blogging</guid>
      <pubDate>Sat, 10 Oct 2020 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Contributing to open source: A short guide for organizations</title>
      <link>http://chrisholdgraf.com/blog/2020/organizations-help-oss-guide</link>
      <description>


Over the years I've had a recurring question from people who are in organizations both big and small: _how can we participate in open source communities?_

Whether it is because of altruism or strategic importance, many companies, research groups, non-profits, etc _want_ to be involved in open source projects (particularly large</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2020/organizations-help-oss-guide</guid>
      <pubDate>Sun, 08 Nov 2020 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Serving in two roles at once via pre-recorded tutorials</title>
      <link>http://chrisholdgraf.com/blog/2021/2021-12-18-hybrid-tutorial-prerecord</link>
      <description>


At AGU 2021 this year I was asked to give [a short tutorial introduction to Jupyter Book](https://www.youtube.com/watch?v=lZ2FHTkyaMU).
The tutorial was 30 minutes long, and the session was fully remote.

This posed a few challenges:

- Tutorials almost **always** go over time - particularly if you're taking questions from attendees.
- It is tricky to</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2021/2021-12-18-hybrid-tutorial-prerecord</guid>
      <pubDate>Fri, 17 Dec 2021 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Ask Twitter: Why don't academic researchers use cloud services?</title>
      <link>http://chrisholdgraf.com/blog/2022/cloud-services-academia</link>
      <description>


_this is an experiment at making my [Twitter conversations](https://twitter.com/choldgraf) a bit more useful and archivable over time. It's going to be a bit messy and unpolished, but hopefully that makes it more likely I'll actually do it :-)_

Over the past decade, cloud infrastructure has become increasingly popular in industry.
An ecosystem</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/cloud-services-academia</guid>
      <pubDate>Mon, 05 Sep 2022 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Automatically redirect folders in Sphinx websites</title>
      <link>http://chrisholdgraf.com/blog/2022/sphinx-redirects-folder</link>
      <description>


I spent a bit of time today updating my website after some changes in the MyST-NB and Sphinx Design ecosystems.
Along the way, I decided to redirect `/posts/` to `/blog/`, since it seems `/blog/` is a much more common folder to use for blog posts.

This posed a problem, because [the `sphinx-rediraffe`</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/sphinx-redirects-folder</guid>
      <pubDate>Sat, 19 Nov 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Automatically updating my publications page with ORCID and doi.org</title>
      <link>http://chrisholdgraf.com/blog/2022/orcid-auto-update</link>
      <description>


For a while I've had a hand-crafted `.bibtex` file stored locally for [my `publications/` page](../../publications.md).
However, manually updating local text file is a pain to remember, especially since there are many services out there that automatically track new publications.

:::{admonition} Update!
A [helpful suggestion on Twitter](https://twitter.com/temorrell/status/1594749942316208128) allowed me to include the full citation</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/orcid-auto-update</guid>
      <pubDate>Sat, 19 Nov 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Custom roles and domains in Sphinx with one line</title>
      <link>http://chrisholdgraf.com/blog/2022/sphinx-custom-crossrefs</link>
      <description>


I was working on [the roles and structure section of the 2i2c Team Compass](https://compass.2i2c.org) and found a nifty feature in Sphinx that I hadn't known before.

You can currently add labels to any section with the following MyST Markdown structure:

```md
(mylabel)=

And now I [reference it](mylabel).
```

However, there are no **semantics** attached to this</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/sphinx-custom-crossrefs</guid>
      <pubDate>Mon, 21 Nov 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Fix phantom GitHub workflows in your ci-cd with protected branch rules</title>
      <link>http://chrisholdgraf.com/blog/2022/phantom-workflows-pull-requests</link>
      <description>


Have you ever had a GitHub pull request show "phantom" workflows that never pass?
This looks like one or more workflows that are in a constant **waiting state**, with a yellow status indicator, and that never complete.

It looks something like this:

```{image} https://user-images.githubusercontent.com/1839645/204134864-da2541f0-ff4f-4d9f-8c80-aa8c4437d8a0.png
```

If you run into this, it may be because of</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/phantom-workflows-pull-requests</guid>
      <pubDate>Sun, 27 Nov 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>`subprocess.run` can execute shell commands directly</title>
      <link>http://chrisholdgraf.com/blog/2022/shell-split</link>
      <description>


I often run shell commands in Python via the [`subprocess.run` command](https://docs.python.org/3/library/subprocess.html#subprocess.run).
One thing that has always bugged me is that this required you to split commands into a list before it'd work properly.
For example, you'd have to do:

```python
import subprocess
import shlex

subprocess.run(*shlex.split("ls -l"))
```

Today I discovered that you don't have to do this!
There's a</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/shell-split</guid>
      <pubDate>Tue, 29 Nov 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Automatically update pre-commit hook versions</title>
      <link>http://chrisholdgraf.com/blog/2022/precommit-autoupdate</link>
      <description>


I figured out a way to automatically update all of the git `pre-commit` hook versions at once!

[`pre-commit`](https://pre-commit.com/) is a useful command line tool for running simple commands before every `git` commit.
I use it to enforce things like [`flake8`](https://flake8.pycqa.org/) and [`black`](https://github.com/psf/black) in many of my projects.

However, I find it really annoying</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/precommit-autoupdate</guid>
      <pubDate>Sat, 03 Dec 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>How to update Sphinx options during the build</title>
      <link>http://chrisholdgraf.com/blog/2022/sphinx-update-config</link>
      <description>


As part of [the `pydata-sphinx-theme`](https://github.com/pydata/pydata-sphinx-theme/pull/1075) we have a few settings that auto-enable extensions and configure them on behalf of the user.
It has always been mysterious to me how to do this properly **during the Sphinx build**.
It's easy to configure things with `conf.py` ahead of time, but what if you want</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/sphinx-update-config</guid>
      <pubDate>Mon, 05 Dec 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Load and plot a remote font with Matplotlib</title>
      <link>http://chrisholdgraf.com/blog/2022/matplotlib-remote-font</link>
      <description>


As part of [my `sphinx-social-previews`](https://github.com/choldgraf/sphinx-social-previews) prototype, I wanted to be able to use the [Roboto Font from Google](https://fonts.google.com/specimen/Roboto) in image previews.
However, Roboto is often not loaded on your local filesystem, so it took some digging to figure out how to make it possible to load via [Matplotlib's text plotting functionality](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.text.html).

Here's</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/matplotlib-remote-font</guid>
      <pubDate>Tue, 06 Dec 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Report from the JupyterLite workshop: WebAssembly is pretty cool</title>
      <link>http://chrisholdgraf.com/blog/2022/jupyterlite-workshop</link>
      <description>


I recently attended [the JupyterLite community workshop in Paris](https://blog.jupyter.org/community-workshop-jupyterlite-e992c61f5d7f?source=collection_home---6------6-----------------------), here are some quick thoughts from the three-day event[^ack].

[^ack]: Many thanks to the [QuantStack](http://quantstack.com/) team for organizing this event, and to [OVHCloud](https://www.ovhcloud.com/en/) for providing a physical space for everyone. 

For those without any background, JupyterLite is a distribution of Jupyter's user</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/jupyterlite-workshop</guid>
      <pubDate>Sat, 10 Dec 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Install dependencies from GitHub with `pyproject.toml` or `requirements.txt`</title>
      <link>http://chrisholdgraf.com/blog/2022/install-github-from-pyproject</link>
      <description>


This is a short post to demonstrate how to install packages directly from GitHub with `pyprojects.toml` or `requirements.txt`, including custom branches and commits.
It will focus on `pyprojects.toml` because this is newer and there's less information about it, but the general pattern holds for `requirements.txt` as well.

In `pyproject.toml`, you can specify</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2022/install-github-from-pyproject</guid>
      <pubDate>Sat, 31 Dec 2022 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Bundle extensions with your Sphinx theme</title>
      <link>http://chrisholdgraf.com/blog/2023/sphinx-add-extensions</link>
      <description>


Sphinx is great because it has a ton of useful extensions that let you grow its functionality.
However, a downside of this is that users have to actually _learn about_ those extensions and activate them manually.
It's not hard, but it's a non-trivial amount of discovery work.

One way to solve this is</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2023/sphinx-add-extensions</guid>
      <pubDate>Thu, 19 Jan 2023 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Report from FOSDEM23: beautiful chaos in a conference</title>
      <link>http://chrisholdgraf.com/blog/2023/fosdem</link>
      <description>


I recently attended [FOSDEM 2023](https://fosdem.org/2023/), my first FOSDEM!
I had heard of the conference before, but hadn't really looked into it too much.
Fortunately, after some urging from friends and social media, I took a deeper look and decided I should join to see what all the fuss was about.

Here are a</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2023/fosdem</guid>
      <pubDate>Mon, 06 Feb 2023 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>A Sphinx directive for social media embeds</title>
      <link>http://chrisholdgraf.com/blog/2023/social-directive</link>
      <description>


:::{note} This probably doesn't work anymore
I've since moved my blog to use [the MyST Document Engine](https://mystmd.org) so this example will no longer work on my personal blog. See [this permalink for the latest working version](https://github.com/choldgraf/choldgraf.github.io/blob/ae8ee9792c74aac72f46c645d19352abc439d572/blog/2023/social-directive.md).
:::

I often want to link to social and other types of web-based media in my Sphinx</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2023/social-directive</guid>
      <pubDate>Wed, 15 Feb 2023 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>A few random opportunities in AI for Social Good</title>
      <link>http://chrisholdgraf.com/blog/2023/ai-for-good</link>
      <description>


Recently a few friends have reached out asking if I knew of any opportunities to work on AI-related things that also have some kind of pro-social tie-in.
I think a lof people see AI as a technology with a lot of potential, but in an environment of companies that don't seem</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2023/ai-for-good</guid>
      <pubDate>Mon, 02 Oct 2023 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Re-building my blog with MySTMD</title>
      <link>http://chrisholdgraf.com/blog/2024/mystmd-with-the-blog</link>
      <description>

Wow it has been a long time since I've last-written here. It turns out that having two small children and a very demanding job means you don't have as much time for blogging. But that's a whole different blog post...

I've decided to convert my blog to use the new [MyST</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2024/mystmd-with-the-blog</guid>
      <pubDate>Fri, 01 Nov 2024 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Generate MyST with Jupyter and insert it into content programmatically</title>
      <link>http://chrisholdgraf.com/blog/2024/programmatic-myst-with-jupyter</link>
      <description>



While I've been [converting my blog to use the new MyST engine](./mystmd-with-the-blog.md), I discovered a useful MyST feature. It's not yet possible to [natively parse Jupyter Markdown outputs as MyST](https://github.com/jupyter-book/mystmd/issues/1026) but there's a workaround if you don't mind generating a temporary file.

The trick is to _write to a temporary file_</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2024/programmatic-myst-with-jupyter</guid>
      <pubDate>Mon, 04 Nov 2024 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Better blog lists with the MyST AST</title>
      <link>http://chrisholdgraf.com/blog/2024/blog-list</link>
      <description>


On my journey to learn more about writing with [the new MyST engine](https:///mystmd.org), I built upon [my recent update to my blog infrastructure](./programmatic-myst-with-jupyter.md) and made some improvements to my blog post list.
Here's what it looks like now:

````{note} Click here to see how it looks now
:class: dropdown
```{postlist}
:number: 3
```
````

Here's a quick rundown</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2024/blog-list</guid>
      <pubDate>Sat, 09 Nov 2024 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>How I'm trying to use BlueSky without getting burned again</title>
      <link>http://chrisholdgraf.com/blog/2024/bluesky</link>
      <description>Some quick thoughts on moving from Twitter/X to BlueSky and how I'll try to use social media after being burned once by Twitter.
</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2024/bluesky</guid>
      <pubDate>Fri, 22 Nov 2024 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Why I'm running for the Jupyter Executive Council</title>
      <link>http://chrisholdgraf.com/blog/2025/jec</link>
      <description>


This year, I decided to nominate myself for the [Jupyter Executive Council](https://jupyter.org/governance/executive_council.html). This is a brief post explaining my rationale for doing so, the kind of service I'd hope to provide the project, and where I imagine the project moving.


The [Jupyter Executive Council](https://jupyter.org/governance/executive_council.html) is the highest governing body within the</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2025/jec</guid>
      <pubDate>Tue, 14 Jan 2025 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Ways the Jupyter Foundation could support open source projects</title>
      <link>http://chrisholdgraf.com/blog/2025/os-support</link>
      <description>

The Jupyter Foundation has a pot of money and it aims to use that funding quickly to support the Jupyter Project. But what should it use the funding _for_? There are many things to do, and not enough time or money to try everything. This is a brief brainstorm and</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2025/os-support</guid>
      <pubDate>Wed, 26 Feb 2025 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>The relationship between the Jupyter Executive Council, Software Steering Council, and Foundation</title>
      <link>http://chrisholdgraf.com/blog/2025/jupyter-org-structure</link>
      <description>


This is a question that I've been asked many times now that I'm serving on the JEC and the JF. I'm writing up a quick response so that I have something to refer back to and align my own thinking on.

**How most Linux Foundation projects seem to be structured**. Linux</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2025/jupyter-org-structure</guid>
      <pubDate>Sun, 02 Mar 2025 00:00:00 -0800</pubDate>
    </item>
    <item>
      <title>Jupyter can align the needs of its community and its foundation by enabling contribution</title>
      <link>http://chrisholdgraf.com/blog/2025/more-contributors</link>
      <description>

This week was my first time attending the [Linux Foundation Member Summit](https://events.linuxfoundation.org/lf-member-summit/). This is an annual meeting for all of the Linux Foundation member organizations and projects. I joined because of my new role [on the Jupyter Executive Council](./jec.md), and so I tried to go into this meeting with the</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2025/more-contributors</guid>
      <pubDate>Sat, 22 Mar 2025 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>Why open source foundations try to fund systems, not development</title>
      <link>http://chrisholdgraf.com/blog/2025/fund-systems-not-developmend</link>
      <description>
This is a brief reflection on something that I've been hearing consistently from the Linux Foundation and its member projects as part of serving on the [Board of the Jupyter Foundation](https://jupyterfoundation.org). Here's a point that originally surprised me when I heard it:

&gt; Most foundations within the Linux Foundation network recommend</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2025/fund-systems-not-developmend</guid>
      <pubDate>Sat, 31 May 2025 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>My system for beating jet lag</title>
      <link>http://chrisholdgraf.com/blog/2025/jet-lag</link>
      <description>

I travel internationally a lot, which means I deal with a lot of jet lag. This post is a quick summary of a system I've found helpful, based on [this paper](https://www.frontiersin.org/articles/10.3389/fphys.2019.00927/full).


The basic idea is to shift your body's internal clock by timing your exposure to light, exercise, and melatonin around</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2025/jet-lag</guid>
      <pubDate>Sat, 18 Oct 2025 00:00:00 -0700</pubDate>
    </item>
    <item>
      <title>The slow boring of hard boards in open source</title>
      <link>http://chrisholdgraf.com/blog/2025/lock-files</link>
      <description>


Max Weber famously wrote that politics is "a strong and slow boring of hard boards." In [Why it took 4 years to get a lock files specification](https://snarky.ca/why-it-took-4-years-to-get-a-lock-files-specification/), Brett Cannon demonstrates how the same principle applies to technical coordination in open source.

Python recently adopted [PEP 751](https://peps.python.org/pep-0751/) for lockfile specification. Doing so</description>
      <guid isPermaLink="false">http://chrisholdgraf.com/blog/2025/lock-files</guid>
      <pubDate>Tue, 21 Oct 2025 00:00:00 -0700</pubDate>
    </item>
  </channel>
</rss>
