Skip to content

Instantly share code, notes, and snippets.

@nitred
Last active April 2, 2018 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitred/0764bfd72087946cab7c477395b24734 to your computer and use it in GitHub Desktop.
Save nitred/0764bfd72087946cab7c477395b24734 to your computer and use it in GitHub Desktop.
Release Protocol for Python Projects

About

This is the protocol to follow when either initializing a Python Package for the first time or when making a release of a Python Package.

Python Package Structure

Ideally use Protemplates to create a Python package. Link to Protemplates.

Installing Protemplates

  • Download the appropriate binary for your system.
  • Copy paste the protemplates binary into your /usr/local/bin directory.

Using Protemplates

$ cd /path/to/projects-dir/
$ protemplates create python

Initial Project Protocol

  1. Update README.md
    • Travis badge
    • Project description
    • Current stable version
    • Installation instructions for usage and development
    • Usage
    • Examples
    • Tests
    • License
    • Resources
  2. Update setup.py
    • Short description
    • Author
    • Author email
    • URL
    • Download URL
    • Python versions
    • Test requires
    • Install requires
  3. Update dev_environment.yml & requirements.txt
    • Add m2r, twine and Sphinx to dev_environment.yml only.
  4. Update LICENSE
  5. Update .travis.yml
  6. Update __init__.py version
  7. Update tests/test_basic.py
  8. Update examples
  9. Update Makefile
    • Create environment
    • Run tests
    • Readme to .rst (.md to .rst)
    • Upload to test Pypi
    • Upload Sphinx documentation to test Pypi
    • Upload to main Pypi
    • Upload Sphinx documentation to main Pypi

Release Protocol

  1. Update README.md
    • Update current stable version
    • Update examples
  2. Update setup.py
    • Update install requires
  3. Update dev_environment.yml & requirements.txt
  4. Update __init__.py version
  5. Update .travis.yml (if applicable)
  6. Update tests
  7. Update examples
# Ignore everything in this directory
*
# Except this file
!
!.gitignore
name: PROJECT_NAME
channels:
- defaults
dependencies:
- python=3.6.3
- pip:
- future
- twine
- m2r

examples/simple_PROJECT_NAME.py

"""Basic functionality."""
import nr_blockchain
MY-PROJECT relies on third-party software for many functionalities. Their respective complete licence terms can be found below. A summary of their license terms can also be found under the section `Summary of Third Party Licenses`.
# Summary of Third Party Licenses
* project-name-mit
* Copyright (c) <YEAR> <NAME>
* https://github.com/<username>/<project-name-mit>
* MIT License
* project-name-apache
* Copyright <YEAR> <NAME>
* https://github.com/<username>/<project-name-apache>
* Apache License 2.0
# Third Party Libraries with MIT License (MIT)
-----------------------------------------------------------------------------
The MIT License (MIT)
Applies to:
- project-name-mit, Copyright (c) <YEAR> <NAME>
- ...
-----------------------------------------------------------------------------
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.
# Third Party Libraries with Apache License, Version 2.0
-----------------------------------------------------------------------------
Apache License, Version 2.0
Applies to:
- project-name-apache, Copyright <YEAR> <NAME>
- ...
-----------------------------------------------------------------------------
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
MIT License
Copyright (c) 2018 NAME
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.
.DEFAULT_GOAL := help
help: ## Show available options with this Makefile
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'
.PHONY : test
test: ## Run all the tests
test:
python setup.py test
.PHONY : recreate_pyenv
recreate_pyenv: ## Create the python environment. Recreates if the env exists already.
recreate_pyenv:
conda env create --force -f dev_environment.yml
.PHONY : readme_to_rst
readme_to_rst: ## Convert README.md to README.rst for the sake of pip documentation.
readme_to_rst:
m2r --overwrite README.md
.PHONY : upload_test_pypi
upload_test_pypi: ## Build and upload distribution to testpypi server
upload_test_pypi: readme_to_rst
python setup.py sdist && \
twine upload --skip-existing --repository testpypi dist/*
.PHONY : upload_pypi
upload_pypi: ## Build and upload distribution to pypi server
upload_pypi: readme_to_rst
python setup.py sdist && \
twine upload --skip-existing --repository testpypi dist/*

PROJECT_NAME

Build Status

Short Description.

Current Stable Version

0.1.0

Installation

Pip

pip install PROJECT_NAME

Development Installation

  • Clone the project.
  • Install in Anaconda3 environment
     $ conda env create --force -f dev_environment.yml
     $ source activate PROJECT_NAME
     $ pip install -e .
    

Test

To run the tests:

make test

Usage

Examples

$ python examples/simple_PROJECT_NAME.py

License

MIT

[aliases]
test=pytest
[tool:pytest]
addopts = --verbose -vv --cov-report term-missing --cov nr_merkletree
import re
from codecs import open # To use a consistent encoding
from os import path
from setuptools import find_packages, setup
here = path.abspath(path.dirname(__file__))
# Get the long description from the relevant file
with open(path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = f.read()
# Get version without importing, which avoids dependency issues
def get_version():
with open('project_name/__init__.py') as version_file:
return re.search(r"""__version__\s+=\s+(['"])(?P<version>.+?)\1""",
version_file.read()).group('version')
install_requires = ['future', ] # Dependencies
test_requires = ['pytest', 'pytest-sugar', 'pytest-cov', ]
setup(
name='project-name',
description="Project description.",
long_description=long_description,
version=get_version(),
include_package_data=True,
install_requires=install_requires,
setup_requires=['pytest-runner'],
tests_require=test_requires,
packages=find_packages(),
zip_safe=False,
author="NAME <EMAIL ID>",
download_url="https://github.com/USERNAME/PROJECT_NAME/archive/{}.tar.gz".format(get_version()),
classifiers=[
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6", ]
)

tests/conftest.py

"""Bunch of fixtures to be used across the tests."""

import pytest


@pytest.fixture(scope="function")
def hello_world(request):
    """Create a test fixture."""
    hw = "Hello World!"

    def tear_down():
        # clean up here
        pass

    request.addfinalizer(tear_down)
    return hw

tests/test_init.py

"""Test __init__."""


def test_init(hello_world):
    """Run a test."""
    import PROJECT_NAME

    # Test __init__
    assert hasattr(PROJECT_NAME, '__version__')

    # Test pytest fixtures
    assert(hello_world == "Hello World!")
language: python
python:
- "3.5"
- "3.6"
# command to install dependencies
install:
- pip install -r requirements.txt
# command to run tests
script:
- python setup.py test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment