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.
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 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 specify
silkiedirectory directly because my project only has a single package. If you have multiple packages nested under a single directory, you should use
find:and follow the instructions in Setuptools documentation
install_requires: specify all third-party dependencies that your project use. Simply put, anything that you
pip installand import in your code should be declared here
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.
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
To publish your Python package to PyPI, you must have
twine installed on your machine. You can install its latest version with
$ 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.
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!