Build
Benefits of packaging
  • Dependency management, a package management system can automatically resolve dependencies and make your installation pain free and quick
  • Accounting, package managers can maintain lists of things installed and other metadata like the version installed etc.
  • Uninstall, push button ways of removing a package from your environment
  • Search, find packages by searching a package index for specific terminology
  • distutils & PyPI

    1. Edit setup.py
    2. Edit MANIFEST.in
    3. python setup.py sdist, create .tar.gz archive file under /dist folder
    4. python setup.py sdist upload (optional), upload the archive file to PyPI with your username and password
    5. Installation
      • python setup.py install, user download the code and install on their own computer
      • pip install project, install package from PyPI repository if the archive file has be deposited to PyPI

    README
    This is a simple example package. You can use
    [Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
    to write your content.
    		
    LICENSE, choose a license at Choose an open source license
    Copyright (c) 2018 The Python Packaging Authority
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.
    		
    setup.py
    from distutils.core import setup
    
    setup(
        name='ECSUProject_1', # a unique name for PyPI
        version='0.1',
        description='Demo for building a Python project',
        author='Lin Chen',
        author_email='lchen@ecsu.edu',
        url='http://lin-chen-va.github.io', # http://location or https://location
        packages=['myFormat', 'myFormat/sub', ], # packages and subpackages containing .py files
        package_data={'myFormat':['other/*']}, # other needed files will be installed for user
        py_modules=[], # individual modules
        scripts=['convert',], # the executable files will be installed for user
        license='Creative Commons Attribution-Noncommercial-Share Alike license',
        long_description=open('README').read(),
        # more meta-data for repository
        classifiers=[
          'Development Status :: 4 - Beta',
          'Environment :: X11 Applications :: GTK',
          'Intended Audience :: End Users/Desktop',
          'Intended Audience :: Developers',
          'License :: OSI Approved :: GNU General Public License (GPL)',
          'Operating System :: POSIX :: Linux',
          'Programming Language :: Python',
          'Topic :: Desktop Environment',
          'Topic :: Text Processing :: Fonts'
          ],
    )
    		
    By default, Distutils does not include all files in your project’s directory. Only the following files will be included by default
    MANIFEST.in, add other files that will be included in the archive file
    include README LICENSE
    recursive-include doc/_build/html *
    		
    python setup.py sdist, build an archive file (.tar.gz)

    Content in the archive file (.tar.gz)

    Installation
  • Download the archive file (.tar.gz) and unpack it
  • python setup.py install
  • import myFormat, import the installed package
  • convert, run the executable script
  • Deposite the archive file to PyPI
  • Register an account at pypi.org
  • Add a .pypirc file under $HOME directory
    [distutils]
    index-servers =
        pypi
    
    [pypi]
    repository: https://upload.pypi.org/legacy/
    username: yourUserName
    password: yourPassword
    		
  • python setup.py sdist upload, deposite the archive file to PyPI repository
  • pip install packageName, install the package from the PyPI repository
  • Options of distutils
  • python setup.py sdist, generate project.1.0.tar.gz for Mac and Linux
  • python setup.py bdist_wininst, generat project.1.0.exe for Windows
  • python setup.py bdist_rpm, generate a rpm distribution
  • python setup.py install, install a package
  • python setup.py develop, installs your package using a symlink to your development code
  • Different Layout

    setup.py
    from distutils.core import setup
    
    setup(
        name='ECSUProject_1',
        version='0.1',
        description='Demo for building a Python project',
        author='Lin Chen',
        author_email='lchen@ecsu.edu',
        url='http://lin-chen-va.github.io',
        packages=['myFormat', 'myFormat/sub', ],
        package_dir={'':'src'}, # set "src" as the root package
        package_data={'myFormat':['other/*']},
        scripts=['src/convert',],
        license='Creative Commons Attribution-Noncommercial-Share Alike license',
        long_description=open('README').read(),
        classifiers=[
          'Development Status :: 4 - Beta',
          'Environment :: X11 Applications :: GTK',
          'Intended Audience :: End Users/Desktop',
          'Intended Audience :: Developers',
          'License :: OSI Approved :: GNU General Public License (GPL)',
          'Operating System :: POSIX :: Linux',
          'Programming Language :: Python',
          'Topic :: Desktop Environment',
          'Topic :: Text Processing :: Fonts'
          ],
    )
    		
    setuptools and PyPI
  • distutils does not support dependencies well, even requires is an option of setup function
  • python setup.py install, the dependent modules will be installed
  • setup.py
    from setuptools import setup
    
    setup(
        name='ECSUProject_2',
        version='0.1',
        description='Demo for building a Python project',
        author='Lin Chen',
        author_email='lchen@ecsu.edu',
        url='http://lin-chen-va.github.io',
        install_requires=['numpy>=1.14.0', 'biopython>=1.60'], # add the dependencies
        packages=['myFormat', 'myFormat/sub', ],
        package_dir={'':'src'},
        package_data={'myFormat':['other/*']},
        scripts=['src/convert',],
        license='Creative Commons Attribution-Noncommercial-Share Alike license',
        long_description=open('README').read(),
        classifiers=[
          'Development Status :: 4 - Beta',
          'Environment :: X11 Applications :: GTK',
          'Intended Audience :: End Users/Desktop',
          'Intended Audience :: Developers',
          'License :: OSI Approved :: GNU General Public License (GPL)',
          'Operating System :: POSIX :: Linux',
          'Programming Language :: Python',
          'Topic :: Desktop Environment',
          'Topic :: Text Processing :: Fonts'
          ],
    )
    		
    setup.py and requirements

  • pip freeze > requirements.txt, create a simple list of all the packages in the current environment
  • setup.py
    from setuptools import setup
    
    with open('requirements.txt') as f:
        requirements = f.read().splitlines()
    
    setup(
        name='ECSUProject_2',
        version='0.1',
        description='Demo for building a Python project',
        author='Lin Chen',
        author_email='lchen@ecsu.edu',
        url='http://lin-chen-va.github.io',
        install_requires=requirements,
        packages=['myFormat', 'myFormat/sub', ],
        package_dir={'':'src'},
        package_data={'myFormat':['other/*']},
        scripts=['src/convert',],
        license='Creative Commons Attribution-Noncommercial-Share Alike license',
        long_description=open('README').read(),
        classifiers=[
          'Development Status :: 4 - Beta',
          'Environment :: X11 Applications :: GTK',
          'Intended Audience :: End Users/Desktop',
          'Intended Audience :: Developers',
          'License :: OSI Approved :: GNU General Public License (GPL)',
          'Operating System :: POSIX :: Linux',
          'Programming Language :: Python',
          'Topic :: Desktop Environment',
          'Topic :: Text Processing :: Fonts'
          ],
    )
    		
    MANIFEST.in
    include README LICENSE requirements.txt
    recursive-include doc/_build/html *
    		
  • python setup.py test, implement test code
  • python setup.py install, install modules and executable script
  • pyinstaller

  • Integrated needed external packages within the stand-alone executables
  • pyinstaller --onefile convert.py
  • Reference
  • pyinstaller
  • setuptools tutorial
  • An Introduction to Distutils
  • The Hitchhiker's Guide
  • Introduction to distutils
  • PyPI Documentation for Python 2
  • PyPI tutorial for Python 3