Project

General

Profile

Support #924

Packaging a Python App

Added by Daniel Curtis almost 7 years ago. Updated almost 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Development Environment
Target version:
Start date:
03/05/2018
Due date:
% Done:

100%

Estimated time:
1.00 h
Spent time:

Description

I recently developed a Python 3.6 app and wanted to package it for distribution to other users. This is a guide on packaging a python app using setuptools. This project uses twisted as an example dependency and include additional folders inside the python module.

This guide uses Arch Linux as its development environment, use the appropriate package manager for your distribution.

For the purpose of this guide, the folder structure of the example app is as follows:

/example-app
 |__ /example-app
      |-- __init__.py
      |__ /main
           |-- __init__.py
           |-- main.py
      |__ /templates
           |-- main
                 |-- index.html
      |__ ..
      |__ .
 |-- setup.py
 |-- README.txt

Prepare the Environment

  • Since this requires setuptools, add it along with a couple other dependencies:
    pacman -S python3 python3-{pip,pkgconfig,setuptools,virtualenv}
    

Packaging the App

  • First get a list of all the dependent modules for the app:
    pip freeze > requirements.txt
    
  • Then display the module depenencies for the next step:
    cat requirements.txt
    
    • Example:
      attrs==17.4.0
      Automat==0.6.0
      constantly==15.1.0
      hyperlink==17.3.1
      incremental==17.5.0
      six==1.11.0
      Twisted==17.9.0
      zope.interface==4.4.3
      
  • Then add the setup.py file if it does not already exist:
    vi setup.py
    
    • And add the following, adjusting the package dependencies as necessary:
      from setuptools import setup
      
      setup(
          name='example-app',
          version='0.1',
          description='Just another example app',
          author='Daniel Curtis',
          author_email='support@example.com',
          license='BSD-2-Clause',
          packages=['example-app'],
          install_requires=[
              'attrs==17.4.0',
              'Automat==0.6.0',
              'constantly==15.1.0',
              'hyperlink==17.3.1',
              'incremental==17.5.0',
              'six==1.11.0',
              'Twisted==17.9.0',
              'zope.interface==4.4.3'
          ],
          zip_safe=False
      )
      
  • Create the source distribution file:
    python setup.py sdist
    

Now a tar.gz file of the app has been created in the dist/ folder.

WARNING: By default the sdist function will not add files recursively. So when the app is installed via pip, the only files available will be python files in the example-app module folder, no subdirectories.

Packaging Recursive Directories

Since this project has files in the main and templates subdirectories, having setuptools recurse through the module directory would be helpful.

  • Edit the setup.py file:
    vi setup.py
    
    • And add the package_files() function and add the package_data parameter to the setup():
      from setuptools import setup
      import os
      
      def package_files(directory):
          paths = []
          for (path, directories, filenames) in os.walk(directory):
              for filename in filenames:
                  paths.append(os.path.join('..', path, filename))
      
          return paths
      
      extra_files = []
      extra_files += package_files('example-app')
      
      setup(
          name='example-app',
          version='0.1',
          description='Just another example app.',
          author='Daniel Curtis',
          author_email='support@example.com',
          license='BSD-2-Clause',
          packages=['example-app'],
          package_data={'': extra_files},
          install_requires=[
              'attrs==17.4.0',
              'Automat==0.6.0',
              'constantly==15.1.0',
              'crc16==0.1.1',
              'hyperlink==17.3.1',
              'incremental==17.5.0',
              'numpy==1.14.1',
              'pyserial==3.4',
              'six==1.11.0',
              'Twisted==17.9.0',
              'zope.interface==4.4.3'
          ],
          zip_safe=False
      )
      
  • Recreate the source distribution file:
    python setup.py sdist
    

Test Installing

  • Create a virtualenv:
    mkdir -p ~/venv
    virtualenv ~/venv/example-app
    
  • Activate the virtualenv:
    source ~/venv/example-app/bin/activate
    
  • Install the source distribution file:
    pip install dist/example-app-0.1.tar.gz
    

Uploading to PyPI

  • Register an account with Python Packaging Index, following the instructions at the prompt:
    python setup.py register
    
  • Once registered, login to upload the source distribution file:
    python setup.py sdist upload
    

Resources

Also available in: Atom PDF