Python tutorials > Deployment > Packaging > How to create `setup.py`?
How to create `setup.py`?
The setup.py
file is the cornerstone of Python packaging. It's used by setuptools
to build, distribute, and install your Python package. This tutorial will guide you through creating a functional setup.py
, explaining each component in detail.
Basic Structure of `setup.py`
This code snippet represents a basic setup.py
file. Let's break down each argument passed to the setup()
function:
name
: The name of your package. This should be unique on PyPI.version
: The current version of your package. Follow semantic versioning (SemVer) for best practices.packages
: A list of packages to include in your distribution. find_packages()
automatically discovers all packages and subpackages in your project. The include
argument allows you to specify which packages to include using wildcards.install_requires
: A list of dependencies required by your package. setuptools
will automatically install these when your package is installed.python_requires
: Specifies the minimum Python version required to run your package.author
: The author's name.author_email
: The author's email address.description
: A short, one-line description of your package.long_description
: A longer, more detailed description of your package. Typically read from a README.md
file.long_description_content_type
: Specifies the format of the long_description
(e.g., 'text/markdown' for Markdown).url
: The URL of your package's homepage (e.g., GitHub repository).license
: The license under which your package is distributed (e.g., 'MIT').classifiers
: A list of Trove classifiers that categorize your package. These help users find your package on PyPI. A full list can be found on the Python Package Index website.
from setuptools import setup, find_packages
setup(
name='your_package_name',
version='0.1.0',
packages=find_packages(include=['your_package_name', 'your_package_name.*']),
install_requires=[
'requests',
'numpy',
],
python_requires='>=3.6',
author='Your Name',
author_email='your.email@example.com',
description='A short description of your package',
long_description=open('README.md').read(),
long_description_content_type='text/markdown',
url='https://github.com/yourusername/your_package_name',
license='MIT',
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Topic :: Software Development :: Libraries',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
],
)
Concepts Behind the Snippet
The core concept is to describe your Python project's metadata and dependencies in a way that setuptools
can understand. This allows for easy installation and distribution using tools like pip
. The find_packages()
function is crucial for automatically including all your project's modules without having to manually list them.
Real-Life Use Case Section
Imagine you've developed a Python library for data analysis. Your setup.py
would specify numpy
, pandas
, and matplotlib
as install_requires
. When a user installs your library using pip install your_package
, these dependencies will be automatically installed alongside your library, ensuring that it functions correctly.
Best Practices
setup.py
.find_packages()
: Avoid manually listing packages unless you have a very specific reason to do so.requests>=2.20
) to ensure compatibility.README.md
: Provide a clear and comprehensive description of your package.
Interview Tip
Be prepared to explain the purpose of setup.py
and the role of setuptools
. Also, understand the difference between install_requires
and extras_require
. Demonstrate familiarity with best practices for Python packaging.
When to use them
You should use setup.py
whenever you want to create a reusable Python package that can be easily installed and distributed. This is essential for sharing your code with others and making it accessible through PyPI.
Alternatives
While setup.py
with setuptools
is the traditional approach, alternative packaging tools exist:
These tools often provide a higher-level interface and automate many of the tasks involved in packaging.
Adding Data Files
To include data files (e.g., configuration files, templates, or data sets) in your package, you can use the include_package_data
, package_data
, and data_files
arguments:
include_package_data=True
: Tells setuptools to automatically include any files matched by the MANIFEST.in
file.package_data
: A dictionary that maps package names to lists of filename patterns. These files will be installed within the package directory. For example, the code above includes all .txt
files in the data
directory and all .html
files in the templates
directory within the your_package_name
package.data_files
: A list of tuples, where each tuple contains an installation directory and a list of files to install in that directory. The installation directory is relative to the installation prefix (e.g., /usr/local
on Linux).
from setuptools import setup, find_packages
import os
setup(
name='your_package_name',
version='0.1.0',
packages=find_packages(include=['your_package_name', 'your_package_name.*']),
install_requires=[
'requests',
'numpy',
],
python_requires='>=3.6',
author='Your Name',
author_email='your.email@example.com',
description='A short description of your package',
long_description=open('README.md').read(),
long_description_content_type='text/markdown',
url='https://github.com/yourusername/your_package_name',
license='MIT',
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Topic :: Software Development :: Libraries',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
],
include_package_data=True,
package_data={'your_package_name': ['data/*.txt', 'templates/*.html']},
data_files=[('config', ['config/settings.ini'])]
)
FAQ
-
What is the purpose of `MANIFEST.in`?
The
MANIFEST.in
file is used to specify additional files to include in your package that are not automatically included bysetuptools
. This is often used for data files, documentation, or other non-code assets. You can specify patterns using wildcards (e.g.,include *.txt
). -
How do I handle versioning?
Use semantic versioning (SemVer). The version string should be in the format
MAJOR.MINOR.PATCH
. Increment the MAJOR version for incompatible API changes, the MINOR version for added functionality in a backwards-compatible manner, and the PATCH version for bug fixes. -
How to run tests during installation?
You can integrate testing into your setup process by using the
test_suite
ortests_require
arguments insetup.py
. Define a test suite or specify test dependencies. This allows running tests automatically when the package is installed or built.