Slide 1

Slide 1 text

Building a Python API Creating a simple interface to Raspberry Pi hardware Ben Nuttall Raspberry Pi Foundation UK Charity 1129409

Slide 2

Slide 2 text

Ben Nuttall ● Education Developer Advocate at the Raspberry Pi Foundation – Learning resources – Picademy – Outreach – events and conferences – Software development – Creative Technologists programme – raspberrypi.org ● From the North ● piweekly.net

Slide 3

Slide 3 text

The Gertboard

Slide 4

Slide 4 text

Gertboard Software

Slide 5

Slide 5 text

Ryanteck RPi Motor Controller Board

Slide 6

Slide 6 text

Ryanteck RPi Motor Controller Board

Slide 7

Slide 7 text

Pimoroni - Pibrella

Slide 8

Slide 8 text

Pibrella Software import pibrella from time import sleep pibrella.light.green.on() sleep(1) pibrella.light.amber.on() sleep(1) pibrella.light.red.on()

Slide 9

Slide 9 text

Energenie – remote controlled power sockets

Slide 10

Slide 10 text

Energenie code

Slide 11

Slide 11 text

Energenie module import energenie from time import sleep energenie.switch_on() sleep(5) energenie.switch_off()

Slide 12

Slide 12 text

Energenie – web app pythonhosted.org/energenie /examples/web/

Slide 13

Slide 13 text

Chef HAT WIP – github.com/bennuttall/chef-hat pypi.python.org/pypi/chef-hat

Slide 14

Slide 14 text

Good examples

Slide 15

Slide 15 text

Sense HAT from sense_hat import SenseHat sense = SenseHat() temp = sense.temperature sense.show_message(“Temperature is %s ” % temp)

Slide 16

Slide 16 text

Who should create the API? ● The company who made the product – i.e. Their employed software developer ● The mug who bought the product and found there was no API – i.e. You

Slide 17

Slide 17 text

Why should we (the company) create the API? ● Make it easy for users to make amazing things with your product ● Show what your product is capable of ● Share example code

Slide 18

Slide 18 text

Why should I (the user) create the API? ● First, badger the company to make one – Or offer to help ● Or just do it – Especially if it's easy ● You want to use the product, don't you? ● Personal pros: – It's good experience – Makes your GitHub profile look good – Maybe they'll hire you – Maybe someone else will hire you

Slide 19

Slide 19 text

Python 2 or Python 3? ● Both ● Python 3 is the present and future of the language ● Python 2 is legacy, but easy to support along with Python 3 ● Always start with Python 3 – It's easier to go backwards than forwards ● If your package depends on a package which is Python 2 only – Request a Python 3 version – Make a Python 3 version and send a PR – Find an alternative package – Weep at the thought that your package doesn't work in Python 3 ● All examples here are for supporting both Python 3 and Python 2

Slide 20

Slide 20 text

How? 1. Write code to access your hardware 2. Design API (plan example usage) 3. Create abstraction layer – e.g. functions 4. Create a module from the code (simple structure of files) 5. Upload to GitHub (naturally) 6. Test installing your module 7. Upload to PyPI (Python Packaging Index) 8. Users can now “pip install” your module

Slide 21

Slide 21 text

Write some code ● Think of an example use of the product – How do you do it the long way? e.g. using RPi.GPIO – Implement it ● Repeat for some or all basic usage

Slide 22

Slide 22 text

Design the API ● What should users be able to do with the API? ● How do you want to use the API? ● Write example usage, e.g: hat = MyHat() hat.green.on() hat.red.on()

Slide 23

Slide 23 text

Create abstraction layer ● Combine the example code with the API design ● Consider code architecture (keep it as simple as possible) – Procedural approach – functions only – Object oriented approach – wrapper class around functions to maintain state – Break into multiple classes if necessary

Slide 24

Slide 24 text

Example – procedural approach # imports + setup... LED = 2 def turn_led_on(): GPIO.output(LED, True) def turn_led_off(): GPIO.output(LED, False)

Slide 25

Slide 25 text

Example – object oriented approach LED = 2 class MyHat(object): def __init__(self): GPIO.setup(LED, GPIO.OUT) def led_on(self): GPIO.output(LED, True) def led_off(self): GPIO.output(LED, False)

Slide 26

Slide 26 text

Example – advanced approach RED = 2 AMBER = 3 GREEN = 4 class LED(object): def __init__(self, pin): self.pin = pin GPIO.setup(self.pin, GPIO.OUT) def on(self): GPIO.output(self.pin, True) def off(self): GPIO.output(self.pin, False) class MyHat(object): def __init__(self): self.red = LED(RED) self.amber = LED(AMBER) self.green = LED(GREEN)

Slide 27

Slide 27 text

Main def main(): my_hat = MyHat() my_hat.green.on() if __name__ == '__main__': main()

Slide 28

Slide 28 text

Create a module (minimal) ├── my_hat │ ├── __init__.py │ └── my_hat.py ├── README.rst └── setup.py

Slide 29

Slide 29 text

Create a module (expanded) ├── CONTRIBUTING.md ├── docs │ └── index.md ├── LICENCE.txt ├── MANIFEST.in ├── my_hat │ ├── __init__.py │ └── my_hat.py ├── README.rst ├── scripts │ └── my_script ├── setup.py └── tests └── test_my_hat.py

Slide 30

Slide 30 text

my_hat/__init__.py from __future__ import absolute_import from .my_hat import MyHat __version__ = '0.1.0'

Slide 31

Slide 31 text

setup.py from setuptools import setup, find_packages ... setup( name="my­hat", version="0.1.0", author="Ben Nuttall", description="Simple API to My HAT", license="BSD", url="https://github.com/bennuttall/my_hat", packages=find_packages(), long_description=read('README.rst'), install_requires=[ "pillow", "numpy" ], ... )

Slide 32

Slide 32 text

Upload to GitHub ● Sign up to github.com ● Create a repository ● add, commit, push, etc. (use git properly) ● Include a licence (see choosealicense.com) ● Include a contributing policy (CONTRIBUTING.md)

Slide 33

Slide 33 text

Install the module ● sudo python3 setup.py install ● sudo python setup.py install

Slide 34

Slide 34 text

Check it installed correctly ● Test it's there – python3 ­c “import my_hat” – python ­c “import my_hat” ● Test it works – Python shell – Python file

Slide 35

Slide 35 text

Test the module ● Python file – Create a Python file with your example usage – Start by importing your module – Test outside of your project folder! – Do not name this file the same as your module! – python3 myfile.py – python myfile.py ● Python shell – Same guidelines apply

Slide 36

Slide 36 text

Upload to PyPI ● Install requirements – sudo apt­get install python3­dev python­dev twine ● Check the namespace is available – http://pypi.python.org/pypi/my-hat ● Sign up to PyPI ● Register the package name – via website or – sudo python3 setup.py register

Slide 37

Slide 37 text

Upload to PyPI ● Create source distribution – python3 setup.py sdist ● Create built distribution – python3 setup.py bdist [options] ● Read up on Python Wheels ● Likely you can use Universal Pure Python wheels: – python3 setup.py bdist_wheel --universal ● Both in one go – python3 setup.py sdist bdist_wheel ­­universal

Slide 38

Slide 38 text

Upload to PyPI ● See what was created – ls dist ● Built distribution (wheel) Source distribution ● my­hat­0.1.0­py2.py3­none­any.whl my­hat­0.1.0.tar.gz ● Upload! – twine upload dist/* ● Look it up on PyPI – http://pypi.python.org/pypi/my-hat

Slide 39

Slide 39 text

pip install ● sudo pip install my­hat ● sudo pip­3.2 install my­hat

Slide 40

Slide 40 text

Check it installed correctly ● Test it's there – python3 ­c “import my_hat” – python ­c “import my_hat” ● Test it works – Python shell – Python file

Slide 41

Slide 41 text

Documentation ● mkdocs - Documentation using markdown – See http://www.mkdocs.org/ – Examples: ● http://pyjok.es/ ● http://www.pythonhosted.org/sense-hat/ ● http://www.pythonhosted.org/energenie/ ● http://www.pythonhosted.org/rpi-greenhouse/ – Upload to pythonhosted.com via PyPI – Upload to GitHub Pages ● readthedocs - Documentation using ReStructured Text – See https://readthedocs.org/ – Example: https://picamera.readthedocs.org/

Slide 42

Slide 42 text

Good Examples ● Picamera – https://github.com/waveform80/picamera/ ● Anything by Dave Jones – https://github.com/waveform80 ● Sense HAT – https://github.com/RPi-Distro/python-sense-hat ● Energenie – https://github.com/RPi-Distro/python-energenie ● Explorer HAT – https://github.com/pimoroni/explorer-hat ● Anything by Pimoroni (Phil Howard) – https://github.com/pimoroni

Slide 43

Slide 43 text

Tips & Further Reading ● See “from future import X” for Python 3 features in Python 2 – https://docs.python.org/2/library/__future__.html ● Python Packaging User Guide – https://python-packaging-user-guide.readthedocs.org/en/latest/ ● Version sensibly – 1.1.0 1.1.1 1.1.2 1.1.3... (very minor changes) → → → – 1.1.6 1.2.0 (new features introduced or significant refactoring with API unchanged) → – 1.0.0 means feature complete – 1.3.5 2.0.0 (major change, breaks backwards compatibility) → ● Bump version number to alpha in testing locally – e.g. 3.1.4a0, 3.1.4a1, etc. ● Plan well – don't break backwards compatibility if you can avoid it

Slide 44

Slide 44 text

apt-get install? ● Packaging for Debian is hard work ● Packaging for PyPI is a good start ● See Debian packaging procedure – https://wiki.debian.org/Python/Packaging ● Good luck

Slide 45

Slide 45 text

Building a Python API Creating a simple interface to Raspberry Pi hardware Ben Nuttall Raspberry Pi Foundation UK Charity 1129409