AboutWhat I doProjectsContact
Blog·MLOps·01/07/2026·2 min

Publishing ten CLIs on PyPI: what nobody tells you

Names already taken, a new-project limit that is not in the documentation, and why the package name does not have to match the command name. Notes from publishing a full suite of tools.

Publishing ten CLIs on PyPI: what nobody tells you

I had ten command-line tools with tests, CI and READMEs, and I thought publishing them on PyPI was the easy part: uv build, uv publish, next. The technical part is. What I did not expect was everything else.

The good names are taken (or almost). Three of my names already existed on PyPI, and a fourth — mlenv — was rejected for being too similar to an existing project, an anti-typosquatting rule I did not know about. The fix has a trick to it: the distribution name and the command name are independent things. The package is called mlenv-cli, but what you type in the terminal is still mlenv. You install pip install mlenv-cli, you run mlenv. Four of my ten tools live like that, with a package name different from the command.

There is a new-project limit, and it is not documented where you look. From the fourth or fifth new project in a short window, PyPI answers 429 Too many new projects created. It is not per second or per hour: it is a cap on new project creation with a long cooldown, hours to days. Publishing a whole suite at once is not the intended use case. If you plan to launch several tools, budget for publishing them in batches over several days, not in one afternoon.

The README gets written before you know the final name. A direct consequence of the above: my READMEs said pip install mlenv weeks before I found out the package would be called mlenv-cli. The moral is to reserve the name early — publishing a minimal 0.1.0 costs little — or not to commit the install command to writing until the name is confirmed.

For the next releases: trusted publishing. Publishing with an API token works, but the token is a long-lived secret someone can leak. GitHub Actions can publish to PyPI with no secret at all using OIDC: PyPI trusts the specific repository and workflow you authorise. You configure it once per project and releases become a git tag. For a ten-package suite, the maintenance difference is enormous.

None of this is hard; all of it is friction that does not show up in tutorials. If you are about to publish your first tool, let this be the checklist: name reserved early, install command written with the real name, batches if there are several, and OIDC so you never manage tokens.

Shall we connect?

Let's talk: feedback, collaboration or an opportunity.

You can write to me about a project, a technical question, to give me feedback, or about an internship or a first junior role. I always reply.

Write to me

Keep reading:

hola@jmwebsoluciones.com