Slide 1

Slide 1 text

Maintaining an open source Python library Ben Nuttall Raspberry Pi Foundation UK charity 1129409

Slide 2

Slide 2 text

Standing on the shoulders of many giants Ben Nuttall Raspberry Pi Foundation UK charity 1129409

Slide 3

Slide 3 text

@ben_nuttall Ben Nuttall  Community Manager at the Raspberry Pi Foundation  Based in Cambridge, UK  Columnist and moderator for opensource.com  Creator of GPIO Zero Python library and the piwheels project

Slide 4

Slide 4 text

@ben_nuttall Distributing software – how? Package managers: ● Linux – apt, rpm, yum ● Language package managers – pip, npm, gem ● Linux portable – snap, flatpak, AppImage ● Mac – homebrew Download from sites: ● GitHub, GitLab, Sourceforge ● Personal websites

Slide 5

Slide 5 text

@ben_nuttall Distributing software – why? ● Ease of access ● Expectations ● Trust and confidence ● Stability

Slide 6

Slide 6 text

@ben_nuttall Writing a Python module . └── project.py

Slide 7

Slide 7 text

@ben_nuttall Packaging a Python module . ├── project │   ├── ├── __init__.py │   ├── └── project.py ├── README.rst └── setup.py

Slide 8

Slide 8 text

@ben_nuttall Packaging a Python module import os from setuptools import setup, find_packages def read(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read() setup( name="project", version="0.1.0", author="Ben Nuttall", description="Example project", license="MIT", keywords=["sample", "project"], url="https://github.com/bennuttall/project", packages=find_packages(), long_description=read('README.rst'), )

Slide 9

Slide 9 text

@ben_nuttall Creating a distribution ben@magicman:~/project $ python3 setup.py sdist running sdist ... ben@magicman:~/project $ ls build dist project project.egg-info README.rst setup.py ben@magicman:~/project $ ls dist/ project-0.1.0.tar.gz

Slide 10

Slide 10 text

@ben_nuttall Creating a distribution ben@magicman:~/project $ python3 setup.py sdist bdist_wheel running sdist ... ben@magicman:~/project $ ls dist/ project-0.1.0-py3-none-any.whl project-0.1.0.tar.gz

Slide 11

Slide 11 text

@ben_nuttall Distributing a Python module pi@raspberrypi:~ $ sudo pip3 install project-0.1.0-py3-none- any.whl

Slide 12

Slide 12 text

@ben_nuttall Publishing a Python module on PyPI ● Register an account on pypi.org ● Put your account details in ~/.pypirc: ben@magicman:~ $ cat .pypirc [pypi] username: bennuttall password: correcthorsebatterystaple ● Install Twine: ● pip install twine

Slide 13

Slide 13 text

@ben_nuttall Publishing a Python module on PyPI ben@magicman:~/project $ twine upload dist/* Uploading distributions to https://upload.pypi.org/legacy/

Slide 14

Slide 14 text

@ben_nuttall Publishing a Python module on PyPI

Slide 15

Slide 15 text

@ben_nuttall Platform wheels

Slide 16

Slide 16 text

@ben_nuttall Licensing ● It’s important to choose a licence for a project ● It’s important to specify which licence ● It’s important to include the licence with the source code and distributions ● Refer to choosealicense.com

Slide 17

Slide 17 text

@ben_nuttall Virtualenv ● Virtual environment for a Python project ● You create the environment, pip install into it ● Build your project inside it, with changes "installed" in real time sudo apt-get install build-essential virtualenv python3-dev python3-virtualenv -y git clone https://github.com/rpi-distro/python-gpiozero virtualenv -p python3 gpiozero-env source gpiozero-env/bin/activate cd python-gpiozero python setup.py develop pip install ipython rpi.gpio

Slide 18

Slide 18 text

@ben_nuttall Testing ● Write tests to validate what your code is supposed to do ● Keep your old tests to make sure nothing breaks in future ● For maximum effect, write tests before you write code! ● Testing can be performed quickly locally ● Testing can be automated – e.g. Travis after commit/push/merge

Slide 19

Slide 19 text

@ben_nuttall Testing - assert from project import add assert add(2, 2) == 4

Slide 20

Slide 20 text

@ben_nuttall Testing - pytest from project import add import pytest assert add(2, 2) == 4 with pytest.raises(TypeError): add("foo", "bar")

Slide 21

Slide 21 text

@ben_nuttall Testing - mock def test_timeofday_value(mock_factory): with TimeOfDay(time(7), time(8), utc=False) as tod: assert repr(tod).startswith('

Slide 22

Slide 22 text

@ben_nuttall Tox ● Run tests in multiple Python versions simultaneously ● tox.ini: [tox] envlist = {py27,py32,py33,py34,py35,py36,py37}

Slide 23

Slide 23 text

@ben_nuttall Coverage Coverage.py is a tool for measuring code coverage of Python programs. It monitors your program, noting which parts of the code have been executed, then analyzes the source to identify code that could have been executed but was not. Coverage measurement is typically used to gauge the effectiveness of tests. It can show which parts of your code are being exercised by tests, and which are not.

Slide 24

Slide 24 text

@ben_nuttall Coverage

Slide 25

Slide 25 text

@ben_nuttall Testing – Travis CI

Slide 26

Slide 26 text

@ben_nuttall GitHub

Slide 27

Slide 27 text

@ben_nuttall GitHub - collaborators

Slide 28

Slide 28 text

@ben_nuttall GitHub - branches

Slide 29

Slide 29 text

@ben_nuttall GitHub - releases

Slide 30

Slide 30 text

@ben_nuttall GitHub - issues

Slide 31

Slide 31 text

@ben_nuttall GitHub - pull requests

Slide 32

Slide 32 text

@ben_nuttall GitHub - project boards

Slide 33

Slide 33 text

@ben_nuttall GitHub - integrations

Slide 34

Slide 34 text

@ben_nuttall Documentation ● User API documentation, how to install, examples ● Developer documentation for contributors (and you!)

Slide 35

Slide 35 text

@ben_nuttall Documentation - GitHub

Slide 36

Slide 36 text

@ben_nuttall Documentation - Markdown # Title Some text ## Header 2 - List item - [link](http://foo.com/)

Slide 37

Slide 37 text

@ben_nuttall Documentation - mkdocs ● Markdown-based documentation builder ● Exports to static HTML ● Easy to write, easy to deploy ● Can host anywhere – e.g. GitHub pages or self-hosted

Slide 38

Slide 38 text

@ben_nuttall Documentation – ReST (ReStructured Text) ===== Title ===== Some text Header 2 ======== * List item * :doc:`api_input`

Slide 39

Slide 39 text

@ben_nuttall Documentation - sphinx ● ReST ● Extracts docs from docstrings ● Can embed additional bespoke docs ● Multiple outputs: ● HTML ● PDF ● Epub ● Language docs linking (e.g. gpiozero can link to Python docs using ReST) ● Cross-project linking (e.g. gpiozero can link to picamera using ReST)

Slide 40

Slide 40 text

@ben_nuttall Documentation - sphinx Regular Classes =============== The following classes are intended for general use with the devices they represent. All classes in this section are concrete (not abstract). LED --- .. autoclass:: LED(pin, \*, active_high=True, initial_value=False, pin_factory=None) :members: on, off, toggle, blink, pin, is_lit, value PWMLED ------ .. autoclass:: PWMLED(pin, \*, active_high=True, initial_value=0, frequency=100, pin_factory=None) :members: on, off, toggle, blink, pulse, pin, is_lit, value

Slide 41

Slide 41 text

@ben_nuttall Documentation - ReadTheDocs ● Multiple versions (v1.0, v1.1, v1.2...) ● Branches ● Multi-user management ● Easy to integrate with GitHub to automate building

Slide 42

Slide 42 text

@ben_nuttall Documentation - Graphviz

Slide 43

Slide 43 text

@ben_nuttall Documentation - Graphviz digraph { graph [rankdir=RL]; node [shape=rect, style=filled, color="#2980b9", fontname=Sans, fontcolor="#ffffff", fontsize=10]; edge [arrowhead=normal, style=solid]; Button -> LED; }

Slide 44

Slide 44 text

@ben_nuttall Documentation - Graphviz digraph { graph [rankdir=RL]; edge [arrowhead=normal, style=solid]; /* Devices */ node [shape=rect, style=filled, color="#2980b9", fontname=Sans, fontcolor="#ffffff", fontsize=10]; led [label="Garden light"] light [label="Light sensor"] motion [label="Motion sensor"] /* functions */ node [shape=oval, style=filled, color="#9ec6e0", fontcolor="#ffffff"]; booleanized all_values all_values -> led; booleanized -> all_values; motion -> all_values; light -> booleanized; }

Slide 45

Slide 45 text

@ben_nuttall Documentation - Graphviz

Slide 46

Slide 46 text

Maintaining an open source Python library Ben Nuttall Raspberry Pi Foundation UK charity 1129409