diff --git a/example.py b/example.py index 23e3dcc..c46be17 100755 --- a/example.py +++ b/example.py @@ -23,4 +23,4 @@ last_device = device print("== Last 3 messages from " + last_device['name'] + ":") -pprint(s.device_messages(last_device, limit=3)) +pprint(s.device_messages(last_device['id'], params={'limit': 3})) diff --git a/pySigfox/pySigfox.py b/pySigfox/pySigfox.py index 74001cb..b3b99a8 100755 --- a/pySigfox/pySigfox.py +++ b/pySigfox/pySigfox.py @@ -5,14 +5,16 @@ import json import requests from pprint import pprint +from ratelimit import limits, sleep_and_retry +from ratelimit.exception import RateLimitException class Sigfox: def __init__(self, login, password, debug=False): if not login or not password: raise Exception("Please define login and password when initiating pySigfox class!") - self.login = login + self.login = login self.password = password - self.api_url = 'https://api.sigfox.com/v2/' + self.api_url = 'https://api.sigfox.com/v2/' self.debug = debug def login_test(self): @@ -28,18 +30,14 @@ def device_types_list(self): """Return list of device types dictionaries """ - out = [] url = self.api_url + 'device-types' r = requests.get(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password)) - for device in json.loads(r.text)['data']: - out.append(device) - return out + return r.json()['data'] def device_rename(self, device_id, new_name): """Rename specific device """ - out = [] url = self.api_url + 'devices/' + str(device_id) if self.debug: print("Connecting to " + url) @@ -49,13 +47,12 @@ def device_info(self, device_id): """Return information about specific device """ - out = [] url = self.api_url + 'devices/' + str(device_id) if self.debug: print("Connecting to " + url) r = requests.get(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password)) try: - return json.loads(r.text) + return r.json() except Exception as e: pprint(r.text) raise @@ -82,12 +79,12 @@ def device_create(self, device, cert, devicetype): if self.debug: print("Adding device " + device['id'] + " to device type " + devicetype['name']) to_post = { - "prefix": "api_added-", - "ids": [ - { 'id': device['id'], 'pac': device['pac'] }, - ], - "productCertificate": str(cert), - } + "prefix": "api_added-", + "ids": [ + {'id': device['id'], 'pac': device['pac']}, + ], + "productCertificate": str(cert), + } url = self.api_url + "devicetypes/" + devicetype['id'] + '/devices/bulk/create/async' if self.debug: print("Connecting to " + url) @@ -95,7 +92,7 @@ def device_create(self, device, cert, devicetype): pprint(to_post) r = requests.post(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password), - json = to_post) + json=to_post) if self.debug: pprint("Response: " + str(r.text)) return r.json() @@ -105,13 +102,13 @@ def device_types_create(self, new): """ dtype = { - 'name': 'test1', - 'contractId': 'moire_la_30f0_30f1' - } + 'name': 'test1', + 'contractId': 'moire_la_30f0_30f1' + } url = self.api_url + 'devicetypes/create' if self.debug: print("Connecting to " + url) - r = requests.post(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password), data = dtype) + r = requests.post(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password), data=dtype) return r def device_list(self, device_type): @@ -123,50 +120,68 @@ def device_list(self, device_type): :rtype: list """ - device_type_ids = [] out = [] - url = self.api_url + 'devices?deviceTypeId=' + device_type['id'] - r = requests.get(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password)) + params = { + 'deviceTypeId': device_type['id'] + } + url = self.api_url + 'devices' + r = requests.get(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password), params=params) try: - out.extend(json.loads(r.text)['data']) + out += r.json()['data'] except Exception as e: print("Unable to access data from returned RESP API call: " + str(e)) pprint(r.text) raise return out - def device_messages(self, device, limit=10): - """Return array of 10 last messages from specific device. - - :param device: Device object - :param limit: how many messages to retrieve - max limit 100 - :type limit: int + @sleep_and_retry + @limits(calls=1, period=5) + def device_messages_page(self, url): + """Return array of message from paging URL. """ - - url = self.api_url + 'devices/' + str(device['id']) + '/messages?limit=' + str(limit) + out = [] r = requests.get(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password)) - + if r.status_code == 429: + raise RateLimitException('Exceeded Sigfox API rate limit', 5) try: - out = json.loads(r.text)['data'] + r_deserialized = r.json() + out = r_deserialized['data'] + try: + out += self.device_messages_page(r_deserialized['paging']['next']) + except KeyError: + pass except Exception as e: pprint(r.text) raise return out + + @sleep_and_retry + @limits(calls=1, period=5) + def device_messages(self, device_id, params=None): + """Return array of 10 last messages from specific device. - def device_messages_page(self, url): - """Return array of message from paging URL. + :param device: Device object + :param limit: how many messages to retrieve - max limit 100 + :type limit: int """ - out = [] - r = requests.get(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password)) - out.extend(json.loads(r.text)['data']) + if params is None: + params = {'limit': 10} + url = self.api_url + 'devices/' + str(device_id) + '/messages' + r = requests.get(url, auth=requests.auth.HTTPBasicAuth(self.login, self.password), params=params) + if r.status_code == 429: + raise RateLimitException('Exceeded Sigfox API rate limit', 5) try: - json.loads(r.text)['paging']['next'] - out.extend(self.device_messages_page(json.loads(r.text)['paging']['next'])) + r_deserialized = r.json() + out = r_deserialized['data'] + try: + out += self.device_messages_page(r_deserialized['paging']['next']) + except KeyError: + pass except Exception as e: - # no more pages - pass + pprint(r.text) + raise return out diff --git a/setup.py b/setup.py index 79c8303..c0b0fc9 100644 --- a/setup.py +++ b/setup.py @@ -12,5 +12,5 @@ 'Programming Language :: Python :: 2.7', ], packages=find_packages(), - install_requires=['requests'], + install_requires=['requests', 'ratelimit'], )