Python API

Overview

Due to supporting both the HTTP and serial APIs, and due to the goal of exposing everything that’s deemed useful, the Python API is a bit more complex than you might have expected. Here is a (simplified) bird’s eye view:

        classDiagram
    direction TD

    class Shocker {
        +shock()
        +vibrate()
        +beep()
        +info()
    }

    class HTTPShocker {
        +sharecode
        +name
        +log_name

        +pause()
    }

    class SerialShocker {
        +shocker_id

        +end()
    }

    class PiShockAPI {
        +username
        +api_key

        +get_shockers()
        +request()
        +verify_credentials()
    }

    class SerialAPI {
        +dev

        +...()
    }

    PiShockAPI -- HTTPShocker : api.shocker()
    Shocker <|-- HTTPShocker
    SerialAPI -- SerialShocker : api.shocker()
    Shocker <|-- SerialShocker
    

For sending shocks/vibrates/beeps, you will have to get a Shocker based on either the HTTP API or a PiShock attched via USB serial.

Getting a Shocker via HTTP API

To get a shocker using the PiShock.com HTTP API, you will need to:

thus:

from pishock import PiShockAPI

username = "..."   # from pishock.com
api_key = "..."    # https://pishock.com/#/account
sharecode = "..."  # https://pishock.com/#/control (share button)

api = PiShockAPI(username, api_key)
shocker = api.shocker(sharecode)

Getting a Shocker via Serial API

To get a shocker for a PiShock device attached via USB, you will need to:

thus:

from pishock import SerialAPI

shocker_id = 1234  # https://pishock.com/#/control (cogwheel button)

api = SerialAPI()
shocker = api.shocker(shocker_id)

Using the Shocker

Once you did so, you will be able to call Shocker.vibrate(), Shocker.shock() and Shocker.beep() on them for the basic operations:

shocker.vibrate(duration=1, intensity=10)

A HTTPShocker also supports .pause() in order to pause/unpause the shocker.

Finally, both classes support calling Shocker.info() to get info about a shocker. However, note that the SerialShocker will only provide BasicShockerInfo, while the HTTP API provides DetailedShockerInfo (which adds max_intensity and max_duration).

>>> serial_shocker.info()
BasicShockerInfo(
    name='Serial shocker (/dev/ttyUSB0)',
    client_id=621,
    shocker_id=1234,
    is_paused=False,
)

>>> http_shocker.info()
DetailedShockerInfo(
    name='left',
    client_id=621,
    shocker_id=1234,
    is_paused=False,
    max_intensity=100,
    max_duration=15,
)

Error handling

For the HTTP API, various errors can be returned from the API (sometimes in subtly different ways). This library tries to convert all of those into sensible Python exceptions, which all inherit from httpapi.APIError. Additionally, httpapi.UnknownError is raised if the response couldn’t be parsed, and httpapi.HTTPError if an API endpoint returned an unexpected HTTP status.

For the serial API, serialapi.SerialAutodetectError is raised if device autodetection failed (multiple potential PiShocks found, or none at all). If a shocker gets requested for an ID that does not exist, serialapi.ShockerNotFoundError is raised. Additionally, serial.SerialException might be raised by the underlying PySerial package.

See the reference documentation for more specific documentation about which methods are expected to raise which exceptions.

Further operations

Further operations not connected to a single shocker are available via the httpapi.PiShockAPI and serialapi.SerialAPI classes directly, see their reference documentation for details: