Skip to content

Commit 1e3d458

Browse files
author
brentru
committed
validate feed keys used, test
1 parent 1c34a8f commit 1e3d458

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

adafruit_io/adafruit_io.py

+27
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"""
2121
import time
2222
import json
23+
import re
2324

2425
from adafruit_io.adafruit_io_errors import (
2526
AdafruitIO_RequestError,
@@ -33,6 +34,18 @@
3334
CLIENT_HEADERS = {"User-Agent": "AIO-CircuitPython/{0}".format(__version__)}
3435

3536

37+
def validate_feed_key(feed_key):
38+
"""Validates a provided feed key against Adafruit IO's system rules.
39+
https://learn.adafruit.com/naming-things-in-adafruit-io/the-two-feed-identifiers
40+
"""
41+
if len(feed_key) > 128: # validate feed key length
42+
raise ValueError("Feed key must be less than 128 characters.")
43+
if not bool(re.match("^[a-z0-9-]+$", feed_key)): # validate key naming scheme
44+
raise TypeError(
45+
"Feed key must contain lower case English letters, numbers, and dash."
46+
)
47+
48+
3649
class IO_MQTT:
3750
"""
3851
Client for interacting with Adafruit IO MQTT API.
@@ -186,6 +199,7 @@ def add_feed_callback(self, feed_key, callback_method):
186199
:param str callback_method: Name of callback method.
187200
188201
"""
202+
validate_feed_key(feed_key)
189203
self._client.add_topic_callback(
190204
"{0}/f/{1}".format(self._user, feed_key), callback_method
191205
)
@@ -199,6 +213,7 @@ def remove_feed_callback(self, feed_key):
199213
:param str feed_key: Adafruit IO feed key.
200214
201215
"""
216+
validate_feed_key(feed_key)
202217
self._client.remove_topic_callback("{0}/f/{1}".format(self._user, feed_key))
203218

204219
def loop(self):
@@ -235,6 +250,7 @@ def subscribe(self, feed_key=None, group_key=None, shared_user=None):
235250
236251
client.subscribe([('temperature'), ('humidity')])
237252
"""
253+
validate_feed_key(feed_key)
238254
if shared_user is not None and feed_key is not None:
239255
self._client.subscribe("{0}/f/{1}".format(shared_user, feed_key))
240256
elif group_key is not None:
@@ -314,6 +330,7 @@ def unsubscribe(self, feed_key=None, group_key=None, shared_user=None):
314330
client.unsubscribe('temperature', shared_user='adabot')
315331
316332
"""
333+
validate_feed_key(feed_key)
317334
if shared_user is not None and feed_key is not None:
318335
self._client.unsubscribe("{0}/f/{1}".format(shared_user, feed_key))
319336
elif group_key is not None:
@@ -398,6 +415,7 @@ def publish(self, feed_key, data, metadata=None, shared_user=None, is_group=Fals
398415
io.publish("location-feed", data, metadata)
399416
400417
"""
418+
validate_feed_key(feed_key)
401419
if is_group:
402420
self._client.publish("{0}/g/{1}".format(self._user, feed_key), data)
403421
if shared_user is not None:
@@ -423,6 +441,7 @@ def get(self, feed_key):
423441
424442
io.get('temperature')
425443
"""
444+
validate_feed_key(feed_key)
426445
self._client.publish("{0}/f/{1}/get".format(self._user, feed_key), "\0")
427446

428447

@@ -534,6 +553,7 @@ def send_data(self, feed_key, data, metadata=None, precision=None):
534553
:param dict metadata: Optional metadata associated with the data
535554
:param int precision: Optional amount of precision points to send with floating point data
536555
"""
556+
validate_feed_key(feed_key)
537557
path = self._compose_path("feeds/{0}/data".format(feed_key))
538558
if precision:
539559
try:
@@ -551,6 +571,7 @@ def receive_all_data(self, feed_key):
551571
returned in reverse order.
552572
:param str feed_key: Adafruit IO feed key
553573
"""
574+
validate_feed_key(feed_key)
554575
path = self._compose_path("feeds/{0}/data".format(feed_key))
555576
return self._get(path)
556577

@@ -559,6 +580,7 @@ def receive_data(self, feed_key):
559580
Return the most recent value for the specified feed.
560581
:param string feed_key: Adafruit IO feed key
561582
"""
583+
validate_feed_key(feed_key)
562584
path = self._compose_path("feeds/{0}/data/last".format(feed_key))
563585
return self._get(path)
564586

@@ -568,6 +590,7 @@ def delete_data(self, feed_key, data_id):
568590
:param string feed: Adafruit IO feed key
569591
:param string data_id: Data point to delete from the feed
570592
"""
593+
validate_feed_key(feed_key)
571594
path = self._compose_path("feeds/{0}/data/{1}".format(feed_key, data_id))
572595
return self._delete(path)
573596

@@ -614,6 +637,7 @@ def add_feed_to_group(self, group_key, feed_key):
614637
:param str group_key: Group
615638
:param str feed_key: Feed to add to the group
616639
"""
640+
validate_feed_key(feed_key)
617641
path = self._compose_path("groups/{0}/add".format(group_key))
618642
payload = {"feed_key": feed_key}
619643
return self._post(path, payload)
@@ -625,6 +649,7 @@ def get_feed(self, feed_key, detailed=False):
625649
:param str feed_key: Adafruit IO Feed Key
626650
:param bool detailed: Returns a more verbose feed record
627651
"""
652+
validate_feed_key(feed_key)
628653
if detailed:
629654
path = self._compose_path("feeds/{0}/details".format(feed_key))
630655
else:
@@ -638,6 +663,7 @@ def create_new_feed(self, feed_key, feed_desc=None, feed_license=None):
638663
:param str feed_desc: Optional description of feed
639664
:param str feed_license: Optional feed license
640665
"""
666+
validate_feed_key(feed_key)
641667
path = self._compose_path("feeds")
642668
payload = {"name": feed_key, "description": feed_desc, "license": feed_license}
643669
return self._post(path, payload)
@@ -647,6 +673,7 @@ def delete_feed(self, feed_key):
647673
Deletes an existing feed.
648674
:param str feed_key: Valid feed key
649675
"""
676+
validate_feed_key(feed_key)
650677
path = self._compose_path("feeds/{0}".format(feed_key))
651678
return self._delete(path)
652679

0 commit comments

Comments
 (0)