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
  • 1. Setup files
  • Source Code
  • # get source code 
    git clone https://github.com/lin-chen-Langley/prime
    		

    README.md, recommend writing README.md file with Markdown syntax
    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.
    		
    requirements.txt
    pip freeze > requirements.txt
    		
  • include files in source distributions
  • MANIFEST.in, add other files that will be included in the archive file
    include README.md LICENSE requirements.txt
    recursive-include doc/_build/html *
    		
  • setup() args
  • name, project name used at PyPI or Conda
  • version, project version
  • author, author names
  • author_email, author emails
  • description, a brief summary of the project
  • long_description, detailed description of the project
  • long_description_content_type, content type, such as Markdown
  • url, the URL for the homepage of the project
  • project_urls, extra links
  • classifiers, additional metadata
  • install_requires, dependency packages
  • package_dir, package names and directories
  • packages, package names
  • python_requires, versions of Python required
  • scripts, executable scripts
  • license, license used in the project
  • setup.py, dynamic metadata
    import setuptools
     
    with open('requirements.txt') as f:
        requirements = f.read().splitlines()
     
    setuptools.setup(
        setup_requires=[
            'pytest-runner',
        ],
        tests_require=['pytest'],
        name='linlangleyprime', # a unique name for PyPI
        version='0.5',
        author='Lin Chen, Yanhua Feng',
        author_email='lin.chen@ieee.org, yf@vims.edu',
        description='Demo for building a Python project',
        long_description=open('README.md').read(),
        long_description_content_type="text/markdown",
        url='http://lin-chen-langley.github.io',
        project_urls = {
            'PyPI': 'https://pypi.org/manage/project/linlangleyprime/releases/',
            'Conda': 'https://anaconda.org/linchenVA/linlangleyprime'
            },
        classifiers=[ # list of classifiers at https://pypi.org/pypi?%3Aaction=list_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'
          ],
        install_requires=requirements,
        package_dir={'':'src'}, # location to find the packages
        packages=setuptools.find_packages(where="src"),
        #packages=['primepackage', ], # packages and subpackages containing .py files will be installed for users
        python_requires=">=3.9",
        scripts=['src/generator',], # executable files will be installed for users
        license='Creative Commons Attribution-Noncommercial-Share Alike license',
    )
    		
    setup.cfg, static metadata, contains option defaults for setup.py commands
    [aliases]
    test=pytest
    		
    2A. Publish Option 1 - Github
    # developer
    git push origin local_branch:remote_branch # push the code to the git repository, such as github
    		
    2B. Publish Option 2 - 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
    		
    # developer
    python setup.py sdist # build a source file (.tar.gz) in /dist folder
    twine upload dist/* # deposite the archive file to PyPI repository
    
    or
    
    python setup.py bdist_wheel # build a whl file in /dist folder
    twine upload dist/* # deposite the wheel file to PyPI repository
    		
    2C. Publish Option 3 - Pypi with pyproject.toml
    pyproject.toml
    [build-system]
    requires = [
        "setuptools>=42",
        "wheel"
    ]
    build-backend = "setuptools.build_meta"
    		
    python -m build # build source file (.tar.gz) and wheel file (.whl) in /dist folder
    twine upload dist/* # deposite the built files to PyPI repository
    		
    3. Installation
    # user installation from a git repository
    git clone url # download the code to local
    python setup.py install # install the executable program and packages
    
    python setup.py install --home='directory' # install to an alternative directory
    		
    # user installation from PyPI
    pip install linlangleyprime
    
    pip install --target='directory' linlangleyprime # install to an alternative directory
    		
    4. Implementation
    generator # run app
    
    import primepackage # import python package
    		
    5. Uninstall
    pip uninstall linlangleyprime
    		
    setuptools
    python setup.py --help-commands # get help
    
    python setup.py bdist # build a tar.gz file in /dist and conduct a installation in /build folder
    
    python setup.py bdist_rpm # create rpm Linux distribution
    or
    python setup.py bdist --formats=rpm
    
    python setup.py bdist_wininst # create exe distribution for Windows
    or
    python setup.py bdist --formats=wininst
    		
    git repository
    # install
    pip install git+https://github.com/lin-chen-Langley/prime
    
    # uninstall
    pip uninstall linlangleyprime
    		
    conda
  • Create Anaconda Account
  • conda install anaconda-client conda-build # install need modules
    		
    # for pip package
    # build
    python setup.py sdist #  build a source file (.tar.gz) in /dist folder
    
    # deposit
    anaconda upload dist/* # deposite the archive file to Conda repository
    
    # install
    pip install -i https://pypi.anaconda.org/linchenva/simple linlangleyprime
    
    # uninstall
    pip uninstall linlangleyprime
    		
    # for a package existing at PyPI
    # 1. create meta.yaml
    conda skeleton pypi linlangleyprime # create a meta.yaml in /linlangleyprime folder
    
    # 2. build
    conda-build linlangleyprime # create ~/anaconda3/envs/[environment_name]/conda-bld/osx-64/linlangleyprime-0.3-py39_0.tar.bz2
    
    # 3. deposit
    anaconda upload ~/anaconda3/envs/[environment_name]/conda-bld/osx-64/linlangleyprime-0.3-py39_0.tar.bz2
    
    # 4. install
    conda install -c linchenva linlangleyprime
    
    # 5. uninstall
    conda install linlangleyprime
    		
    # meta.yaml
    {% set name = "linlangleyprime" %}
    {% set version = "0.3" %}
    
    package:
      name: "{{ name|lower }}"
      version: "{{ version }}"
    
    source:
      url: "https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz"
      sha256: 5c7c41ba47d6b0226a4d66e3be34642298c64e7c8ea1d9675cefd0a7a6f4d7e0
    
    build:
      number: 0
      script: "{{ PYTHON }} -m pip install . -vv"
    
    requirements:
      host:
        - certifi ==2020.12.5
        - pip
        - python
      run:
        - certifi ==2020.12.5
        - python
    
    test:
      imports:
        - primepackage
    
    about:
      home: "http://lin-chen-va.github.io"
      license: "GNU General Public (GPL)"
      license_family: LGPL
      license_file:
      summary: "Demo for building a Python project"
      doc_url:
      dev_url:
    
    extra:
      recipe-maintainers:
        - your-github-id-here
    		
    # for a package at a git repository
    # 1. create meta.yaml in /linlangleyprime folder
    
    # 2. build
    conda-build linlangleyprime # create ~/anaconda3/envs/[environment_name]/conda-bld/osx-64/linlangleyprime-0.3-py39_0.tar.bz2
    
    # 3. deposit
    anaconda upload ~/anaconda3/envs/[environment_name]/conda-bld/osx-64/linlangleyprime-0.3-py39_0.tar.bz2
    
    # 4. install
    conda install -c linchenva linlangleyprime
    
    # 5. uninstall
    conda install linlangleyprime
    		
    # meta.yaml
    {% set name = "linlangleyprime" %}
    {% set version = "0.3" %}
    
    package:
      name: "{{ name|lower }}"
      version: "{{ version }}"
    
    source:
      git_rev: master
      git_url: https://github.com/lin-chen-Langley/prime
    
    build:
      number: 0
      script: "{{ PYTHON }} -m pip install . -vv"
    
    requirements:
      host:
        - certifi ==2020.12.5
        - pip
        - python
      run:
        - certifi ==2020.12.5
        - python
    
    test:
      imports:
        - primepackage
    
    about:
      home: "http://lin-chen-langley.github.io"
      license: "GNU General Public (GPL)"
      license_family: LGPL
      license_file:
      summary: "Demo for building a Python project"
      doc_url:
      dev_url:
    
    extra:
      recipe-maintainers:
        - your-github-id-here
    		
    pyinstaller
  • App is self-contained
  • Users do not need to have Python installed at all
  • Distribute an application for more than one OS, for example both Windows and Mac OS X, must install PyInstaller on each platform and bundle the app separately on each
  • # hello.py
    import pandas
    
    def f():
        print('Hello World!')
    
    if __name__ == '__main__':
        f()
    		
    # create one folder app
    pyinstaller hello.py 
    # create /build, log file and working files
    # create /dist, hello executable folder
    # create hello.spec
    
    # deliver /dist/hello folder to user, which contain executable file and dependencies
    		
    # implementation
    ./hello/hello
    		
    # create one file app
    pyinstaller --onefile hello.py
    		
    # optimization
    python -OO -m PyInstaller hello.py
    
    python -O -m PyInstaller --onefile hello.py # -OO may not work
    		
    # options
    -h, help
    -v, version
    --onedir, create one folder app
    --onefile, create one file app
    		
    Reference
  • layout
  • conda
  • setuptools
  • pyinstaller