Upgrading Legacy SetupTools to PyProject TOML for PyPi Packages

in DevTalklast year


hitesh-choudhary-pMnw5BSZYsA-unsplash.jpg
Photo by Hitesh Choudhary on Unsplash

If you've been a Python developer for sometime...

You might have hoarded so much utils that you ought to re-use in every projects you build.

Python allows you to publish open source packages on PyPi, so you can have a version-controlled project, lessening the breakage compared to copy-pasting classes, methods, and/or functions from different projects that you manage!

What is PyPi?

PyPi stands for Python Package Index, it is basically the go-to magic hat for Python developers and hobbyists alike! It is home to 418,710 projects including several other trusted and powerful Data Analytics, Visualization, and Machine Learning libraries known to the industry.

Leveraging open source and readily available software can speed up your development process compared to building from scratch. This is where the heart of open source through contributions from anyone in the community.

Python allows you to install third-party libraries from servers such as PyPi through pip which is the de-facto tool to install Python packages, although several other methods and tools are available.

pip install package-name

Once installed successfully, depending on the package, you can import it on your Python scripts and/or directly use it on the command-line.

Publishing in PyPi

Before being able to uploading anything to PyPi, it requires a verified account and have generated API tokens saved to your PC user directory.

On the top-level, there is a very little difference between the legacy and the recent changes in the process of uploading packages to PyPi.

Before, the project metadata is directly fed to the setuptools.setup() method as parameters, but right now, the approach will still go through but will generate warnings along the process. Still, you can still continue using setuptools, but you should do some minor changes starting by creating a new TOML file in the root of the project directory, equivalent to the data found in the original Python file.

Previously, the package information is stored in the setup.py file containing something like the script below.

import setuptools

with open("README.md", "r") as f:
    long_description = f.read()

setuptools.setup(
    name = "<package-name>",
    packages = ["<package-name>"],
    version = "x.y.z",
    license="...",
    description = "...",
    long_description=long_description,
    long_description_content_type="text/markdown",
    author = "<author-name>",
    author_email = "[email protected]",
    url = "<repo-url>",
    download_url = "...",
    keywords = [],
    install_requires=[],
    classifiers=[
        "Development Status :: 5 - Production/Stable",
        "Intended Audience :: Developers", 
        "Topic :: Software Development :: Build Tools",
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 3"
    ],
    python_requires=">=3.10"
)

TOML is a distant relative of JSON and CONFIG files, but is closer to YAML. It is an alternative means to store data, but in a less programmatic way and more in a user-friendly way.

Using TOML was originally specified under PEP-621 and the canonical specification is actively maintained on the PyPA specifications page. The shift was generally for simplicity, ease-of-use, and interoperability.

The

It allows for the project metadata to be reusable by various other software that will try to access it.

TOML and Further Setup

Different builders might require a subtle difference in TOML contents, but refer again to the PyPA specifications page for the standard and core metadata for your pyproject.toml file.

Currently, PyPa endorses Hatchling, setuptools, Flit, and PDM as options for building the project for PyPi.

Hatchling

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

setuptools

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

Flit

[build-system]
requires = ["flit_core>=3.2"]
build-backend = "flit_core.buildapi"

PDM

[build-system]
requires = ["pdm-pep517"]
build-backend = "pdm.pep517.api"

If you opt to continue using setuptools, refer here to follow more about the configuration using pyproject.toml files. I prefer PDM for my setup.

After filling up the TOML metadata, it should look like as presented below.

[build-system]
requires = ["pdm-pep517"]
build-backend = "pdm.pep517.api"

[project]
name = "<package-name>"
version = "x.y.z"
description = "..."
readme = "README.md"
requires-python = ">=3.10"
license = {file = "LICENSE.txt"}
keywords = []
authors = [
    { name="<author-name>" },
    { email="[email protected]" }
]
classifiers = [
    "Development Status :: 5 - Production/Stable",
    "Intended Audience :: Developers",
    "Topic :: Software Development :: Build Tools",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3",
]

dependencies = []

[project.urls]
homepage = "<repo-url>"
documentation = "https://<package-name>.readthedocs.io"

Additional installs are required aside from the selected builder, such as build and twine packages.

pip install -U wheel
pip install -U build
pip install -U twine

Before continuing make sure your project is organized well and have been fully documented and tested to avoid messy and buggy projects.

Generating a New Distribution Archive
Check once again if the project version x.y.z was update appropriately. Once everything is ready, run the commands below to generate new distribution archives.

rm -fr dist/*
py -m build --sdist --wheel --outdir dist/

Uploading the Distribution Archive to PyPi
After successfully generating the distribution archive, run the code below to upload it to PyPi.

py -m twine upload dist/*

Alongside, PyPi, you should also commit your changes to your repository such as GitHub. And that's it! Wait for a few seconds up to a minute and the project can be successfully install via pip anywhere in the world.

For more information about PyPi, visit the help page or to the Packaging Python page for the complete walkthrough, FAQs and other helpful links to further readings.

Do you have questions or want to connect? Just comment or DM me :)





 
Rydeon ⟠
 
Sup frens, Rydeon here!

I do nerd-stuff to feed the wallet, relatable? I live in Cebu City, but most of the time inside the computer. Frequently doing Python, Analytics, ML, and always coffee. I've been to blockchains and cryptocurrencies for some time already, but it would be dumb and risky to share unreliable financial advice. So, don't ask me.

Thinking of following? I'll gonna resume writing about time-waster games, awesome technology, and the cafés I went to connect to their Wi-Fi. g2g...



Sort:  

Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!

Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).

You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support. 
 

Congratulations @avid.serosik! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You received more than 300 upvotes.
Your next target is to reach 400 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out the last post from @hivebuzz:

HiveBuzz World Cup Contest - Recap of Day 11
Be ready for the last Hive Power Up Month of the year!
Hive Power Up Day - December 1st 2022
Support the HiveBuzz project. Vote for our proposal!