Fancy PyPI READMEs with Hatch
Project description
hatch-fancy-pypi-readme
Because your ✨fancy project✨ deserves a ✨fancy PyPI landing page✨.
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 usesre.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:
start-after
end-before
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:
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
- License: MIT
- PyPI: https://pypi-hypernode.com/project/hatch-fancy-pypi-readme/
- Source Code: https://github.com/hynek/hatch-fancy-pypi-readme
- Documentation: https://github.com/hynek/hatch-fancy-pypi-readme#readme
- Changelog: https://github.com/hynek/hatch-fancy-pypi-readme/blob/main/CHANGELOG.md
- Supported Python Versions: 3.8 and later. Please note that this is the requirement for building packages and not for the packages themselves!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file hatch_fancy_pypi_readme-22.1.0.tar.gz
.
File metadata
- Download URL: hatch_fancy_pypi_readme-22.1.0.tar.gz
- Upload date:
- Size: 21.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.10.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cc11d4c4421c4523f983930401431e145ffb43129695384776aa460814e2fa50 |
|
MD5 | 71e424f3bbbb53ebb3f0da64c6a30c6c |
|
BLAKE2b-256 | 7ace5bd1aade0bcc1b08e4968e768f04067701ca78908f8eae7c5dee99a0bf05 |
File details
Details for the file hatch_fancy_pypi_readme-22.1.0-py3-none-any.whl
.
File metadata
- Download URL: hatch_fancy_pypi_readme-22.1.0-py3-none-any.whl
- Upload date:
- Size: 11.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.10.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 891db32f109b0e5806347a2e9c08f47ff694c091f926e88d441f84fe91f2e215 |
|
MD5 | f17a6f40f27ac0e28ee4ea39feb2650c |
|
BLAKE2b-256 | d4a90ad5957b80e3e555f17a324a329912c1abd81f7e19412524a4f1be57827b |