Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ repos:
rev: 6.0.1
hooks:
- id: isort
args: ["--profile", "black"]
args: ["--profile", "black", "-o", "aiohttp", "-o", "apyhiveapi", "-o", "boto3", "-o", "botocore", "-o", "pyquery", "-o", "requests", "-o", "setuptools", "-o", "six", "-o", "urllib3"]
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.37.1
hooks:
Expand Down
6 changes: 1 addition & 5 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,9 @@ build-backend = "setuptools.build_meta"
[bdist_wheel]
universal = 1

[settings]
multi_line_output = 3
include_trailing_comma = True
known_third_party = aiohttp,boto3,botocore,pyquery,requests,setuptools,six,urllib3

[tool.isort]
profile = "black"
known_third_party = aiohttp,apyhiveapi,boto3,botocore,pyquery,requests,setuptools,six,urllib3


[flake8]
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def requirements_from_file(filename="requirements.txt"):


setup(
version="1.0.8",
version="1.0.9",
packages=["apyhiveapi", "apyhiveapi.api", "apyhiveapi.helper"],
package_dir={"apyhiveapi": "src"},
package_data={"data": ["*.json"]},
Expand Down
97 changes: 81 additions & 16 deletions src/api/hive_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

# pylint: skip-file
import json
import logging

import requests
import urllib3
from pyquery import PyQuery

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

_LOGGER = logging.getLogger(__name__)


class HiveApi:
"""Hive API Code."""
Expand Down Expand Up @@ -43,6 +46,10 @@ def __init__(self, hiveSession=None, websession=None, token=None):

def request(self, type, url, jsc=None, camera=False):
"""Make API request."""
_LOGGER.debug("request - Making %s request to: %s", type, url)
if jsc:
_LOGGER.debug("request - Request payload: %s", jsc)

if self.session is not None:
if camera:
self.headers = {
Expand Down Expand Up @@ -72,17 +79,27 @@ def request(self, type, url, jsc=None, camera=False):
"authorization": self.token,
}

if type == "GET":
return requests.get(
url=url, headers=self.headers, data=jsc, timeout=self.timeout
)
if type == "POST":
return requests.post(
url=url, headers=self.headers, data=jsc, timeout=self.timeout
)
_LOGGER.debug(
"request - Request headers: %s",
{k: v for k, v in self.headers.items() if k.lower() != "authorization"},
)

try:
if type == "GET":
return requests.get(
url=url, headers=self.headers, data=jsc, timeout=self.timeout
)
if type == "POST":
return requests.post(
url=url, headers=self.headers, data=jsc, timeout=self.timeout
)
except Exception as e:
_LOGGER.error("Request failed: %s", e)
raise

def refreshTokens(self, tokens={}):
"""Get new session tokens - DEPRECATED NOW BY AWS TOKEN MANAGEMENT."""
_LOGGER.debug("refreshTokens - Attempting token refresh (deprecated method)")
url = self.urls["refresh"]
if self.session is not None:
tokens = self.session.tokens.tokenData
Expand All @@ -97,21 +114,31 @@ def refreshTokens(self, tokens={}):
info = self.request("POST", url, jsc)
data = json.loads(info.text)
if "token" in data and self.session:
_LOGGER.debug(
"refreshTokens - Token refresh successful, updating session"
)
self.session.updateTokens(data)
self.urls.update({"base": data["platform"]["endpoint"]})
self.urls.update({"camera": data["platform"]["cameraPlatform"]})
self.json_return.update({"original": info.status_code})
self.json_return.update({"parsed": info.json()})
except (OSError, RuntimeError, ZeroDivisionError):
except (OSError, RuntimeError, ZeroDivisionError, json.JSONDecodeError) as e:
_LOGGER.error("Token refresh failed: %s", str(e))
self.error()

return self.json_return

def getLoginInfo(self):
"""Get login properties to make the login request."""
_LOGGER.debug(
"getLoginInfo - Fetching login info from: %s", self.urls["properties"]
)
url = self.urls["properties"]
try:
data = requests.get(url=url, verify=False, timeout=self.timeout)
_LOGGER.debug(
"getLoginInfo - Login info response status: %s", data.status_code
)
html = PyQuery(data.content)
json_data = json.loads(
'{"'
Expand All @@ -126,19 +153,35 @@ def getLoginInfo(self):
loginData.update({"UPID": json_data["HiveSSOPoolId"]})
loginData.update({"CLIID": json_data["HiveSSOPublicCognitoClientId"]})
loginData.update({"REGION": json_data["HiveSSOPoolId"]})
_LOGGER.debug("getLoginInfo - Login info extracted successfully")
return loginData
except (OSError, RuntimeError, ZeroDivisionError):
except (
OSError,
RuntimeError,
ZeroDivisionError,
json.JSONDecodeError,
KeyError,
) as e:
_LOGGER.error("Failed to get login info: %s", str(e))
self.error()

def getAll(self):
"""Build and query all endpoint."""
_LOGGER.debug("getAll - Fetching all devices/products/actions from Hive API")
json_return = {}
url = self.urls["base"] + self.urls["all"]
try:
info = self.request("GET", url)
json_return.update({"original": info.status_code})
json_return.update({"parsed": info.json()})
except (OSError, RuntimeError, ZeroDivisionError):
if info is not None:
json_return.update({"original": info.status_code})
json_return.update({"parsed": info.json()})
_LOGGER.debug(
"getAll - All data fetch successful, status: %s", info.status_code
)
else:
_LOGGER.error("Failed to get response from all endpoint")
except (OSError, RuntimeError, ZeroDivisionError, json.JSONDecodeError) as e:
_LOGGER.error("Failed to fetch all data: %s", str(e))
self.error()

return json_return
Expand Down Expand Up @@ -259,6 +302,12 @@ def getWeather(self, weather_url):

def setState(self, n_type, n_id, **kwargs):
"""Set the state of a Device."""
_LOGGER.debug(
"setState - Setting state for device %s (type: %s): %s",
n_id,
n_type,
kwargs,
)
jsc = (
"{"
+ ",".join(
Expand All @@ -271,9 +320,24 @@ def setState(self, n_type, n_id, **kwargs):

try:
response = self.request("POST", url, jsc)
self.json_return.update({"original": response.status_code})
self.json_return.update({"parsed": response.json()})
except (OSError, RuntimeError, ZeroDivisionError, ConnectionError):
if response is not None:
self.json_return.update({"original": response.status_code})
self.json_return.update({"parsed": response.json()})
_LOGGER.debug(
"setState - State set successfully for %s, status: %s",
n_id,
response.status_code,
)
else:
_LOGGER.error("Failed to set state for %s - no response", n_id)
except (
OSError,
RuntimeError,
ZeroDivisionError,
ConnectionError,
json.JSONDecodeError,
) as e:
_LOGGER.error("Failed to set state for %s: %s", n_id, str(e))
self.error()

return self.json_return
Expand All @@ -293,6 +357,7 @@ def setAction(self, n_id, data):

def error(self):
"""An error has occurred interacting with the Hive API."""
_LOGGER.error("API error occurred - returning error response")
self.json_return.update({"original": "Error making API call"})
self.json_return.update({"parsed": "Error making API call"})

Expand Down
3 changes: 1 addition & 2 deletions src/api/hive_async_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ async def getAll(self):
"""Build and query all endpoint."""
json_return = {}
url = self.urls["all"]
_LOGGER.debug("Fetching all nodes from Hive API.")
try:
resp = await self.request("get", url)
json_return.update({"original": resp.status})
Expand Down Expand Up @@ -303,7 +302,7 @@ async def getWeather(self, weather_url):

async def setState(self, n_type, n_id, **kwargs):
"""Set the state of a Device."""
_LOGGER.debug("Setting state for %s/%s: %s", n_type, n_id, kwargs)
_LOGGER.debug("setState - Setting state for %s/%s: %s", n_type, n_id, kwargs)
json_return = {}
jsc = (
"{"
Expand Down
Loading
Loading