How to Package Your Python Code. A simple guide to packaging your python… | by Nacho Vargas | Apr, 2022

In case you simply need the step-by-step information, please skip forward.

Packaging your code is principally making it accessible for use by others. Or making it able to be shared principally…

What does that truly imply? Effectively in Python it means the creation of a tar.gz file with every little thing your venture wants (known as the source archive) and extra importantly, a wheel distribution file (known as the built distribution) which is what we name the precise distribution.

the results of packaging a python code

Why 2 information?

The principle distribution is the .whl file (wheel construct distribution). The tar.gz file is used as a fall again by pip if wanted when putting in the .whl file.

What’s Wheel and what’s the Construct distribution?

A construct distribution is a file containing every little thing your venture must run in one other laptop together with metadata reminiscent of title, model, licence, and many others.

Wheel is a construct distribution format launched by PEP 427 (meant to interchange the Egg format).

Observe that the model is all the time included within the file names. It is because a distribution is versioned, that means a number of variations of the identical bundle can and will exist. These are known as releases.

That is the format of the distribution file title:
distribution-version(-build tag)?-python tag-abi tag-platform tag.whl

Okay! we now know what packaging is, very cool, however…

If you need your bundle to be accessible to everybody, then we use the Python Bundle Index (PyPi).

If you want on your bundle for use internally by your self, your pals, or coworkers, you want a non-public index reminiscent of JFrog’s artifactory.

I’ll clarify the best way to add our bundle to each of those…

As soon as uploaded to any of those indices, your bundle shall be accessible to be downloaded (utilizing pip for instance) and utilized by others.

To place issues into perspective, there are 3 predominant elements in place when distributing a Python bundle:

  • Bundle format: The supply distribution we talked about earlier than. The wheel is an instance of a format.
  • Bundle index: A central place the place packages are saved and managed. There are public ones and personal ones.
    Public: PyPI
    Non-public: JFrog has one for instance, however you can even host your personal.
  • Bundle supervisor: A software program that’s in command of getting the requested distribution from an index and putting in the wheel into you laptop. A traditional instance is pip, however there are others like build.

Okay, sufficient principle…

Let’s bundle a small pattern code!

We’ll use setuptools so every little thing shall be advisable based on their suggestions.

setuptools is a library which is constructed on high of distutils(that has been deprecated). The bundle presents a variety of performance that facilitates packaging of Python tasks.

Okay, first the venture construction:

venture construction

The goal code right here lives inside my_awesome_module. The title of the module is vital as a result of it’s what shall be imported by others.

Yup… Easy sufficient…

Now we want a technique to inform construct instruments some details about our bundle. To do that, setuptools makes use of 3 information:

  • pyproject.toml: A file that tells construct instruments (like pip and build) what’s required to construct your venture.
  • setup.cfg: The configuration file for setuptools. It tells setuptools about your bundle (such because the title and model) in addition to which code information to incorporate.
  • The construct script for setuptools. It may possibly maintain the identical metadata as setup.cfg however its dynamic not static, and permits the execution of packaging instructions.


This text makes use of setuptools, so open pyproject.toml and enter the next content material:

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


Along with the setup.pythat is the primary file the place your configuration is saved.

Setuptools permits utilizing configuration information (normally setup.cfg) to outline a bundle’s metadata and different choices which can be usually provided to the setup() operate (declarative config).

title = my_own_custom_package
model = 0.0.1
writer = You
author_email =
description = A small instance bundle
long_description = file:
long_description_content_type = textual content/markdown
url =
classifiers =
Programming Language :: Python :: 3
Working System :: OS Unbiased
license_files = LICENSE.txt
install_requires =
package_dir == src
packages = discover:
python_requires = >=3.6
the place = src

Key objects:

  • title — The title of your bundle. That is what you’ll pip set up <package_name>
  • modelPresent model of your bundle. Essential to extend this on each change
  • descriptions — Description of the bundle. You may seek advice from your file additionally like within the instance.
  • packager_dir and packages — The packages that your bundle embody. On this instance, embody every little thing contained in the src module.
  • install_requires — Defines the packages your bundle must run, on this instance I’ve added a traditional Python bundle: requests

A full record of accessible objects might be discovered here.

The file might be a very powerful file that’s imagined to be included on the root your Python venture listing and it largely serves two major functions:

  1. It may possibly include varied info related to your bundle together with choices and metadata, reminiscent of bundle title, model, writer, license, minimal dependencies, entry factors, information information and lots of extra. (That is advisable to be contained within the setup.cfg as we noticed).
  2. Serves because the command line interface that allows the execution of packaging instructions.

As is advisable by setup-tools, we maintain the metadata within the setup.cgf so our seems like this:

from setuptools import setupif __name__ == '__main__':

easy proper?

Lets bundle it…

Be sure you have the newest model of PyPA’s build put in:

python3 -m pip set up --upgrade construct
py -m pip set up --upgrade construct

Now let’s construct:

python3 -m construct
py -m construct
constructing the bundle

Completed! you need to find yourself with one thing like this:

discover the brand new dir folder

We’ve discovered what it means to bundle our code, and if you happen to adopted the final half, we’ve now the packaged information for our superior Python code.

Nice, now let’s add it so it may possibly really be utilized by others…


On this article, we are going to use the testing server of PyPi which is a separate occasion of the bundle index supposed for testing.

To register an account, go here and full the steps on that web page. Additionally, you will must confirm your e mail deal with earlier than you’re in a position to add any packages. For extra particulars, see Using TestPyPI.

Now that you’re registered, you should utilize twine to add the distribution packages. You’ll want to put in Twine:

python3 -m pip set up --upgrade twine

py -m pip set up --upgrade twine


The twine command to push the bundle will ask for authentication clearly. There are 3 methods of doing this:

1. Use your e mail and password (nice for testing)

2. Create an API Token and use it immediately.
Create one here, setting the Scope to Whole account. Don’t shut the web page till you’ve copied and saved the token — you received’t see that token once more.
Username and password are the identical as within the part under.

3. Create an API Token and retailer it in your twine conf (advisable)
After you’ve the token, arrange a$HOME/.pypirc file like this:

username = __token__
password = <your-token-including-the-pypi-prefix>

Okay, let’s run Twine to add all the archives underneath dist .

python3 -m twine add --repository testpypi dist/*
py -m twine add --repository testpypi dist/*

In case you didn’t setup your twine conf, you may be prompted for a username and password. Authenticate accordingly.

After the command completes, you need to see output much like this:

And if you happen to go to your projects in TestPyPi, you’ll se your new bundle!

You might be completed! Anybody can now use the bundle in opposition to TestPyPi working:

pip set up my-own-custom-package

* Observe that pip have to be configured to level to TestPyPi.

The steps to deploy to precise PyPi are precisely the identical simply deploy to pypi as a substitute of testpypi :

python3 -m twine add --repository pypi dist/*
py -m twine add --repository pypi dist/*


You may have your very personal Python bundle deployed and prepared for use in PyPi! Go test it out!


Here you may see my very own deployment of this check code into PyPi.

Import it and use it

I’ll use the one I published, however please try to use the one you simply revealed into PyPi or TestPyPi.

pip set up my_awesome_package

Now anybody can use it of their code:

from my_awesome_module import good dayif __name__ == "__main__":
good day.say_hello("Nacho")

Observe that the import bundle is my_awesome_module no matter what title you gave your distribution bundle in setup.cfg or (on this case, my_awesome_package).

output of the instance above.

Non-public Index (JFrog Artifactory)

First create a JFrog Account and add a brand new Python Artifactory repo.

Observe: JFrog presents a free cloud answer to host packages in addition to different issues like docker pictures, and many others.
That being stated, it additionally has paid plans, so see what plan matches your wants. For this text (and in some work eventualities as properly) I went for a free plan.

After you’ve your repository in place in JFrog, create a .pypirc file in your root folder and add this to it:

index-servers = native
repository: http://localhost:8081/artifactory/api/pypi/pypi
username: <user_name>
password: <password>

native might be modified to something. Remember to change it within the following command.

Then run this to deploy your bundle:

python3 -m twine add -r native dist/* --config-file ~/.pypirc
py -m twine add -r native dist/* --config-file ~/.pypirc

That’s it! GO and see your bundle in your repo.

Discover the total particulars for these on the JFrog manual.

More Posts