Package a Python Project and Make it Available via pip install: Simple ExampleLast updated:
- sample setup.py file
- Project Structure
- Package the project
- Upload project to PyPi
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
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="firstname.lastname@example.org", 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-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
myprojectproject 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.
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'
(venv)$ pip install --upgrade --force-reinstall setuptools
This short post is part of the Data Newsletter. Click here to sign up.