Skip to content

Commit

Permalink
Add MockDevice support for /data and /df (#25)
Browse files Browse the repository at this point in the history
* Add support for api/v1/data/ and api/v1/df/ APIs.

Mock is currently always returning  the same data regardless of stream
slug.

* Build IOTileProjectSlug if needed when constructing an IOTileVariableSlug

* Remove hard coded filter on /data and /df

Now properly getting filter argument from Request object

* Fix changelog
  • Loading branch information
dkarchmer authored Feb 7, 2018
1 parent 0877bce commit d0883e7
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### v0.8.3 (2018-02-06)

* Add support for `api/v1/data/?filter=` and `api/v1/df/?filter=` APIs.
* Build IOTileProjectSlug if needed when constructing an IOTileVariableSlug

### v0.8.2 (2018-01-27)

* Add support for uploading reports using /streamer/report/ api, keeping
Expand Down
3 changes: 2 additions & 1 deletion iotile_cloud/utils/gid.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ def __init__(self, id, project=None):
:param project: IOTileCProjectSlug instance
"""
if project:
assert(isinstance(project, IOTileProjectSlug))
if not isinstance(project, IOTileProjectSlug):
project = IOTileProjectSlug(project)
if isinstance(id, int) and project != None:
vid = int2vid(id)
self._slug = gid_join(['v', project.formatted_id(), vid])
Expand Down
31 changes: 29 additions & 2 deletions iotile_cloud/utils/mock_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ def __init__(self, config_file=None):

# APIs for getting raw data
self._add_api(r"/api/v1/stream/(s--[0-9\-a-f]+)/data/", self.get_stream_data)
# Function will get stream from '?filter='
self._add_api(r"/api/v1/data/", self.get_stream_data)
self._add_api(r"/api/v1/df/", self.get_stream_df)
self._add_api(r"/api/v1/event/([0-9]+)/data/", self.get_raw_event)

# APIs for querying single models
Expand Down Expand Up @@ -363,8 +366,17 @@ def get_raw_event(self, request, event_id):

return results

def get_stream_data(self, request, stream):
if stream not in self.streams:
def get_stream_data(self, request, stream=None):

if not stream:
# Stream can only be none if not used by /stream/<stream>/
# which means this is called from either /df/?filter= or /data/?filter=
if 'filter' in request.args:
filter = request.args['filter']
if filter.split('--')[0] == 's':
stream = filter + '.raw'

if stream.split('.')[0] not in self.streams:
raise ErrorCode(404)

results = []
Expand All @@ -381,6 +393,21 @@ def get_stream_data(self, request, stream):

return self._paginate(results, request, 1000)

def get_stream_df(self, request, stream=None):

results = []

data = self.get_stream_data(request, stream)

for row in data['results']:
results.append({
'row': row['timestamp'],
'value': row['value'],
'stream_slug': row['stream']
})

return results

def _format_stream_data(self, stream, csvpath):
results = []

Expand Down
137 changes: 137 additions & 0 deletions tests/data/watermeter/s--0000-0077--0000-0000-0000-00d2--5001.raw.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
[
{
"id": 577632,
"stream": "s--0000-0077--0000-0000-0000-00d2--5001",
"project": "p--0000-0077",
"device": "d--0000-0000-0000-00d2",
"variable": "v--0000-0077--5001",
"type": "ITR",
"device_timestamp": null,
"timestamp": "2017-04-12T20:06:02Z",
"int_value": 96,
"value": 36339.936,
"streamer_local_id": 9777,
"dirty_ts": false,
"status": "unk"
},
{
"id": 577636,
"stream": "s--0000-0077--0000-0000-0000-00d2--5001",
"project": "p--0000-0077",
"device": "d--0000-0000-0000-00d2",
"variable": "v--0000-0077--5001",
"type": "ITR",
"device_timestamp": null,
"timestamp": "2017-04-12T20:16:02Z",
"int_value": 100,
"value": 37854.1,
"streamer_local_id": 9779,
"dirty_ts": false,
"status": "unk"
},
{
"id": 577640,
"stream": "s--0000-0077--0000-0000-0000-00d2--5001",
"project": "p--0000-0077",
"device": "d--0000-0000-0000-00d2",
"variable": "v--0000-0077--5001",
"type": "ITR",
"device_timestamp": null,
"timestamp": "2017-04-12T20:26:02Z",
"int_value": 101,
"value": 38232.641,
"streamer_local_id": 9781,
"dirty_ts": false,
"status": "unk"
},
{
"id": 577644,
"stream": "s--0000-0077--0000-0000-0000-00d2--5001",
"project": "p--0000-0077",
"device": "d--0000-0000-0000-00d2",
"variable": "v--0000-0077--5001",
"type": "ITR",
"device_timestamp": null,
"timestamp": "2017-04-12T20:36:02Z",
"int_value": 100,
"value": 37854.1,
"streamer_local_id": 9786,
"dirty_ts": false,
"status": "unk"
},
{
"id": 577648,
"stream": "s--0000-0077--0000-0000-0000-00d2--5001",
"project": "p--0000-0077",
"device": "d--0000-0000-0000-00d2",
"variable": "v--0000-0077--5001",
"type": "ITR",
"device_timestamp": null,
"timestamp": "2017-04-12T20:46:02Z",
"int_value": 101,
"value": 38232.641,
"streamer_local_id": 9788,
"dirty_ts": false,
"status": "unk"
},
{
"id": 577652,
"stream": "s--0000-0077--0000-0000-0000-00d2--5001",
"project": "p--0000-0077",
"device": "d--0000-0000-0000-00d2",
"variable": "v--0000-0077--5001",
"type": "ITR",
"device_timestamp": null,
"timestamp": "2017-04-12T20:56:02Z",
"int_value": 100,
"value": 37854.1,
"streamer_local_id": 9790,
"dirty_ts": false,
"status": "unk"
},
{
"id": 577656,
"stream": "s--0000-0077--0000-0000-0000-00d2--5001",
"project": "p--0000-0077",
"device": "d--0000-0000-0000-00d2",
"variable": "v--0000-0077--5001",
"type": "ITR",
"device_timestamp": null,
"timestamp": "2017-04-12T21:06:02Z",
"int_value": 100,
"value": 37854.1,
"streamer_local_id": 9792,
"dirty_ts": false,
"status": "unk"
},
{
"id": 577660,
"stream": "s--0000-0077--0000-0000-0000-00d2--5001",
"project": "p--0000-0077",
"device": "d--0000-0000-0000-00d2",
"variable": "v--0000-0077--5001",
"type": "ITR",
"device_timestamp": null,
"timestamp": "2017-04-12T21:16:02Z",
"int_value": 101,
"value": 38232.641,
"streamer_local_id": 9794,
"dirty_ts": false,
"status": "unk"
},
{
"id": 577664,
"stream": "s--0000-0077--0000-0000-0000-00d2--5001",
"project": "p--0000-0077",
"device": "d--0000-0000-0000-00d2",
"variable": "v--0000-0077--5001",
"type": "ITR",
"device_timestamp": null,
"timestamp": "2017-04-12T21:26:02Z",
"int_value": 100,
"value": 37854.1,
"streamer_local_id": 9796,
"dirty_ts": false,
"status": "unk"
}
]
4 changes: 4 additions & 0 deletions tests/test_gid.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ def test_block_slug(self):
def test_variable_slug(self):
self.assertRaises(AssertionError, IOTileVariableSlug, 5)

id = IOTileVariableSlug(5, '1234')
self.assertEqual(str(id), 'v--0000-1234--0005')
self.assertEqual(id.formatted_local_id(), '0005')

id = IOTileVariableSlug(5, IOTileProjectSlug('1234'))
self.assertEqual(str(id), 'v--0000-1234--0005')
self.assertEqual(id.formatted_local_id(), '0005')
Expand Down
35 changes: 35 additions & 0 deletions tests/test_mock_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,41 @@ def test_data_access(water_meter):
api.vartype('water-meter-volume').get()


def test_data_stream(water_meter):
"""Make sure we can load and access data."""

domain, _cloud = water_meter

api = Api(domain=domain, verify=False)
api.login('test', '[email protected]')

data = api.data.get(filter='s--0000-0077--0000-0000-0000-00d2--5001')

assert data['count'] == 9
first = data['results'][0]
assert first['project'] == 'p--0000-0077'
assert first['device'] == 'd--0000-0000-0000-00d2'
assert first['stream'] == 's--0000-0077--0000-0000-0000-00d2--5001'
assert first['value'] == 36339.936
assert first['int_value'] == 96


def test_data_frame(water_meter):
"""Make sure we can load and access data."""

domain, _cloud = water_meter

api = Api(domain=domain, verify=False)
api.login('test', '[email protected]')

data = api.df.get(filter='s--0000-0077--0000-0000-0000-00d2--5001')

first = data[0]
assert first['stream_slug'] == 's--0000-0077--0000-0000-0000-00d2--5001'
assert first['value'] == 36339.936
assert first['row'] == '2017-04-12T20:06:02Z'


def test_quick_add_functionality(mock_cloud_private_nossl):
"""Make sure quick add functions work."""

Expand Down
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = '0.8.2'
version = '0.8.3'

0 comments on commit d0883e7

Please sign in to comment.