Joseph P. Vantassel, jpvantassel.com
- A Python package is a module or collection of modules inside a directory with
a module named
__init__.py(note this module is typically empty). - A Python package may contain any number of sub packages (i.e., sub-directories
with their own
__init__.py). - A Python package can be combined into a distribution package using the
setuptoolsmodule and asetup.pyfile (details on a typicalsetup.pyare listed here). - The Python Package Authority (PyPA) has created the Python Package Users Guide (PyPUG) as the definitive reference for building and using Python packages.
A Python package is a module or collection of modules that has/have been bundled
together for some purpose. Modules are simply saved
Python code stored in a text file with a .py extension. The package in a
literal sense is simply a directory containing the desired modules to be
packaged and an additional module __init__.py (often referred to as a dunder
init), which may be and generally is empty.
The main benefit of packages is that they can combine multiple modules together and be built into what is called a distribution package. Distribution packages are what is being installed when you use pip.
There are two ways in which distribution packages can be released either as source or pre-built.
- Source Distributions - As-is Python code rolled into a compressed tarball. Will install on any architecture running a compliant version of Python.
- Built Distributions - Partially interpreted Python code. The old
style of built distributions were
bdist_eggwhich have since been replaced bybdist_wheel.
The built distribution bdist_wheel is the more common and can be one of three
types.
- Universal - Distribution will run on Python 2 and 3.
- Pure Python - Distribution is version specific and will run on Python 2 or 3, but not both.
- Platform - Distribution will run only on certain operating systems (e.g., OS X or Windows).
To transform your collection of code into a module, you will need the following:
- Required Items
- A directory with the same name as your package, inside of which is your
source code and an
__init__.py. This directory may also contain sub packages (i.e., sub-directories with their own source code and__init__.py). - A
setup.py, details on this file are shown below.
- A directory with the same name as your package, inside of which is your
source code and an
- Optional (but still important)
- A
README.mdorREADME.rstto explain what your package is all about. - A
LICENCEfile explain how and for what your code may be used. Refer to choosealicense.com for help on selecting a license. - A
./testdirectory for all of your unittests.
- A
- Optional (slightly less important)
- A
./docsdirectory where the documentation for your package is stored. - A
requirements.txtfile listing the packages required for developers (not for users, dependencies for users are handled in thesetup.py).
- A
After the code itself, the setup.py file is the mode important part of a
Python package. An example setup.py file is shown below with comments for
clarifications.
from setuptools import setup, find_packages
setup(
name='my_sample_project', # Name of package, should match src directory.
version='0.1.0', # major.minor.micro refer to PEP440.
description='Example package', # Short one-liner description.
long_description='Long description for PyPI project page. ...',
url='example_dot_com', # Url for more info or link to documentation.
author='Joseph P. Vantassel', # Author name
author_email='jvantassel@utexas.edu', # Author email
liscence='GPLv3', # License information
# For full listing of classifiers see (https://pypi.org/classifiers/).
classifiers=[
'Development Status :: 2 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: GPLv3',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
],
keywords='example practice', # Space separated keywords to improve search on PyPI.
packages=find_packages(exclude=['docs', 'tests*']), # Have setuptools find the package.
install_requires=['requests'], # User installation dependencies.
package_data={
'sample' : ['package_data.dat'] # Extra data needed to use the package.
}
data_files=None # Specify absolute path.
]
entry_points={
'console_scripts':[
'hello=example:say_hello', # Creates cmd line wrapper for package.
],
}
)After having gone through the effort of packaging your Python code, you will inevitably what to share it with others. You can do this in multiple ways.
Sharing a built or source distribution is simple and involves two steps.
- Creating the source and/or built distribution, using the syntax
python setup.py sdistfor sourcepython setup.py bdist_wheelfor built, orpython setup.py sdist bdist_wheelfor both.
- Installing from the source or built distribution, using the syntax
pip install <*.tar.gz>if from source orpip install <*.whl>if from built.
Good documentation for this can be found on PyPI.