Skip to content

Commit

Permalink
Merge pull request #98 from ForgottenProgramme/mahe-typehint
Browse files Browse the repository at this point in the history
Add TypeHints to adafruit_io.py
  • Loading branch information
FoamyGuy authored Jul 31, 2023
2 parents 1f885d5 + d790205 commit 0772f3b
Showing 1 changed file with 74 additions and 35 deletions.
109 changes: 74 additions & 35 deletions adafruit_io/adafruit_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
import json
import re

try:
from typing import List, Any, Callable, Optional
except ImportError:
pass

from adafruit_minimqtt.adafruit_minimqtt import MMQTTException
from adafruit_io.adafruit_io_errors import (
AdafruitIO_RequestError,
Expand All @@ -35,7 +40,7 @@
CLIENT_HEADERS = {"User-Agent": "AIO-CircuitPython/{0}".format(__version__)}


def validate_feed_key(feed_key):
def validate_feed_key(feed_key: str):
"""Validates a provided feed key against Adafruit IO's system rules.
https://learn.adafruit.com/naming-things-in-adafruit-io/the-two-feed-identifiers
"""
Expand Down Expand Up @@ -143,7 +148,7 @@ def _on_disconnect_mqtt(self, client, userdata, return_code):
self.on_disconnect(self)

# pylint: disable=not-callable
def _on_message_mqtt(self, client, topic, payload):
def _on_message_mqtt(self, client, topic: str, payload: str):
"""Runs when the client calls on_message. Parses and returns
incoming data from Adafruit IO feeds.
Expand Down Expand Up @@ -195,7 +200,7 @@ def _on_unsubscribe_mqtt(self, client, user_data, topic, pid):
if self.on_unsubscribe is not None:
self.on_unsubscribe(self, user_data, topic, pid)

def add_feed_callback(self, feed_key, callback_method):
def add_feed_callback(self, feed_key: str, callback_method: Callable):
"""Attaches a callback_method to an Adafruit IO feed.
The callback_method function is called when a
new value is written to the feed.
Expand All @@ -211,7 +216,7 @@ def add_feed_callback(self, feed_key, callback_method):
"{0}/f/{1}".format(self._user, feed_key), callback_method
)

def remove_feed_callback(self, feed_key):
def remove_feed_callback(self, feed_key: str):
"""Removes a previously registered callback method
from executing whenever feed_key receives new data.
Expand Down Expand Up @@ -239,7 +244,12 @@ def loop(self, timeout=1):
self._client.loop(timeout)

# Subscriptions
def subscribe(self, feed_key=None, group_key=None, shared_user=None):
def subscribe(
self,
feed_key: str = None,
group_key: str = None,
shared_user: Optional[str] = None,
):
"""Subscribes to your Adafruit IO feed or group.
Can also subscribe to someone else's feed.
Expand Down Expand Up @@ -277,7 +287,7 @@ def subscribe_to_errors(self):
"""
self._client.subscribe("%s/errors" % self._user)

def subscribe_to_randomizer(self, randomizer_id):
def subscribe_to_randomizer(self, randomizer_id: int):
"""Subscribes to a random data stream created by the Adafruit IO Words service.
:param int randomizer_id: Random word record you want data for.
Expand All @@ -286,7 +296,7 @@ def subscribe_to_randomizer(self, randomizer_id):
"{0}/integration/words/{1}".format(self._user, randomizer_id)
)

def subscribe_to_weather(self, weather_record, forecast):
def subscribe_to_weather(self, weather_record: int, forecast: str):
"""Subscribes to a weather forecast using the Adafruit IO PLUS weather
service. This feature is only avaliable to Adafruit IO PLUS subscribers.
Expand All @@ -299,7 +309,7 @@ def subscribe_to_weather(self, weather_record, forecast):
)
)

def subscribe_to_time(self, time_type):
def subscribe_to_time(self, time_type: str):
"""Adafruit IO provides some built-in MQTT topics for getting the current server time.
:param str time_type: Current Adafruit IO server time. Can be 'seconds', 'millis', or 'iso'.
Expand All @@ -312,7 +322,12 @@ def subscribe_to_time(self, time_type):
else:
self._client.subscribe("time/" + time_type)

def unsubscribe(self, feed_key=None, group_key=None, shared_user=None):
def unsubscribe(
self,
feed_key: str = None,
group_key: str = None,
shared_user: Optional[str] = None,
):
"""Unsubscribes from an Adafruit IO feed or group.
Can also subscribe to someone else's feed.
Expand Down Expand Up @@ -345,11 +360,13 @@ def unsubscribe(self, feed_key=None, group_key=None, shared_user=None):
raise AdafruitIO_MQTTError("Must provide a feed_key or group_key.")

# Publishing
def publish_multiple(self, feeds_and_data, timeout=3, is_group=False):
def publish_multiple(
self, feeds_and_data: List, timeout: int = 3, is_group: bool = False
):
"""Publishes multiple data points to multiple feeds or groups with a variable
timeout.
:param str feeds_and_data: List of tuples containing topic strings and data values.
:param list feeds_and_data: List of tuples containing topic strings and data values.
:param int timeout: Delay between publishing data points to Adafruit IO, in seconds.
:param bool is_group: Set to True if you're publishing to a group.
Expand All @@ -373,8 +390,15 @@ def publish_multiple(self, feeds_and_data, timeout=3, is_group=False):
time.sleep(timeout)

# pylint: disable=too-many-arguments
def publish(self, feed_key, data, metadata=None, shared_user=None, is_group=False):
"""Publishes to an An Adafruit IO Feed.
def publish(
self,
feed_key: str,
data: str,
metadata: str = None,
shared_user: str = None,
is_group: bool = False,
):
"""Publishes to an Adafruit IO Feed.
:param str feed_key: Adafruit IO Feed key.
:param str data: Data to publish to the feed or group.
Expand Down Expand Up @@ -439,7 +463,7 @@ def publish(self, feed_key, data, metadata=None, shared_user=None, is_group=Fals
else:
self._client.publish("{0}/f/{1}".format(self._user, feed_key), data)

def get(self, feed_key):
def get(self, feed_key: str):
"""Calling this method will make Adafruit IO publish the most recent
value on feed_key.
https://io.adafruit.com/api/docs/mqtt.html#retained-values
Expand Down Expand Up @@ -484,7 +508,7 @@ def _create_headers(io_headers):
return headers

@staticmethod
def _create_data(data, metadata):
def _create_data(data, metadata: dict):
"""Returns a data payload as expected by the Adafruit IO HTTP API
:param data: Payload value.
Expand All @@ -508,15 +532,15 @@ def _handle_error(response):
if response.status_code >= 400:
raise AdafruitIO_RequestError(response)

def _compose_path(self, path):
def _compose_path(self, path: str):
"""Composes a valid API request path.
:param str path: Adafruit IO API URL path.
"""
return "https://io.adafruit.com/api/v2/{0}/{1}".format(self.username, path)

# HTTP Requests
def _post(self, path, payload):
def _post(self, path: str, payload: Any):
"""
POST data to Adafruit IO
Expand All @@ -531,7 +555,7 @@ def _post(self, path, payload):

return json_data

def _get(self, path):
def _get(self, path: str):
"""
GET data from Adafruit IO
Expand All @@ -544,7 +568,7 @@ def _get(self, path):
json_data = response.json()
return json_data

def _delete(self, path):
def _delete(self, path: str):
"""
DELETE data from Adafruit IO.
Expand All @@ -559,7 +583,13 @@ def _delete(self, path):
return json_data

# Data
def send_data(self, feed_key, data, metadata=None, precision=None):
def send_data(
self,
feed_key: str,
data: str,
metadata: Optional[dict] = None,
precision: Optional[int] = None,
):
"""
Sends value data to a specified Adafruit IO feed.
Expand All @@ -580,7 +610,7 @@ def send_data(self, feed_key, data, metadata=None, precision=None):
payload = self._create_data(data, metadata)
self._post(path, payload)

def send_batch_data(self, feed_key, data_list):
def send_batch_data(self, feed_key: str, data_list: list):
"""
Sends a batch array of data to a specified Adafruit IO feed
Expand All @@ -592,7 +622,7 @@ def send_batch_data(self, feed_key, data_list):
data_dict = type(data_list)((data._asdict() for data in data_list))
self._post(path, {"data": data_dict})

def receive_all_data(self, feed_key):
def receive_all_data(self, feed_key: str):
"""
Get all data values from a specified Adafruit IO feed. Data is
returned in reverse order.
Expand All @@ -603,7 +633,7 @@ def receive_all_data(self, feed_key):
path = self._compose_path("feeds/{0}/data".format(feed_key))
return self._get(path)

def receive_data(self, feed_key):
def receive_data(self, feed_key: str):
"""
Return the most recent value for the specified feed.
Expand All @@ -613,7 +643,7 @@ def receive_data(self, feed_key):
path = self._compose_path("feeds/{0}/data/last".format(feed_key))
return self._get(path)

def delete_data(self, feed_key, data_id):
def delete_data(self, feed_key: str, data_id: str):
"""
Deletes an existing Data point from a feed.
Expand All @@ -625,7 +655,7 @@ def delete_data(self, feed_key, data_id):
return self._delete(path)

# Groups
def create_new_group(self, group_key, group_description):
def create_new_group(self, group_key: str, group_description: str):
"""
Creates a new Adafruit IO Group.
Expand All @@ -636,7 +666,7 @@ def create_new_group(self, group_key, group_description):
payload = {"name": group_key, "description": group_description}
return self._post(path, payload)

def delete_group(self, group_key):
def delete_group(self, group_key: str):
"""
Deletes an existing group.
Expand All @@ -645,7 +675,7 @@ def delete_group(self, group_key):
path = self._compose_path("groups/{0}".format(group_key))
return self._delete(path)

def get_group(self, group_key):
def get_group(self, group_key: str):
"""
Returns Group based on Group Key
Expand All @@ -654,7 +684,7 @@ def get_group(self, group_key):
path = self._compose_path("groups/{0}".format(group_key))
return self._get(path)

def create_feed_in_group(self, group_key, feed_name):
def create_feed_in_group(self, group_key: str, feed_name: str):
"""Creates a new feed in an existing group.
:param str group_key: Group name.
Expand All @@ -664,7 +694,7 @@ def create_feed_in_group(self, group_key, feed_name):
payload = {"feed": {"name": feed_name}}
return self._post(path, payload)

def add_feed_to_group(self, group_key, feed_key):
def add_feed_to_group(self, group_key: str, feed_key: str):
"""
Adds an existing feed to a group
Expand All @@ -677,7 +707,7 @@ def add_feed_to_group(self, group_key, feed_key):
return self._post(path, payload)

# Feeds
def get_feed(self, feed_key, detailed=False):
def get_feed(self, feed_key: str, detailed: bool = False):
"""
Returns an Adafruit IO feed based on the feed key
Expand All @@ -691,7 +721,12 @@ def get_feed(self, feed_key, detailed=False):
path = self._compose_path("feeds/{0}".format(feed_key))
return self._get(path)

def create_new_feed(self, feed_key, feed_desc=None, feed_license=None):
def create_new_feed(
self,
feed_key: str,
feed_desc: Optional[str] = None,
feed_license: Optional[str] = None,
):
"""
Creates a new Adafruit IO feed.
Expand All @@ -705,7 +740,11 @@ def create_new_feed(self, feed_key, feed_desc=None, feed_license=None):
return self._post(path, payload)

def create_and_get_feed(
self, feed_key, detailed=False, feed_desc=None, feed_license=None
self,
feed_key: str,
detailed: bool = False,
feed_desc: Optional[str] = None,
feed_license: Optional[str] = None,
):
"""
Attempts to return a feed; if the feed does not exist, it is created, and then returned.
Expand All @@ -723,7 +762,7 @@ def create_and_get_feed(
)
return self.get_feed(feed_key, detailed=detailed)

def delete_feed(self, feed_key):
def delete_feed(self, feed_key: str):
"""
Deletes an existing feed.
Expand All @@ -734,7 +773,7 @@ def delete_feed(self, feed_key):
return self._delete(path)

# Adafruit IO Connected Services
def receive_weather(self, weather_id):
def receive_weather(self, weather_id: int):
"""
Get data from the Adafruit IO Weather Forecast Service
NOTE: This service is avaliable to Adafruit IO Plus subscribers only.
Expand All @@ -744,7 +783,7 @@ def receive_weather(self, weather_id):
path = self._compose_path("integrations/weather/{0}".format(weather_id))
return self._get(path)

def receive_random_data(self, generator_id):
def receive_random_data(self, generator_id: int):
"""
Get data from the Adafruit IO Random Data Stream Service
Expand Down

0 comments on commit 0772f3b

Please sign in to comment.