Publishing a Python package used to feel like a small battle: setup.py rituals, half-forgotten twine commands, and the anxiety of accidentally pushing a broken release to PyPI. Thankfully, modern tooling has cleaned all of this up.
With uv, publishing a Python package is fast, minimal, and refreshingly boring. In this article, we’ll walk through how to publish a Python package using uv and a PyPI API token, end to end, without unnecessary ceremony.
If you already know Python and want a clean, modern publishing flow, this guide will feel right at home.
Table of Contents
- What is uv and Why Use It?
- Prerequisites
- Project Structure
- Configuring pyproject.toml
- Creating a PyPI API Token
- Publishing with uv
- Common Pitfalls
- Key Takeaways
- Conclusion
What is uv and Why Use It?
uv is a modern Python toolchain written in Rust that replaces a whole collection of traditional tools like pip, virtualenv, pip-tools, and parts of setuptools.
Why uv is gaining serious traction:
- Extremely fast dependency resolution
- First-class support for pyproject.toml
- Clean build and publish workflows
- Fewer configuration files and fewer surprises
In short: less tooling drama, more shipping.
Prerequisites
Before publishing your package, make sure you have:
- Python 3.8 or newer
- A PyPI account
- uv installed on your system
- A package that actually imports and runs
To install uv:
curl -Ls https://astral.sh/uv/install.sh | sh
Project Structure
A clean project structure avoids confusion and keeps PyPI happy. A minimal recommended layout looks like this:
my_package/
├── src/
│ └── my_package/
│ ├── init.py
│ └── core.py
├── README.md
├── pyproject.toml
└── LICENSE
Important notes:
- Use the src layout to avoid import bugs
- The package name must be importable
- README.md becomes your PyPI project description
Configuring pyproject.toml
The pyproject.toml file is the single source of truth for modern Python packaging. A minimal and solid configuration looks like this:
[project]
name = "my-package"
version = "0.1.0"
description = "A small but useful Python package"
readme = "README.md"
requires-python = ">=3.9"
license = { text = "MIT" }
authors = [
{ name = "Your Name", email = "you@example.com" }
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
This setup avoids legacy tooling and works perfectly with uv.
Creating a PyPI API Token
Uploading with a username and password is deprecated. PyPI strongly recommends using API tokens instead.
Steps:
- Log in to PyPI
- Go to Account Settings → API tokens
- Create a new token
- Choose either full-account access or project-specific access
- Copy the token immediately
The token will look something like this:
pypi-AgEIcHlwaS5vcmcCJ…
Publishing with uv
Build your package:
uv build
This generates both a source distribution and a wheel.
Finally, publish to PyPI:
uv publish
Create a token in pypi.
Add your username as __token__ and your actual token as the password.
If everything is configured correctly, your package will be live within seconds.
Common Pitfalls
Even with great tooling, a few mistakes still show up often:
- Forgetting to bump the version number
- Choosing a package name that already exists on PyPI
- Broken Markdown in the README
- Missing
__init__.py files in the package
Catching these early saves a lot of frustration.
Key Takeaways
- uv simplifies Python packaging dramatically
- pyproject.toml is all you need for configuration
- PyPI API tokens are safer and automation-friendly
- Publishing can be boring, fast, and reliable
Conclusion
Publishing Python packages no longer needs to feel fragile or ceremonial. With uv, the workflow is fast, modern, and predictable. You write code, declare metadata, run two commands, and ship.
Once you’ve used this flow a few times, going back to older tooling feels unnecessary.
Happy packaging.
Suggested Posts
Simple JSON parser without knowing anything beforehands
Table of Content Introduction Scanning the text Looking for specific characters Identifying element...
How to get gemini response as json using python and google genai
Normally you can tune models to return json. But, fortunately, Gemini First install the lib pip inst...
How to Install Azure Cli on Linux Mint 22 / Wilma
Follow any installing azure cli on Linux mint tutorial, but, on the step below add noble main instea...