Steps for new Python library or package

Here are the steps.

Create repo on github with license, gitignore and readme stubs.

Clone the repo in the work area.

Lets say, my new library is called new-library

new-library is the repo name.

Inside the cloned repo, create virtual env by running:
pipenv install --python 3.8

Above step creates a virtualenv using python 3.8 (already installed on my system)

now install all the required packages. The basic ones I always install are:
pytest, pytest-cov, typing, codecov, mypy and flake8

pipenv shell

pipenv install pytest pytest-cov typing codecov mypy flake8


# IDE dirs

to .gitignore

create a directory called new-library (inside the directory new-library .. this is also the repo). Inside this, create a file called new-library is now a Python package. I tend to have my blank.

lets create a file called inside this directory so that we have something to work with.

from typing import Union
from decimal import Decimal
import warnings

Dint = Union[Decimal, int]

class Currency:
    """Handles money per specified currency"""

    __slots__ = ('amount', 'currency')

    def __init__(self, amount: Dint, currency: str) -> None:
        if isinstance(amount, float):
                SyntaxWarning(  # pragma: no cover
                    'float value detected. Please use Decimal instead.'
        self.amount = amount
        self.currency = currency.upper() or 'USD'

    def __str__(self) -> str:
        return f'{str(self.amount)} {self.currency}'

Now lets create a tests directory right under the repo directory (called new-library). This tests directory is at the same level as .gitignore and files.
Inside this directory, create Then create a file called

import pytest

from new-library.currency import Currency

def test_str():
    currency = Currency(5, 'USD')
    assert str(currency) == '5 USD'

Now create a .coveragerc file to configure code coverage. This file is also at the root level (same level as .gitignore)

branch = 1
omit = */test*.py
source = new-library

exclude_lines =
    pragma: no cover
    raise NotImplementedError
    return NotImplemented

Now create a setup.cfg file where you can put configuration details. Again at the root.

description-file =

exclude = .git,*migrations*,
max-line-length = 79

Now create a file. Again at root level.

from distutils.core import setup
    name='new-library',         # How you named your package folder (MyLib)
    packages=['new-library'],   # Chose the same as "name"
    version='1.0',      # Start with a small number and increase it with every change you make
    license='MIT',        # Chose a license from here:
    description='Handles money',   # Give a short description about your library
    author='tek shinobi',                   # Type in your name
    author_email='',      # Type in your E-Mail
    url='',   # Provide either the link to your github or to your website
    keywords=['money', 'currency'],   # Keywords that define your package best
    install_requires=[            # I get to this in a second
        'Development Status :: 3 - Alpha',      # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package
        'Intended Audience :: Developers',      # Define that your audience are developers
        'Topic :: Software Development :: Libraries :: Python Modules',
        'License :: OSI Approved :: MIT License',   # Again, pick a license
        'Programming Language :: Python :: 3',      # Specify which python versions that you want to support
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.8',
        'Operating System :: OS Independent',

Now, lastly create .travis.yml file. Again at root level.

language: python
  - 3.6
  - 3.8
  - pip install pipenv
  - pipenv install
  - python install
  - pip install mypy pytest pytest-cov flake8
  - pip install codecov
  - flake8 new-library
  - pytest --cov
  - mypy new-library --ignore-missing-imports
  - codecov

Don’t forget to register and enable the repo in Travis CI dashboard before checking in the project. Now, after you check in all changes to github, you will see that build gets triggered in travis.

locally, you can run the tests with coverage using:
pytest --cov=new-library tests/

You can check the compile with type safety:
mypy new-library --ignore-missing-imports

You can check linting:
flake8 new-library

Steps for PyPi package

first install check-manifest for creating
pipenv install --dev check-manifest

create a source distribution for PyPi
python sdist

now check the distribution created for all the files:
tar tzf dist/read-only-attributes-1.0.tar.gz

It will be missing Pipfile, Pipfile.lock and LICENSE files. You need to create a to include these files.
check-manifest --create

Now re-create source distribution to include the files listed in the and then check to see that the are in the dist
python sdist
tar tzf dist/read-only-attributes-1.0.tar.gz

Now we are ready to publish it.
So lets build the .whl distribution file for PyPi
python bdist_wheel sdist

check the dist folder to ensure that .gz and .whl files were created
ls dist/

Now we are ready to upload to PyPi.
Since we need twine to upload to PyPi, install it first
pipenv install --dev twine

now upload it:
twine upload dist/*

No Comments

You can leave the first : )

Leave a Reply

Your email address will not be published. Required fields are marked *