Sphinx Documentation on GitHub Pages using Poetry (2024)

Sphinx is the most widespread documentation tool I’ve seen used for Python projects. It can output to multiple formats, including HTML and PDF, handle code and cross-references, and plenty of extensions are available in PyPI for more specific use-cases.

But this post is not about the wonders of Sphinx, or the nuances of how to write reStructuredText, as there is already plenty of documentation out there1. Instead I’ll be focusing on my efforts over the last couple of weeks to automate a Sphinx documentation deployment pipeline, by hosting it in Github Pages, for a project that uses poetry as its dependency management tool.

The project that I’ll be using as an example is airflow-dbt-python, an Airflow operator I’ve written to work with dbt (don’t worry, you don’t need to know what any of these tools are for to follow this blog post, it’s just the project I’ve worked on documenting). In the next sections I’ll be dissecting each part of the documentation pipeline, and you can checkout the repo if you want to see the final product up and running.

Specifying the dependencies in poetry

Let’s start by adding the necessary dependencies to our pyproject.toml file (non-documentation specific dependencies have been omitted for clarity):

[tool.poetry.dependencies]Sphinx = { version = "4.2.0", optional = true }sphinx-rtd-theme = { version = "1.0.0", optional = true }sphinxcontrib-napoleon = { version = "0.7", optional = true }[tool.poetry.extras]docs = ["Sphinx", "sphinx-rtd-theme", "sphinxcontrib-napoleon"]

Several things are going on here:

  • Like any other dependency, we added Sphinx and the extensions we are using to the [tool.poetry.dependencies] section of our pyproject.toml file.
  • For stability, we have pinned the dependency versions used.
  • The dependencies have been set as optional, as we don’t want to include them in release versions of the package by default.
  • These optional dependencies have been grouped together in the [tool.poetry.extras] section to allow for easy installation.

This way, developers working on the project may install the documentation dependencies by running:

poetry install airflow-dbt-python --extras docs

Writing our documentation with Sphinx

We will not be saying too much here as there are plenty of resources on how to write good documentation and, in particular, on how to use Sphinx to do it2. I encourage you to go over the Sphinx quickstart guide if you want to get up and running to continue with this blog post. If you have used poetry to install Sphinx, as detailed in the previous section, remember you’ll need to run the Sphinx commands with poetry:

poetry run sphinx-quickstart

Setting up GitHub Actions

In order to automate the deployment of our documentation, we’ll be using GitHub Actions. This is not strictly required, and other CI/CD vendors may work just as well or even better, but since my project is hosted in GitHub, I’m taking advantage of those free credits.

Here’s the full YAML, which should be dropped in .github/workflows/docs_pages.yaml:

name: Docs2Pageson: push: tags: '*' pull_request: branches: - masterjobs: build-docs: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/[emailprotected] with: fetch-depth: 0 - uses: actions/[emailprotected] with: python-version: 3.9 - uses: abatilo/[emailprotected] - name: install run: poetry install -E amazon -E docs - name: Build documentation run: | mkdir gh-pages touch gh-pages/.nojekyll cd docs/ poetry run sphinx-build -b html . _build cp -r _build/* ../gh-pages/  - name: Deploy documentation if: ${{ github.event_name == 'push' }} uses: JamesIves/[emailprotected] with: branch: gh-pages folder: gh-pages

Let’s now go over each relevant section:

on: push: tags: '*' pull_request: branches: - master

This is just configuring the action to run only when a tag is pushed, or when a pull request is made against the master branch of the repo. We want our documentation to be built and deployed whenever a new tag is pushed, but we also want to build the documentation when a pull request is opened to ensure the build succeeds.

jobs: build-docs: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/[emailprotected] with: fetch-depth: 0 - uses: actions/[emailprotected] with: python-version: 3.9 - uses: abatilo/[emailprotected] - name: install run: poetry install -E amazon -E docs

The first three steps handle checking out the repo, setting up python and poetry, and installing the package with its dependencies. You can checkout the specific action we use to install poetry over here. This particular action assumes we have already setup python, which is why we run it in this particular order.

In the last step, notice that we are running the poetry install command using the -E (same as --extras) flag to install our docs dependencies. This will install Sphinx and its dependencies as we specified before.

 - name: Build documentation run: | mkdir gh-pages touch gh-pages/.nojekyll cd docs/ poetry run sphinx-build -b html . _build cp -r _build/* ../gh-pages/ 

We finally get to the actual build step. There are several commands running here:

  • Our documentation will be built on a directory we have named gh-pages, so the first mkdir creates it.
  • By default, GitHub uses Jekyll to generate a static site. We are already using Sphinx for it, so we tell GitHub not to use Jekyll by including an empty .nojekyll file. Omitting this would cause our Sphinx themes to not be properly loaded.
  • We move to the docs/ directory and run our sphinx-build command using poetry: poetry run sphinx-build -b html . _build. Notice that we are not running sphinx-build directly as we have installed it using poetry. This will output our documentation HTML files that we just move to the gh-pages directory created in the first step.
 - name: Deploy documentation if: ${{ github.event_name == 'push' }} uses: JamesIves/[emailprotected] with: branch: gh-pages folder: gh-pages

The last step in our pipeline deploys the documentation to GitHub Pages. The actual deployment involves committing the contents of the gh-pages folder to a branch that we have also named gh-pages. You can find the action used for this step here. If you checkout the gh-pages branch of the repo you will see it looks nothing like other branches, it just contains the documentation we built in the previous step.

One last thing to mention: we have an if-conditional to ensure the deployment step happens only on push events. Since our entire action only runs on tag pushes or pull requests, this means deployment will only run when we push tags, as we don’t support multiple documentation environments. The pipeline could be extended here to support test and/or development environments to deploy the documentation, but that’s beyond the scope of this post.

Finishing by configuring our GitHub repo

If you have followed all the steps until now, and have pushed a tag, you’ll find yourself with a new gh-pages branch which contains all the documentation files built by Sphinx. However, nothing has happened yet as we have not told GitHub that we want to use GitHub Pages to host our documentation. This is a very simple task that we can accomplish by going into the Settings of our repo, under the Pages section and creating a Source pointing to our new gh-pages branch:

Sphinx Documentation on GitHub Pages using Poetry (1)

And that’s it! After a few minutes our documentation should be up-and-running in a URL with the format: https://<account>.github.io/<repo>/. GitHub will let us know when the site is available in the same Settings page:

Sphinx Documentation on GitHub Pages using Poetry (2)

Final thoughts

The idea for this post came to me as all of the guides and other posts I could find regarding deploying Sphinx documentation to GitHub Pages were not using poetry as their package management tool. Since adapting those guides gave me a few headaches, I wanted to help other people smooth out the process with my own guide. I’m hoping at least to have clearly explained the poetry-specific parts of the setup and would like to leave you with some ideas on what to do next:

  • Consider building and deploying the documentation on pushes to master branch using different paths in the URL, e.g. https://<account>.github.io/<repo>/master/ and https://<account>.github.io<repo>/latest/.
  • Try mixing up the theme of the docs. The themes used by the flask documentation are a nice alternative: https://github.com/pallets/pallets-sphinx-themes.
Sphinx Documentation on GitHub Pages using Poetry (2024)

FAQs

Sphinx Documentation on GitHub Pages using Poetry? ›

Sphinx is the most widespread documentation tool I've seen used for Python projects. It can output to multiple formats, including HTML and PDF, handle code and cross-references, and plenty of extensions are available in PyPI for more specific use-cases.

How do I add a Sphinx document to github? ›

Open the Settings tab and select Pages from the sidebar. From the source section, select the branch wherever you have pushed the documentation code. Ideally, you could create a separate branch for your documentation say gh-pages or any name you see fit. Commit the code and select the branch in the source section.

How do you use Sphinx to generate documentation in Windows? ›

Auto-Generated Python Documentation with Sphinx (See ...

How do you run a sphinx python? ›

Using Sphinx for Python Documentation
  1. Workflow.
  2. Prepare.
  3. Step 1: Use sphinx-quickstart to generate Sphinx source directory with conf.py and index.rst.
  4. Step 2: Configure the conf.py. ...
  5. Step 3: Use sphinx-apidoc to generate reStructuredText files from source code.
  6. Step 4: Edit index.rst and the generated reStructuredText files.
Sep 19, 2019

How do you publish a Sphinx document? ›

Publishing your documentation sources
  1. Sign up for a GitHub account.
  2. Create a new repository.
  3. Open the “Upload files” page of your new repository.
  4. Select the files on your operating system file browser (in your case README. ...
  5. Click on the Commit changes button.
Nov 16, 2021

How do you use Sphinx markdown? ›

To configure your Sphinx project for Markdown support, proceed as follows:
  1. Install the Markdown parser MyST-Parser: ...
  2. Add myst_parser to the list of configured extensions : ...
  3. If you want to use Markdown files with extensions other than .md , adjust the source_suffix variable.

Is Sphinx only for Python? ›

I hope that this shows you how Sphinx can be used for documentation all kinds of software, not just Python. It is a fantastically powerful documentation tool, and you shouldn't discard it without looking at it closely.

How do you create a read document? ›

Sphinx & Read the Docs - YouTube

Does Sphinx work on Windows? ›

Sphinx works just fine on Windows. To get started, go to the Quickstart tutorial and follow the instructions.

How many Sphinx are in Egypt? ›

The 1.7-mile long Avenue of the Sphinxes in Luxor, Egypt, which is flanked by more than 1,000 statues of sphinxes and rams, officially reopened today in a lavish ceremony organised by the Egyptian ministry of Tourism and Antiquities.

How do I automatically code a Python file? ›

Five Tips for Automatic Python Documentation
  1. MkDocs & Material installation.
  2. Automate type-hints to docstrings.
  3. Automate docstrings to MkDocs with mkgendocs.
  4. Automate the documentation of new Python functions.
  5. Tie everything together in pre-commit Git hooks.
Jun 17, 2021

What does sphinx stand for? ›

Definition of sphinx

1a capitalized : a winged female monster in Greek mythology having a woman's head and a lion's body and noted for killing anyone unable to answer its riddle. b : an enigmatic or mysterious person she is a sphinx whose features hold a blank fascination.

How do I upload a document to GitHub? ›

On GitHub.com, navigate to the main page of the repository. Above the list of files, using the Add file drop-down, click Upload files. Drag and drop the file or folder you'd like to upload to your repository onto the file tree.

What is a .nojekyll file? ›

nojekyll . The existence of this file tells GitHub Pages not to run the published files through Jekyll. This is important since Jekyll will discard any files that begin with _ . By default, Antora puts the UI files in a directory named _ , which Jekyll then erases.

How do you install a sphinx? ›

Part 1 - Installing sphinx - YouTube

What is GH page branch? ›

git checkout gh-pages means you've switched to the branch named 'gh-pages'. Any change you commit to this branch is picked up by github to build your github pages. To switch back to the 'master' branch (presumably your source code), do git checkout master .

Top Articles
Latest Posts
Article information

Author: Gregorio Kreiger

Last Updated:

Views: 6453

Rating: 4.7 / 5 (57 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Gregorio Kreiger

Birthday: 1994-12-18

Address: 89212 Tracey Ramp, Sunside, MT 08453-0951

Phone: +9014805370218

Job: Customer Designer

Hobby: Mountain biking, Orienteering, Hiking, Sewing, Backpacking, Mushroom hunting, Backpacking

Introduction: My name is Gregorio Kreiger, I am a tender, brainy, enthusiastic, combative, agreeable, gentle, gentle person who loves writing and wants to share my knowledge and understanding with you.