iobeam is a data platform for connected devices.
This is a Python library for sending data to iobeam. For more information on the iobeam, please check our our documentation.
Please note that we are currently invite-only. You will need an invite to generate a valid token and use our APIs. (Sign up here for an invite.)
Before you can start sending data to the iobeam backend, you'll need a
project_id and project_token (with write-access enabled) for a valid
iobeam account. You can get these easily with our
command-line interface (CLI) tool or by
accessing your project settings from our web app.
You need python 2.7.9+ or 3.4.3+ (earlier versions of python3 may work, but it has not been tested).
The easiest way to install is to use pip:
pip install iobeam
You will need the requests and pyjwt libraries installed.
You can get it via pip:
pip install requests pyjwt
If you are using Python2, or Python3 earlier than 3.5,
you will need the enum34 library as well:
pip install enum34
Then, to install from source:
git clone https://github.com/iobeam/iobeam-client-python.git
Then make sure that the iobeam folder is in your PYTHONPATH.
This library allows Python clients to send data to the iobeam backend.
At a high-level, here's how it works:
-
Build an iobeam client object with your
project_idandproject_token -
Make sure your device is registered, either generating a
device_idin code or via another method (e.g., our CLI or REST APIs). -
Create
iobeam.DataStoreobjects for your data streams. You can create one object per stream, or, if you have streams that are always collected together (e.g. the axes of a gyroscope), you can put them in one object. -
Add data values to your
iobeam.DataStoreobjects. -
When you're ready, send your data to the iobeam backend
Here's how to get started, using a basic example that sends temperature
data to iobeam. (For simplicity, let's assume that the current temperature
can be accessed with getTemperature()).
(Reminder: Before you start, create a user account, project, and
project_token (with write access) using the iobeam APIs, CLI or web app.
Write down your new project_id and project_token.)
There are several ways to initialize the iobeam client. All require
that you have project_id and project_token before hand.
Without a registered device_id
Perhaps the most natural way is to let the device register itself.
There are two ways to register a device_id:
(1) Let iobeam generate one for you:
from iobeam import iobeam
...
builder = iobeam.ClientBuilder(PROJECT_ID, PROJECT_TOKEN) \
.saveToDisk().registerDevice()
iobeamClient = builder.build()(2) Provide your own (must be unique to your project):
from iobeam import iobeam
...
builder = iobeam.ClientBuilder(PROJECT_ID, PROJECT_TOKEN) \
.saveToDisk().registerDevice(deviceId="my_desired_id")
iobeamClient = builder.build()With the saveToDisk() call, the device_id will be saved to disk in the
directory the script is called from (optionally, you can supply a path).
On future calls, this on-disk storage will be read first.
If a device_id exists, the registerDevice will do nothing; otherwise,
it will get a new random ID from us. If you provide a different device_id to registerDevice, the old one will be replaced.
With a registered device_id
If you have registered a device_id (e.g. using our
CLI), you can pass this to the Builder instead
of registering:
from iobeam import iobeam
...
builder = iobeam.ClientBuilder(PROJECT_ID, PROJECT_TOKEN) \
.saveToDisk().setDeviceId(DEVICE_ID)
iobeamClient = builder.build()You must have registered some other way (CLI, website, previous installation, etc) for this to work.
Advanced: not saving to disk
If you don't want the device_id to be automatically stored for you, simply
exclude the saveToDisk() call while building:
builder = iobeam.ClientBuilder(PROJECT_ID, PROJECT_TOKEN).registerDevice()
iobeamClient = builder.build()This is useful for cases where you want to persist the ID yourself (e.g.
in a settings file), or if you are making Iobeam objects that are
temporary. For example, if the device you are using acts as a relay or
proxy for other devices, it could get the device_id from those devices
and have no need to save it.
For a more in-depth discussion about adding data, please see our guide on adding data.
To track time-series data, you need to decide how to break down your data
streams into "stores", a collection of data streams grouped together. You
create a iobeam.DataStore with a list of stream names that it contains.
So if you're tracking just temperature in a store called conditions:
conditions = iobeamClient.createDataStore(["temperature"])Then for every data point, you'll want to add it to the store:
now = ... # e.g., now = int(time.time() * 1000) (import time first)
t = getTemperature()
conditions.add(iobeam.Timestamp(now), {"temperature": t})The values are passed in via a dictionary, keyed by which data stream the individual values belong to along with a timestamp. (For more on timestamps, see the next section.)
The iobeam.DataStore object can hold several streams at once. For
example, if you also had a getHumidity() function, you could track both in
the same DataStore:
conditions = iobeamClient.createDataStore(["temperature", "humidity"])
now = ... # current time
temp = getTemperature()
humidity = getHumidity()
conditions.add(iobeam.Timestamp(now), {"temperature": temp, "humidity": humidity})Not every add() call needs all streams to have a value; if a stream is
omitted from the dictionary, it will be assumed to be None.
By default, if you pass just an integer for timestamp when
constructing an iobeam.DataPoint, it will set the unit as
milliseconds. To specify other precisions, you need to use the
iobeam.Timestamp and iobeam.TimeUnit classes:
# Timestamps in seconds:
now = int(time.time())
ts = iobeam.Timestamp(now, unit=iobeam.TimeUnit.SECONDS)
dp = iobeam.DataPoint(t, timestamp=ts)
# Another way to do milliseconds:
now = int(time.time() * 1000)
ts = iobeam.Timestamp(now, unit=iobeam.TimeUnit.MILLISECONDS)
dp = iobeam.DataPoint(t, timestamp=ts)
# Timestamps in microseconds:
now = int(time.time() * 1000000)
ts = iobeam.Timestamp(now, unit=iobeam.TimeUnit.MICROSECONDS)
dp = iobeam.DataPoint(t, timestamp=ts)Currently we support expressing timestamps in seconds, milliseconds, and microseconds.
You can send your data stored in iobeam.Iobeam to the iobeam backend
easily:
iobeamClient.send()This call is blocking and will attempt to send all your data. It will
return True if successful.
Here's the full source code for our example:
from iobeam import iobeam
import time
# Constants initialization
PROJECT_ID = ... # int
PROJECT_TOKEN = ... # String
...
# Init iobeam
builder = iobeam.ClientBuilder(PROJECT_ID, PROJECT_TOKEN) \
.saveToDisk().registerDevice()
iobeamClient = builder.build()
conditions = iobeamClient.createDataStore(["temperature", "humidity"])
...
# Data gathering
now = ... # current time
ts = iobeam.Timestamp(now)
temp = getTemperature()
humidity = getHumidity()
conditions.add(ts, {"temperature": temp, "humidity": humidity})
...
# Data transmission
iobeamClient.send()The tests use the Python unittest module, along with mock. If you are running a Python lower
than 3.3, you need to install mock from PyPI:
pip install mock
(Versions >= 3.3 already have mock installed.)
You can invoke the tests with:
python -m unittest discover
Or for more verbose output:
python -m unittest discover -v