diff --git a/.pylintrc b/.pylintrc index f945e92..ddbd91f 100644 --- a/.pylintrc +++ b/.pylintrc @@ -55,7 +55,7 @@ confidence= # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" # disable=import-error,raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,deprecated-str-translate-call -disable=raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,import-error,pointless-string-statement,unspecified-encoding +disable=raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,import-error,pointless-string-statement,unspecified-encoding,too-many-public-methods # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/adafruit_io/adafruit_io.py b/adafruit_io/adafruit_io.py index 8325b01..3099d27 100755 --- a/adafruit_io/adafruit_io.py +++ b/adafruit_io/adafruit_io.py @@ -855,6 +855,77 @@ def receive_random_data(self, generator_id: int): path = self._compose_path("integrations/words/{0}".format(generator_id)) return self._get(path) + def get_user_info(self): + """ + Get detailed account information for the current user. + + See https://io.adafruit.com/api/docs/#get-user-info + """ + return self._get("https://io.adafruit.com/api/v2/user") + + def get_user_rate_info(self): + """ + Get rate limit and usage information for the current user. + + See https://io.adafruit.com/api/docs/#get-detailed-user-info + + Example output: + ``` + { + "data_rate_limit": 30, + "active_data_rate": 0, + "authentication_rate": 0, + "subscribe_authorization_rate": 0, + "publish_authorization_rate": 0, + "hourly_ban_rate": 0, + "mqtt_ban_error_message": null, + "active_sms_rate": 0 + } + ``` + """ + path = self._compose_path("throttle") + return self._get(path) + + def get_remaining_throttle_limit(self): + """ + Get the remaining data points allowed before hitting the throttle limit. + This retrieves the user rate limit and deducts usage for the current user. + + See https://io.adafruit.com/api/docs/#get-detailed-user-info + """ + user_rates = self.get_user_rate_info() + if user_rates is None: + raise ValueError( + "Could not get user info, get_user_rate_info returned None." + ) + return user_rates["data_rate_limit"] - user_rates["active_data_rate"] + + def get_throttle_limit(self): + """ + Get user throttle limit a.k.a "data_rate_limit" for the current user. + + See https://io.adafruit.com/api/docs/#get-detailed-user-info + """ + user_rates = self.get_user_rate_info() + if user_rates is None: + raise ValueError( + "Could not get user info, get_user_rate_info returned None." + ) + return user_rates["data_rate_limit"] + + def get_current_usage(self): + """ + Get current rate usage a.k.a "active_data_rate" for the current user. + + See https://io.adafruit.com/api/docs/#get-detailed-user-info + """ + user_rates = self.get_user_rate_info() + if user_rates is None: + raise ValueError( + "Could not get user info, get_user_rate_info returned None." + ) + return user_rates["active_data_rate"] + def receive_time(self, timezone: str = None): """ Returns a struct_time from the Adafruit IO Server based on the device's IP address. diff --git a/examples/adafruit_io_http/adafruit_io_user_info.py b/examples/adafruit_io_http/adafruit_io_user_info.py new file mode 100644 index 0000000..3351311 --- /dev/null +++ b/examples/adafruit_io_http/adafruit_io_user_info.py @@ -0,0 +1,62 @@ +# SPDX-FileCopyrightText: 2024 Tyeth Gundry for Adafruit Industries +# SPDX-License-Identifier: MIT + +# retrieve user rate info via adafruit_circuitpython_adafruitio with native wifi networking +import ssl +import time # pylint: disable=unused-import +import adafruit_requests +import socketpool +import wifi +from adafruit_io.adafruit_io import IO_HTTP + +# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and +# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other +# source control. + +# pylint: disable=no-name-in-module,wrong-import-order +try: + from secrets import secrets +except ImportError: + print("WiFi secrets are kept in secrets.py, please add them there!") + raise + +# Set your Adafruit IO Username and Key in secrets.py +# (visit io.adafruit.com if you need to create an account, +# or if you need your Adafruit IO key.) +aio_username = secrets["aio_username"] +aio_key = secrets["aio_key"] + +print("Connecting to %s" % secrets["ssid"]) +wifi.radio.connect(secrets["ssid"], secrets["password"]) +print("Connected to %s!" % secrets["ssid"]) + + +pool = socketpool.SocketPool(wifi.radio) +requests = adafruit_requests.Session(pool, ssl.create_default_context()) +# Initialize an Adafruit IO HTTP API object +io = IO_HTTP(aio_username, aio_key, requests) + +print("===============\nUser Rate info:\n===============") +print("\n".join([f"{k:<30}\t=\t{v}" for (k, v) in io.get_user_rate_info().items()])) + +print(f"Throttle limit: {io.get_throttle_limit()}") +print(f"Remaining throttle limit: {io.get_remaining_throttle_limit()}") + + +# # Uncomment these lines to retrieve all user info as one big json object: +# print("Waiting 5seconds before fetching full user info (a lot of JSON output)") +# time.sleep(5) +# try: +# print("\n\nFull User info:") +# print(io.get_user_info()) +# except MemoryError as me: +# print( +# "Board ran out of memory when processing all that user info json." +# + "This is expected on most boards (ESP32-S3 should work)" +# ) +# raise me +# except Exception as e: +# print("Unexpected error!") +# raise e + +print("\n\nDone!")