Skip to main content

Fancy PyPI READMEs with Hatch

Project description

hatch-fancy-pypi-readme

Because your ✨fancy project✨ deserves a ✨fancy PyPI landing page✨.

PyPI - Version PyPI - Python Version License: MIT

hatch-fancy-pypi-readme is a Hatch metadata plugin for everyone who cares about the first impression of their project’s PyPI landing page. It allows you to define your PyPI project description[^names] in terms of concatenated fragments that are based on static strings, files, and most importantly: parts of files defined using cut-off points or regular expressions.

[^names]: PyPI project description, PyPI landing page, PyPI readme all refer to the same thing. In setuptools it’s called long_description and is the text shown on a project’s PyPI page.

We refer to it as “readme” because that’s how it’s called in [PEP 621](https://peps.python.org/pep-0621/)-based `pyproject.toml` files.

You want your PyPI readme to be the project readme, but without badges, followed by the license file, and the changelog section for only the last release? You’ve come to the right place!

Motivation

In the olden days of setup.py files, I’ve taken advantage of the fact that I can write Python to have compelling PyPI readmes.

For example this is the code that gave me the PyPI readme for attrs 22.1.0. Especially having a summary of the latest changes is something I’ve found users to appreciate.

The move away from dynamic setup.py files to static pyproject.toml configurations is great, but it robbed me of being able to provide this service to my users. I've been able to add some dynamism using the wonderful Cog, but it’s a bit awkward and shouldn’t be the long-term solution.

The goal of this plugin is to be able to switch away from setup.py without compromising on the user experience and without needing third-party tools for configuration-file templating.


With Hatch we got a standards-based packaging library that offers exactly the plugin interface I needed. Now you too can have fancy PyPI readmes – just by adding a few lines of configuration to your pyproject.toml.

Configuration

hatch-fancy-pypi-readme is, like Hatch, configured in your project’s pyproject.toml.

First you have to add hatch-fancy-pypi-readme to your [build-system]:

[build-system]
requires = ["hatchling", "hatch-fancy-pypi-readme"]
build-backend = "hatchling.build"

Next, you must tell the build system that your readme is dynamic by adding it to the project.dynamic list:

[project]
# ...
dynamic = ["readme"]

Next, you must add a [tool.hatch.metadata.hooks.fancy-pypi-readme] section.

Here, you must supply a content-type. Currently, only text/markdown and text/x-rst are supported.

[tool.hatch.metadata.hooks.fancy-pypi-readme]
content-type = "text/markdown"

Fragments

Finally, you also must supply an array of fragments. A fragment is a piece of text that is appended to your readme in the order that it’s specified.

We recommend TOML's syntactic sugar for arrays of wrapping the array name in double brackets and will use it throughout this documentation.

Text

Text fragments consist of a single text key and are appended to the readme exactly as you specify them:

[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]
text = "Fragment #1"

[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]
text = "Fragment #2"

results in:

Fragment #1Fragment #2

Note that there’s no additional space or empty lines between fragments unless you specify them.

File

A file fragment reads a file specified by the path key and appends it:

[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]
path = "AUTHORS.md"

Additionally it’s possible to cut away parts of the file before appending it:

  • start-after cuts away everything before the string specified.

  • end-before cuts away everything after.

  • pattern takes a regular expression and returns the first group from it (you probably want to make your capture group non-greedy by appending a question mark: (.*)?). Internally, it uses

    re.search(pattern, whatever_is_left_after_slicing, re.DOTALL).group(1)
    

    to find it.

Both Markdown and reST have comments (<!-- this is a Markdown comment --> and .. this is a reST comment) that you can use for invisible markers:

# Boring Header

<!-- cut after this -->

This is the *interesting* body!

<!-- but before this -->

Uninteresting Footer

together with:

[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]
path = "path.md"
start-after = "<!-- cut after this -->\n\n"
end-before = "\n\n<!-- but before this -->"
pattern = "the (.*) body"

would append:

*interesting*

to your readme.

Note

  • You can insert the same file multiple times – each time a different part!

  • The order of the options in a fragment block does not matter. They’re always executed in the same order:

    1. start-after
    2. end-before
    3. pattern

For a complete example, please see our example configuration.

CLI Interface

For faster feedback loops, hatch-fancy-pypi-readme comes with a CLI interface that takes a pyproject.toml file as an argument and renders out the readme that would go into respective package.

Your can run it either as hatch-fancy-pypi-readme or python -m hatch_fancy_pypi_readme. If you don’t pass an argument, it looks for a pyproject.toml in the current directory. You can optionally pass a -o option to write the output into a file instead of to standard out.

Since hatch-fancy-pypi-readme is part of the isolated build system, it shouldn’t be installed along with your projects. Therefore we recommend running it using pipx:

pipx run hatch-fancy-pypi-readme

You can pipe the output into tools like rich-cli or bat to verify your markup.

For example, if you run

$ pipx run hatch-fancy-pypi-readme | pipx run rich-cli --markdown --hyperlinks -

with our example configuration, you will get the following output:

rich-cli output

Warning While the execution model is somewhat different from the Hatch-Python packaging pipeline, it uses the same configuration validator and text renderer, so the fidelity should be high.

It will not help you debug packaging issues, though.

Project Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hatch_fancy_pypi_readme-22.1.0.tar.gz (21.6 kB view details)

Uploaded Source

Built Distribution

hatch_fancy_pypi_readme-22.1.0-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file hatch_fancy_pypi_readme-22.1.0.tar.gz.

File metadata

File hashes

Hashes for hatch_fancy_pypi_readme-22.1.0.tar.gz
Algorithm Hash digest
SHA256 cc11d4c4421c4523f983930401431e145ffb43129695384776aa460814e2fa50
MD5 71e424f3bbbb53ebb3f0da64c6a30c6c
BLAKE2b-256 7ace5bd1aade0bcc1b08e4968e768f04067701ca78908f8eae7c5dee99a0bf05

See more details on using hashes here.

File details

Details for the file hatch_fancy_pypi_readme-22.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for hatch_fancy_pypi_readme-22.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 891db32f109b0e5806347a2e9c08f47ff694c091f926e88d441f84fe91f2e215
MD5 f17a6f40f27ac0e28ee4ea39feb2650c
BLAKE2b-256 d4a90ad5957b80e3e555f17a324a329912c1abd81f7e19412524a4f1be57827b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page