This week, I've published Silkie, my Python static site generator (SSG), to PyPI. It may seem daunting at first, but you can publish your own Python package by following these 5 steps.
Start
To avoid most painful misconfiguration, I organized my project to follow a standard directory structure:
silkie
├── LICENSE
├── README.md
├── pyproject.toml
├── requirements.txt
├── setup.cfg
├── silkie
│ ├── __init__.py
│ ├── __main__.py
│ ├── cli.py
│ ├── ...
├── tests
└── tox.ini
You might want to use Cookiecutter to set up a template for your Python project if you are starting from scratch.
We'll be uploading our package to PyPI, so we should have an account created on PyPI. In addition, you can also create another account on TestPyPI to test your package first before an official publication.
Configure
Setuptools, a popular and extensible library for packaging Python projects, seems like a perfect choice for my project. Configuration steps for it includes writing two files: pyproject.toml
and setup.cfg
.
The pyproject.toml
file simply declares the requirements for building our package:
[build-system]
requires = [
"setuptools>=42",
"wheel"
]
build-backend = "setuptools.build_meta"
Based on your project architecture, setup.cfg
can be configured accordingly. I think this tutorial does a better job explaining the details, so you should definitely check it out. As for Silkie, this is how I set it up:
[metadata]
name = silkie
version = 1.0.7
...
description = Static site generator with the smoothness of silk
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/oliver-pham/silkie
project_urls =
Bug Tracker = https://github.com/oliver-pham/silkie/issues
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent
[options]
packages = silkie
python_requires = >=3.9
install_requires =
click >= 8.0.0
markdown >= 3.3.0
yattag >= 1.14.0
python-frontmatter >= 1.0.0
[options.entry_points]
console_scripts =
silkie = silkie.cli:silkie
Some notes you may want to consider to avoid some misconfigurations (that I made):
-
packages
: I specifysilkie
directory directly because my project only has a single package. If you have multiple packages nested under a single directory, you should usefind:
and follow the instructions in Setuptools documentation -
install_requires
: specify all third-party dependencies that your project use. Simply put, anything that youpip install
and import in your code should be declared here
Build
Once you are done with configuration, let's build your Python package.
Before we can build it, make sure you have the latest version of build
installed on your machine.
$ pip install --upgrade build
Then, just run build in the root directory of your project:
$ python -m build
You should have a .whl
file and a .tar.gz
file inside your dist/
directory when the build process is completed.
Test
Before publishing your package, make sure that the newly built distribution contains all the necessary packages and files. You can run this command to see what's inside your distribution:
$ tar tzf <your-package-name>.tar.gz
Publish
To publish your Python package to PyPI, you must have twine
installed on your machine. You can install its latest version with pip
:
$ pip install --upgrade twine
Once it's installed, run this command to upload your distribution to TestPyPI for testing:
$ twine upload --repository TestPyPI dist/*
When prompted, you can either enter your account credentials or use an API token like this:
Enter your username: __token__
Enter your password: <your-API-token>
When your package can be uploaded to TestPyPI and installed on your local machine, you're ready to upload it to PyPI:
$ twine upload dist/*
Just like TestPyPI, your credentials or API token (for PyPI) can be used to authenticate your upload. Congratulations! You can now ask others to install and test your package.
As for Silkie, I've asked some of my friends to test the SSG. One of them found a critical bug due to a lack of testing. Another one suggested a piece of ASCII Art to me for Silkie, which was really nice. Overall, we have only tested it on Mac and Linux. If you happen to encounter any bug or issue while using Silkie, feel free to open an issue on GitHub.
Final thoughts
In general, I think publishing a Python package isn't really complex, but I was so nervous that I made a lot mistakes. It's fine if you mess up your release because you can always apply a new patch to it (unless your package is used by a majority of developers). Happy coding!
Top comments (0)