Package a Python Project and Make it Available via pip install: Simple Example

Package a Python Project and Make it Available via pip install: Simple Example

Last updated:
Package a Python Project and Make it Available via pip install: Simple Example
Source
Table of Contents

Here is an example project built following the instructions on this post: Python Data Science Utils

For more information on what terms like pip, virtualenv, etc., mean see Python Environment Cheatsheet

sample setup.py file

File setup.py is the most important configuration file for your project. Here is an example to get you started:

# -*- coding: utf-8 -*-

import setuptools

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

setuptools.setup(
    name="myproject",
    version="0.0.1",                        # Update this for every new version
    author="Your name",
    author_email="your@email.com",
    description="long description",
    long_description=long_description,
    long_description_content_type="text/markdown",
    install_requires=[                      # Add project dependencies here
        "pandas>=0.20.0"                    # example: pandas version 0.20 or greater                          
    ],                                             
    url="https://github.com/your/github/project",  
    packages=setuptools.find_packages(),
    classifiers=(                                 # Classifiers help people find your 
        "Programming Language :: Python :: 3",    # projects. See all possible classifiers 
        "License :: OSI Approved :: MIT License", # in https://pypi.org/classifiers/
        "Operating System :: OS Independent",   
    ),
)

Project Structure

project-name/        <--- project name, does not need to match the inner name
│             
├── myproject        <--- module name, this is the name you'll use in "import"                   
│   ├── __init__.py  <--- init file must be here, even if your project is Python 3 only
│   └── module.py    <--- submodules
│ 
├── LICENSE          <--- optional but recommended  
│ 
├── README.md
│ 
└── setup.py         <--- package information. name, author, version, and DEPENDENCIES    

Package the project

To package the project, run python setup.py sdist bdist_wheel (preferably under a virtualenv):

(test-venv)$ python setup.py sdist bdist_wheel
running sdist
running egg_info
creating myproject.egg-info
writing requirements to myproject.egg-info/requires.txt
...
...

After running the packaging commands, your project should now look like this:

project-name/
│ 
├── build
│   ├── bdist.linux-x86_64
│   └── lib
│       └── myproject
│           ├── __init__.py
│           └── module.py 
├── dist                                     <--- this is the directory that
│   ├── myproject-0.0.1-py3-none-any.whl          will get uploaded to pypi
│   └── myproject-0.0.1.tar.gz
│ 
├── LICENSE
│ 
├── myproject
│   ├── __init__.py
│   └── module.py
│ 
├── myproject.egg-info
│   ├── dependency_links.txt
│   ├── PKG-INFO
│   ├── SOURCES.txt
│   └── top_level.txt
│ 
├── README.md
│ 
└── setup.py

Upload project to PyPi

Trying to upload the myproject project will fail because someone has already created a project on PyPi with that name!

To upload the project you need a tool called twine, which can be installed with pip:

(test-venv)$ pip install twine
Collecting twine
...
...

At this point, you should register an account on pypi.org so that you can upload packages.

After you created your account, you can upload the packaged files using: twine upload dist/*

The error message is expected because the name already exists. You should pick a unique project name.

(test-venv)$ twine upload dist/*
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: xxxxx
Enter your password: 
Uploading myproject-0.0.1-py3-none-any.whl
100%|████████████████████████████████████████████████████████| 4.52k/4.52k [00:00<00:00, 5.46kB/s]
HTTPError: 403 Client Error: The user 'xxxxx' isn't allowed to upload to project 'MyProject'. 
See https://pypi.org/help/#project-name for more information. for url: https://upload.pypi.org/legacy/

Congratulations! After uploading the project (as above), anyone can install your project via pip.

Troubleshooting

Can't import module

If you can't import the module you just uploaded, make sure you have an __init__.py file as in the instructions, even if your project is full Python 3!

Module 'pkg_resources' has no attribute 'iter_entry_points'

Force reinstall setuptools:

(venv)$ pip install --upgrade --force-reinstall setuptools

This short post is part of the Data Newsletter. Click here to sign up.


References