A.I, Data and Software Engineering

Create and distribute your python package

C

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.

Prerequisites:

You will need the following tools installed in your computer:

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

Note: get-pip.py also installs setuptools 2 and wheel if they are not already ! We will later use these tools to install our package. You can update these tools to the latest version using:

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

where packaging_tutorial is the project root directory. All your code will be place in example_pkg, and __init__.py can simply be an empty file or can be used to import the directory as a package.

The 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

Creating setup.py

Next, you will edit setup.py by your favorite editor. The file contain 3 mains parts:

  • import tools
  • Display License or ReadMe
  • Configuration
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="author@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:

  • name is the distribution name of your package. This can be any name as long as only contains letters, numbers, _ , and -. 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.
  • version is the package version see PEP 440 for more details on versions.
  • author and author_email are used to identify the author of the package.
  • description is a short, one-sentence summary of the package.
  • long_description is 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.md which is a common pattern.
  • long_description_content_type tells the index what type of markup is used for the long description. In this case, it’s Markdown.
  • url is 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.
  • packages is 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.
  • classifiers gives 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 directory:

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:

To use an API token:

  • Set your username to __token__
  • Set your password to the token value, including the pypi- prefix

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 dist:

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

Wrapping up

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.

Add comment

💬

A.I, Data and Software Engineering

PetaMinds focuses on developing the coolest topics in data science, A.I, and programming, and make them so digestible for everyone to learn and create amazing applications in a short time.

Categories