How to package and deploy your Python app to the PyPi package index
This is a TLDR summary on how to quickly package and deploy your Python application to the PyPi package index. See the full article over at python.org.

Project structure
packaging_tutorial/
├── LICENSE
├── pyproject.toml
├── README.md
├── setup.cfg
├── setup.py # optional, needed to make editable pip installs work
├── src/
│ └── pkg_name-/
│ └── __init__.py
└── tests/
Notes
Setup your project. The file structure should look something like the above. A quick rundown of the files:
-
setup.cfg - Static metadata
-
setup.py - dynamic metadata
-
pyproject.toml - tells build tools like pip, poetry what system you are using and what is required for a build.
Generate distribution archives
# install latest versions of PyPA’s
$ python3 -m pip install --upgrade build
# then run this in the same folder where pyproject.toml is located.
$ python3 -m build
The command should generate the following files in the dist directory:
dist/
pkg_name_here-0.0.1-py3-none-any.whl
pkg_name_here-0.0.1.tar.gz
Upload to the Python package index
Install twine and create an account at Test PyPI and create an API token.
TestPyPI is a separate instance of the package index for testing and experimentation.
# upgrade twine
$ python3 -m pip install --upgrade twine
# upload to the index.
$ python3 -m twine upload --repository testpypi dist/*
# You will be prompted for your username and password.
Uploading distributions to https://test.pypi.org/legacy/
Enter your username: [your username]
Enter your password:
Uploading pkg_name_here-0.0.1-py3-none-any.whl
100%|█████████████████████| 10.87k/10.87k [00:01<00:00, 5.88kB/s]
Uploading pkg_name_here-0.0.1.tar.gz
100%|█████████████████████| 5.22k/5.22k [00:01<00:00, 4.05kB/s]
Check that your package has been uploaded at for example at https://test.pypi.org/project/pkg_name_here.
Testing
Download and install your package.
$ python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps pkg-name-here==0.0.1
Looking in indexes: https://test.pypi.org/simple/
Collecting pkg-name-here==0.0.1
Downloading https://test-files.pythonhosted.org/packages/50/51/f38453224c89bc94dd9d975cd76be1a157e3a51981213ab11bb1026d4d63/vanty_installer-0.0.1-py3-none-any.whl (2.3 kB)
Installing collected packages: pkg-name-here
Successfully installed pkg-name-here-0.0.1
Notes
You will notice a couple of unusual flags in the shell command above.
-
--index-url - indicates which package index to use.
-
--no-deps - tells pip to ignore any dependencies.
Congratulations you have deployed your package. To upload to the live package index, sign up for an account at PyPI and repeat Step 4 above. Don't forget to remove the
--index-url
flag from your command.
Using Alternative Build Tools - (Poetry)
If you are using poetry as your build tool, you can use it to both package indexes and publish your project. Assuming you have already installed poetry, you can go back to Step 2 above and build your project.
# Build the project
$ poetry build
# Add pypitest as a repository and publish
$ poetry config repositories.testpypi https://test.pypi.org/legacy/
$ poetry publish --repository testpypi
Username: [username_but_not_in_brackets]
Password:
Publishing pkg-name-here (0.0.5) to testpypi
- Uploading pkg-name-here-0.0.5.tar.gz 100%
- Uploading pkg-name-here-0.0.5-py3-none-any.whl 100%
Using tokens for PyPy authentication:
### Publishing to PYPI Test
$ poetry config repositories.testpypi https://test.pypi.org/legacy/
$ export POETRY_PYPI_TOKEN_TESTPYPI=my-token
or
$ poetry config pypi-token.testpypi my-token
$ poetry publish -r testpypi
And that's it. For a more detailed article on how to use poetry check this article out .
Glossary Terms
-
Package index - A repository of distributions with a web interface to automate package discovery and consumption.
-
PyPI - the default Package Index for the Python community. It is open to all Python developers to consume and distribute their distributions.