This is a quick guide for create and generate distribution package of your python project so that others can install, import and use in their projects.
You will need the following tools installed in your computer:
- Python (2.x/3.x)
- API key for uploading your package to distribution platform, such as test.pypi.org.
After install python, you can install pip by using:
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python get-pip.py
python3 -m pip install --user --upgrade setuptools wheel
Create folder structure
Suppose that you want to create a package under the name
example_pkg, then you can create the following folder structure:
packaging_tutorial/ example_pkg/ __init__.py
packaging_tutorial is the project root directory. All your code will be place in
__init__.py can simply be an empty file or can be used to import the directory as a package.
setup.py is the important file that contains the configuration of the package, e.g. package name, version etc. If you want to add
README.md and LICENSE file, then also place them in the root folder.
packaging_tutorial/ example_pkg/ __init__.py your_other_files.py setup.py LICENSE README.md
Next, you will edit
setup.py by your favorite editor. The file contain 3 mains parts:
- import tools
- Display License or ReadMe
import setuptools with open("README.md", "r") as fh: long_description = fh.read() setuptools.setup( name="example-pkg-YOUR-USERNAME-HERE", # Replace with your own username version="0.0.1", author="Example Author", author_email="email@example.com", description="A small example package", long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/pypa/sampleproject", packages=setuptools.find_packages(), classifiers=[ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], python_requires='>=3.6', )
This example package uses a relatively minimal set:
nameis the distribution name of your package. This can be any name as long as only contains letters, numbers,
-. It also must not already be taken on pypi.org. Be sure to update this with your username, as this ensures you won’t try to upload a package with the same name as one which already exists when you upload the package.
versionis the package version see PEP 440 for more details on versions.
author_emailare used to identify the author of the package.
descriptionis a short, one-sentence summary of the package.
long_descriptionis a detailed description of the package. This is shown on the package detail package on the Python Package Index. In this case, the long description is loaded from
README.mdwhich is a common pattern.
long_description_content_typetells the index what type of markup is used for the long description. In this case, it’s Markdown.
urlis the URL for the homepage of the project. For many projects, this will just be a link to GitHub, GitLab, Bitbucket, or similar code hosting service.
packagesis a list of all Python import packages that should be included in the distribution package. Instead of listing each package manually, we can use
find_packages()to automatically discover all packages and subpackages. In this case, the list of packages will be example_pkg as that’s the only package present.
classifiersgives the index and pip some additional metadata about your package. In this case, the package is only compatible with Python 3, is licensed under the MIT license, and is OS-independent. You should always include at least which version(s) of Python your package works on, which license your package is available under, and which operating systems your package will work on. For a complete list of classifiers, see https://pypi.org/classifiers/.
Generating distribution archives
When everything is ready, it is time for generating distribution packages by runing this command from the same directory where
setup.py is located:
python3 setup.py sdist bdist_wheel
This command should output a lot of text and once completed should generate two files in the
dist/ example_pkg_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl example_pkg_YOUR_USERNAME_HERE-0.0.1.tar.gz
Uploading the distribution archives
Ignore this if you don’t want to distribute your package online. Otherwise, if you use pypi.org, you can follow their tutorial to create one.
- Register an API token
- Upload the archives
Go to https://test.pypi.org/manage/account/#api-tokens and create a new API token; don’t limit its scope to a particular project, since you are creating a new project. API tokens provide an alternative way (instead of username and password) to authenticate when uploading packages to PyPI.
Don’t close the page until you have copied and saved the token — you won’t see that token again.
You can create a token for an entire PyPI account, in which case, the token will work for all projects associated with that account. Alternatively, you can limit a token’s scope to a specific project.
We strongly recommend you authenticate with an API token where possible.
To make an API token:
- Verify your email address (check your account settings)
- In your account settings, go to the API tokens section and select “Add API token”
To use an API token:
- Set your username to
- Set your password to the token value, including the
Where you edit or add these values will depend on your individual use case. For example, some users may need to edit their
.pypirc file, while others may need to update their CI configuration file (e.g.
.travis.yml if you are using Travis).
Advanced users may wish to inspect their token by decoding it with base64, and checking the output against the unique identifier displayed on PyPI.
Now that you are registered, you can use twine to upload the distribution packages. You’ll need to install Twine:
python3 -m pip install --user --upgrade twine
Once installed, run Twine to upload all of the archives under
python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
You will be prompted for a username and password. For the username, use
__token__. For the password, use the token value, including the
pypi- prefix. After the command completes, you should see output similar to this:
Uploading distributions to https://test.pypi.org/legacy/ Enter your username: [your username] Enter your password: Uploading example_pkg_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl 100%|█████████████████████| 4.65k/4.65k [00:01<00:00, 3.88kB/s] Uploading example_pkg_YOUR_USERNAME_HERE-0.0.1.tar.gz 100%|█████████████████████| 4.25k/4.25k [00:01<00:00, 4.05kB/s]
Once uploaded your package should be viewable on TestPyPI, for example, https://test.pypi.org/project/example-pkg-YOUR-USERNAME-HERE
Congratulations, you’ve packaged and distributed a Python project!
Keep in mind that this tutorial showed you how to upload your package to Test PyPI, which isn’t a permanent storage. The Test system occasionally deletes packages and accounts. It is best to use Test PyPI for testing and experiments like this tutorial.