See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed · Editable canvas, not a picture
The renderer and its allowlist
PyPI renders long_description with readme_renderer, the library the Warehouse codebase uses for exactly this, and cleans the resulting HTML against an allowlist. Script, style and iframe elements do not survive that pass. The img element does, which is what makes a rendered diagram possible on a project page at all.
The content type has to match the markup. Set long_description_content_type to text/markdown for a Markdown README, or text/x-rst for reStructuredText. Get it wrong and PyPI displays the description as preformatted plain text, image line included, which is a distinctive and easily recognised failure.
There is no interactive option here. Put the image on the page and a link next to it for anyone who wants pan and zoom in a browser tab.
Relative paths have nothing to resolve against
A PyPI project page has no repository context. There is no branch, no raw host, no base URL to complete ./docs/architecture.png into something fetchable, so a relative image is a request for a file that does not exist on pypi.org. GitHub makes this easy to miss, because the same README renders correctly there.
Use an absolute https address. The https part matters as much as the absolute part: project pages are served over https, so an http image is blocked as mixed content by every current browser and shows nothing.
The same rule applies to badges, screenshots and any linked asset in the description. One absolute-URL policy for the whole README file removes an entire class of release-day embarrassment.
<!-- Renders on GitHub, blank on PyPI -->  <!-- Renders on both, and keeps up between releases --> 
The description is fixed for the release
PyPI does not accept a re-upload of a version that already exists, so a description cannot be corrected in place. A broken image line lives on the project page until the next release, or until someone takes the drastic route of deleting the release entirely.
That constraint is the argument for an image URL rather than a committed file, sharpened. The description text is frozen the moment the version is uploaded, and the picture behind an address is not. A project whose last release was six months ago can still show what its architecture looks like this week.
Run twine check on the built distribution before uploading. It runs the description through readme_renderer and fails on markup PyPI would reject, which catches the content-type mistake and malformed markup before they become permanent.
python -m build python -m twine check dist/*
What the diagram should show for a library
A package page reader is deciding whether this library fits their system, so the useful picture is the runtime one: what the package connects to, which services it calls, where data ends up. A module tree answers a question nobody is asking at that moment.
For a package that wraps a platform, showing the platform is often the point. Datadef ships 2,098 provider icons as individual SVGs: 439 for AWS, 624 for Azure, 226 for Google Cloud, and the remainder across data tooling, Kubernetes, networking and general infrastructure. A wrapper around Snowflake or Kafka draws with the Snowflake and Kafka marks, so the picture on the project page reads as the systems it names rather than as a row of grey boxes with words in them.
Keeping it current without a release
Connect the repository read-only from GitHub, GitLab or Azure DevOps, choose a branch or tag, and the sync regenerates the diagram and an architecture.md daily. The image behind the address on your project page follows, no upload involved.
The image endpoint sends Cache-Control public, max-age=300, stale-while-revalidate=86400, and an ETag built from the canvas id, its updated timestamp and the requested size, so an edited diagram reaches readers within about five minutes, a reader who arrives during the next twenty-four hours is served the cached render while a fresh one is built behind them, and a repeat visitor gets a 304 rather than a re-render. The same address belongs in the repository README and in the docs site, so all three agree. See embedding documentation.
FAQ
Why is my README image not showing on PyPI?
Can I fix a broken image in a PyPI description without a new release?
Does PyPI allow iframes or scripts in a project description?
Can a PyPI project page show a diagram that changes after the release?
Do readers need an account to view the linked diagram?