From e2eee5754816cac79d526516a8e2aeaa1620e421 Mon Sep 17 00:00:00 2001 From: Adam Jacques Date: Wed, 8 Jan 2025 22:37:05 -0800 Subject: [PATCH 1/6] Pass exception to python logger TypeError: can only concatenate str (not "TypeError") to str --- pytryfi/common/query.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pytryfi/common/query.py b/pytryfi/common/query.py index f9d845f..970db1e 100644 --- a/pytryfi/common/query.py +++ b/pytryfi/common/query.py @@ -14,7 +14,7 @@ def getUserDetail(sessionId): LOGGER.debug(f"getUserDetails: {response}") return response['data']['currentUser'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def getPetList(sessionId): @@ -28,7 +28,7 @@ def getPetList(sessionId): LOGGER.debug(f"getPetList: {response}") return response['data']['currentUser']['userHouseholds'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def getBaseList(sessionId): @@ -42,7 +42,7 @@ def getBaseList(sessionId): LOGGER.debug(f"getBaseList: {response}") return response['data']['currentUser']['userHouseholds'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def getCurrentPetLocation(sessionId, petId): @@ -54,7 +54,7 @@ def getCurrentPetLocation(sessionId, petId): LOGGER.debug(f"getCurrentPetLocation: {response}") return response['data']['pet']['ongoingActivity'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def getCurrentPetStats(sessionId, petId): @@ -64,7 +64,7 @@ def getCurrentPetStats(sessionId, petId): LOGGER.debug(f"getCurrentPetStats: {response}") return response['data']['pet'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def getCurrentPetRestStats(sessionId, petId): @@ -74,7 +74,7 @@ def getCurrentPetRestStats(sessionId, petId): LOGGER.debug(f"getCurrentPetStats: {response}") return response['data']['pet'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def getDevicedetails(sessionId, petId): @@ -84,7 +84,7 @@ def getDevicedetails(sessionId, petId): LOGGER.debug(f"getDevicedetails: {response}") return response['data']['pet'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def setLedColor(sessionId, deviceId, ledColorCode): @@ -95,7 +95,7 @@ def setLedColor(sessionId, deviceId, ledColorCode): LOGGER.debug(f"setLedColor: {response}") return response['data'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def turnOnOffLed(sessionId, moduleId, ledEnabled): @@ -106,7 +106,7 @@ def turnOnOffLed(sessionId, moduleId, ledEnabled): LOGGER.debug(f"turnOnOffLed: {response}") return response['data'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def setLostDogMode(sessionId, moduleId, action): @@ -121,14 +121,14 @@ def setLostDogMode(sessionId, moduleId, action): LOGGER.debug(f"setLostDogMode: {response}") return response['data'] except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def getGraphqlURL(): try: return API_HOST_URL_BASE + API_GRAPHQL except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def mutation(sessionId, qString, qVariables): @@ -140,7 +140,7 @@ def mutation(sessionId, qString, qVariables): jsonObject = execute(url, sessionId, params=params, method='POST').json() return jsonObject except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def query(sessionId, qString): @@ -151,7 +151,7 @@ def query(sessionId, qString): jsonObject = execute(url, sessionId, params=params).json() return jsonObject except Exception as e: - LOGGER.error("Error performing query: " + e) + LOGGER.error(f"Error performing query", exc_info=e) capture_exception(e) def execute(url, sessionId, method='GET', params=None, cookies=None): From d36dfdf03c644013448d7fd6c0ed320011963498 Mon Sep 17 00:00:00 2001 From: Adam Jacques Date: Fri, 10 Jan 2025 09:40:52 -0800 Subject: [PATCH 2/6] Remove extra layer of try-catches --- pytryfi/__init__.py | 6 +- pytryfi/common/query.py | 209 ++++++++++++++-------------------------- 2 files changed, 77 insertions(+), 138 deletions(-) diff --git a/pytryfi/__init__.py b/pytryfi/__init__.py index 0a3eb7a..7badb56 100644 --- a/pytryfi/__init__.py +++ b/pytryfi/__init__.py @@ -152,6 +152,7 @@ def updateBases(self): h = h + 1 self._bases = updatedBases except Exception as e: + LOGGER.error("Error fetching bases", exc_info=e) capture_exception(e) # return the pet object based on petId @@ -228,7 +229,4 @@ def login(self): LOGGER.debug(f"Successfully logged in. UserId: {self._userId}") except requests.RequestException as e: LOGGER.error(f"Cannot login, error: ({e})") - capture_exception(e) - raise requests.RequestException(e) - except Exception as e: - capture_exception(e) + raise e diff --git a/pytryfi/common/query.py b/pytryfi/common/query.py index 970db1e..b462636 100644 --- a/pytryfi/common/query.py +++ b/pytryfi/common/query.py @@ -8,165 +8,106 @@ LOGGER = logging.getLogger(__name__) def getUserDetail(sessionId): - try: - qString = QUERY_CURRENT_USER + FRAGMENT_USER_DETAILS - response = query(sessionId, qString) - LOGGER.debug(f"getUserDetails: {response}") - return response['data']['currentUser'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + qString = QUERY_CURRENT_USER + FRAGMENT_USER_DETAILS + response = query(sessionId, qString) + LOGGER.debug(f"getUserDetails: {response}") + return response['data']['currentUser'] def getPetList(sessionId): - try: - qString = QUERY_CURRENT_USER_FULL_DETAIL + FRAGMENT_USER_DETAILS \ - + FRAGMENT_USER_FULL_DETAILS + FRAGMENT_PET_PROFILE + FRAGEMENT_BASE_PET_PROFILE \ - + FRAGMENT_BASE_DETAILS + FRAGMENT_POSITION_COORDINATES + FRAGMENT_BREED_DETAILS \ - + FRAGMENT_PHOTO_DETAILS + FRAGMENT_DEVICE_DETAILS + FRAGMENT_LED_DETAILS + FRAGMENT_OPERATIONAL_DETAILS \ - + FRAGMENT_CONNECTION_STATE_DETAILS - response = query(sessionId, qString) - LOGGER.debug(f"getPetList: {response}") - return response['data']['currentUser']['userHouseholds'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + qString = QUERY_CURRENT_USER_FULL_DETAIL + FRAGMENT_USER_DETAILS \ + + FRAGMENT_USER_FULL_DETAILS + FRAGMENT_PET_PROFILE + FRAGEMENT_BASE_PET_PROFILE \ + + FRAGMENT_BASE_DETAILS + FRAGMENT_POSITION_COORDINATES + FRAGMENT_BREED_DETAILS \ + + FRAGMENT_PHOTO_DETAILS + FRAGMENT_DEVICE_DETAILS + FRAGMENT_LED_DETAILS + FRAGMENT_OPERATIONAL_DETAILS \ + + FRAGMENT_CONNECTION_STATE_DETAILS + response = query(sessionId, qString) + LOGGER.debug(f"getPetList: {response}") + return response['data']['currentUser']['userHouseholds'] def getBaseList(sessionId): - try: - qString = QUERY_CURRENT_USER_FULL_DETAIL + FRAGMENT_USER_DETAILS \ - + FRAGMENT_USER_FULL_DETAILS + FRAGMENT_PET_PROFILE + FRAGEMENT_BASE_PET_PROFILE \ - + FRAGMENT_BASE_DETAILS + FRAGMENT_POSITION_COORDINATES + FRAGMENT_BREED_DETAILS \ - + FRAGMENT_PHOTO_DETAILS + FRAGMENT_DEVICE_DETAILS + FRAGMENT_LED_DETAILS + FRAGMENT_OPERATIONAL_DETAILS \ - + FRAGMENT_CONNECTION_STATE_DETAILS - response = query(sessionId, qString) - LOGGER.debug(f"getBaseList: {response}") - return response['data']['currentUser']['userHouseholds'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + qString = QUERY_CURRENT_USER_FULL_DETAIL + FRAGMENT_USER_DETAILS \ + + FRAGMENT_USER_FULL_DETAILS + FRAGMENT_PET_PROFILE + FRAGEMENT_BASE_PET_PROFILE \ + + FRAGMENT_BASE_DETAILS + FRAGMENT_POSITION_COORDINATES + FRAGMENT_BREED_DETAILS \ + + FRAGMENT_PHOTO_DETAILS + FRAGMENT_DEVICE_DETAILS + FRAGMENT_LED_DETAILS + FRAGMENT_OPERATIONAL_DETAILS \ + + FRAGMENT_CONNECTION_STATE_DETAILS + response = query(sessionId, qString) + LOGGER.debug(f"getBaseList: {response}") + return response['data']['currentUser']['userHouseholds'] def getCurrentPetLocation(sessionId, petId): - try: - qString = QUERY_PET_CURRENT_LOCATION.replace(VAR_PET_ID, petId) + FRAGMENT_ONGOING_ACTIVITY_DETAILS \ - + FRAGMENT_UNCERTAINTY_DETAILS + FRAGMENT_CIRCLE_DETAILS + FRAGMENT_LOCATION_POINT \ - + FRAGMENT_PLACE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_POSITION_COORDINATES - response = query(sessionId, qString) - LOGGER.debug(f"getCurrentPetLocation: {response}") - return response['data']['pet']['ongoingActivity'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + qString = QUERY_PET_CURRENT_LOCATION.replace(VAR_PET_ID, petId) + FRAGMENT_ONGOING_ACTIVITY_DETAILS \ + + FRAGMENT_UNCERTAINTY_DETAILS + FRAGMENT_CIRCLE_DETAILS + FRAGMENT_LOCATION_POINT \ + + FRAGMENT_PLACE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_POSITION_COORDINATES + response = query(sessionId, qString) + LOGGER.debug(f"getCurrentPetLocation: {response}") + return response['data']['pet']['ongoingActivity'] def getCurrentPetStats(sessionId, petId): - try: - qString = QUERY_PET_ACTIVITY.replace(VAR_PET_ID, petId) + FRAGMENT_ACTIVITY_SUMMARY_DETAILS - response = query(sessionId, qString) - LOGGER.debug(f"getCurrentPetStats: {response}") - return response['data']['pet'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + qString = QUERY_PET_ACTIVITY.replace(VAR_PET_ID, petId) + FRAGMENT_ACTIVITY_SUMMARY_DETAILS + response = query(sessionId, qString) + LOGGER.debug(f"getCurrentPetStats: {response}") + return response['data']['pet'] def getCurrentPetRestStats(sessionId, petId): - try: - qString = QUERY_PET_REST.replace(VAR_PET_ID, petId) + FRAGMENT_REST_SUMMARY_DETAILS - response = query(sessionId, qString) - LOGGER.debug(f"getCurrentPetStats: {response}") - return response['data']['pet'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + qString = QUERY_PET_REST.replace(VAR_PET_ID, petId) + FRAGMENT_REST_SUMMARY_DETAILS + response = query(sessionId, qString) + LOGGER.debug(f"getCurrentPetStats: {response}") + return response['data']['pet'] def getDevicedetails(sessionId, petId): - try: - qString = QUERY_PET_DEVICE_DETAILS.replace(VAR_PET_ID, petId) + FRAGMENT_PET_PROFILE + FRAGEMENT_BASE_PET_PROFILE + FRAGMENT_DEVICE_DETAILS + FRAGMENT_LED_DETAILS + FRAGMENT_OPERATIONAL_DETAILS + FRAGMENT_CONNECTION_STATE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_BREED_DETAILS + FRAGMENT_PHOTO_DETAILS - response = query(sessionId, qString) - LOGGER.debug(f"getDevicedetails: {response}") - return response['data']['pet'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + qString = QUERY_PET_DEVICE_DETAILS.replace(VAR_PET_ID, petId) + FRAGMENT_PET_PROFILE + FRAGEMENT_BASE_PET_PROFILE + FRAGMENT_DEVICE_DETAILS + FRAGMENT_LED_DETAILS + FRAGMENT_OPERATIONAL_DETAILS + FRAGMENT_CONNECTION_STATE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_BREED_DETAILS + FRAGMENT_PHOTO_DETAILS + response = query(sessionId, qString) + LOGGER.debug(f"getDevicedetails: {response}") + return response['data']['pet'] def setLedColor(sessionId, deviceId, ledColorCode): - try: - qString = MUTATION_SET_LED_COLOR + FRAGMENT_DEVICE_DETAILS + FRAGMENT_OPERATIONAL_DETAILS + FRAGMENT_CONNECTION_STATE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_LED_DETAILS - qVariables = '{"moduleId":"'+deviceId+'","ledColorCode":'+str(ledColorCode)+'}' - response = mutation(sessionId, qString, qVariables) - LOGGER.debug(f"setLedColor: {response}") - return response['data'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + qString = MUTATION_SET_LED_COLOR + FRAGMENT_DEVICE_DETAILS + FRAGMENT_OPERATIONAL_DETAILS + FRAGMENT_CONNECTION_STATE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_LED_DETAILS + qVariables = '{"moduleId":"'+deviceId+'","ledColorCode":'+str(ledColorCode)+'}' + response = mutation(sessionId, qString, qVariables) + LOGGER.debug(f"setLedColor: {response}") + return response['data'] def turnOnOffLed(sessionId, moduleId, ledEnabled): - try: - qString = MUTATION_DEVICE_OPS + FRAGMENT_DEVICE_DETAILS + FRAGMENT_OPERATIONAL_DETAILS + FRAGMENT_CONNECTION_STATE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_LED_DETAILS - qVariables = '{"input": {"moduleId":"'+moduleId+'","ledEnabled":'+str(ledEnabled).lower()+'}}' - response = mutation(sessionId, qString, qVariables) - LOGGER.debug(f"turnOnOffLed: {response}") - return response['data'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + qString = MUTATION_DEVICE_OPS + FRAGMENT_DEVICE_DETAILS + FRAGMENT_OPERATIONAL_DETAILS + FRAGMENT_CONNECTION_STATE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_LED_DETAILS + qVariables = '{"input": {"moduleId":"'+moduleId+'","ledEnabled":'+str(ledEnabled).lower()+'}}' + response = mutation(sessionId, qString, qVariables) + LOGGER.debug(f"turnOnOffLed: {response}") + return response['data'] def setLostDogMode(sessionId, moduleId, action): - try: - if action: - mode = PET_MODE_LOST - else: - mode = PET_MODE_NORMAL - qString = MUTATION_DEVICE_OPS + FRAGMENT_DEVICE_DETAILS + FRAGMENT_OPERATIONAL_DETAILS + FRAGMENT_CONNECTION_STATE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_LED_DETAILS - qVariables = '{"input": {"moduleId":"'+moduleId+'","mode":"'+mode+'"}}' - response = mutation(sessionId, qString, qVariables) - LOGGER.debug(f"setLostDogMode: {response}") - return response['data'] - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + if action: + mode = PET_MODE_LOST + else: + mode = PET_MODE_NORMAL + qString = MUTATION_DEVICE_OPS + FRAGMENT_DEVICE_DETAILS + FRAGMENT_OPERATIONAL_DETAILS + FRAGMENT_CONNECTION_STATE_DETAILS + FRAGMENT_USER_DETAILS + FRAGMENT_LED_DETAILS + qVariables = '{"input": {"moduleId":"'+moduleId+'","mode":"'+mode+'"}}' + response = mutation(sessionId, qString, qVariables) + LOGGER.debug(f"setLostDogMode: {response}") + return response['data'] def getGraphqlURL(): - try: - return API_HOST_URL_BASE + API_GRAPHQL - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + return API_HOST_URL_BASE + API_GRAPHQL def mutation(sessionId, qString, qVariables): - try: - jsonObject = None - url = getGraphqlURL() - - params = {"query": qString, "variables": json.loads(qVariables)} - jsonObject = execute(url, sessionId, params=params, method='POST').json() - return jsonObject - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + jsonObject = None + url = getGraphqlURL() + + params = {"query": qString, "variables": json.loads(qVariables)} + jsonObject = execute(url, sessionId, params=params, method='POST').json() + return jsonObject def query(sessionId, qString): - try: - jsonObject = None - url = getGraphqlURL() - params={'query': qString} - jsonObject = execute(url, sessionId, params=params).json() - return jsonObject - except Exception as e: - LOGGER.error(f"Error performing query", exc_info=e) - capture_exception(e) + jsonObject = None + url = getGraphqlURL() + params={'query': qString} + jsonObject = execute(url, sessionId, params=params).json() + return jsonObject def execute(url, sessionId, method='GET', params=None, cookies=None): response = None - try: - if method == 'GET': - response = sessionId.get(url, params=params) - elif method == 'POST': - response = sessionId.post(url, json=params) - else: - raise TryFiError(f"Method Passed was invalid: {method}") - except requests.RequestException as e: - capture_exception(e) - raise requests.RequestException(e) - except Exception as e: - capture_exception(e) + if method == 'GET': + response = sessionId.get(url, params=params) + elif method == 'POST': + response = sessionId.post(url, json=params) + else: + raise TryFiError(f"Method Passed was invalid: {method}") return response - \ No newline at end of file From 0c251fd2cc43bfb607789ddb76f01ffd5938ee71 Mon Sep 17 00:00:00 2001 From: Adam Jacques Date: Fri, 10 Jan 2025 09:46:21 -0800 Subject: [PATCH 3/6] More exception cleanup --- pytryfi/fiPet.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/pytryfi/fiPet.py b/pytryfi/fiPet.py index b0009f3..bae4cda 100644 --- a/pytryfi/fiPet.py +++ b/pytryfi/fiPet.py @@ -62,12 +62,8 @@ def setPetDetailsJSON(self, petJSON): #capture_exception(e) LOGGER.warning(f"Cannot find photo of your pet. Defaulting to empty string.") self._photoLink = "" - try: - self._device = FiDevice(petJSON['device']['id']) - self._device.setDeviceDetailsJSON(petJSON['device']) - except Exception as e: - capture_exception(e) - + self._device = FiDevice(petJSON['device']['id']) + self._device.setDeviceDetailsJSON(petJSON['device']) def __str__(self): return f"Last Updated - {self.lastUpdated} - Pet ID: {self.petId} Name: {self.name} Is Lost: {self.isLost} From: {self.homeCityState} ActivityType: {self.activityType} Located: {self.currLatitude},{self.currLongitude} Last Updated: {self.currStartTime}\n \ using Device/Collar: {self._device}" @@ -103,6 +99,22 @@ def setCurrentLocation(self, activityJSON): except Exception as e: capture_exception(e) + def setConnectedTo(self, connectedToJSON): + connectedToString = "" + try: + typename = connectedToJSON['__typename'] + if typename == 'ConnectedToUser': + connectedToString = connectedToJSON['user']['firstName'] + " " + connectedToJSON['user']['lastName'] + elif typename == 'ConnectedToCellular': + connectedToString = "Cellular Signal Strength - " + str(connectedToJSON['signalStrengthPercent']) + elif typename == 'ConnectedToBase': + connectedToString = "Base ID - " + connectedToJSON['chargingBase']['id'] + else: + connectedToString = "unknown" + return connectedToString + except: + return "unknown" + # set the Pet's current steps, goals and distance details for daily, weekly and monthly def setStats(self, activityJSONDaily, activityJSONWeekly, activityJSONMonthly): try: @@ -391,6 +403,10 @@ def activityType(self): @property def areaName(self): return self._areaName + + @property + def connectedTo(self): + return self._connectedTo def getCurrPlaceName(self): return self.currPlaceName From 4a50dda96774714af21c2273ca90ace8b5985e81 Mon Sep 17 00:00:00 2001 From: Adam Jacques Date: Fri, 10 Jan 2025 09:46:28 -0800 Subject: [PATCH 4/6] import connected to change --- pytryfi/fiPet.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pytryfi/fiPet.py b/pytryfi/fiPet.py index bae4cda..a60eeba 100644 --- a/pytryfi/fiPet.py +++ b/pytryfi/fiPet.py @@ -64,6 +64,8 @@ def setPetDetailsJSON(self, petJSON): self._photoLink = "" self._device = FiDevice(petJSON['device']['id']) self._device.setDeviceDetailsJSON(petJSON['device']) + self._connectedTo = self.setConnectedTo(petJSON['device']['lastConnectionState']) + def __str__(self): return f"Last Updated - {self.lastUpdated} - Pet ID: {self.petId} Name: {self.name} Is Lost: {self.isLost} From: {self.homeCityState} ActivityType: {self.activityType} Located: {self.currLatitude},{self.currLongitude} Last Updated: {self.currStartTime}\n \ using Device/Collar: {self._device}" @@ -403,7 +405,7 @@ def activityType(self): @property def areaName(self): return self._areaName - + @property def connectedTo(self): return self._connectedTo From c487131d6b872948e6aadf9883cac9f171ab6ef5 Mon Sep 17 00:00:00 2001 From: Adam Jacques Date: Fri, 10 Jan 2025 13:49:59 -0800 Subject: [PATCH 5/6] Clean-up Python code. Remove try-catches. Organize error handling --- .gitignore | 1 + pytryfi/__init__.py | 8 +-- pytryfi/common/query.py | 10 ++-- pytryfi/fiPet.py | 119 +++++++++++++--------------------------- 4 files changed, 46 insertions(+), 92 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ba0430d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ \ No newline at end of file diff --git a/pytryfi/__init__.py b/pytryfi/__init__.py index 7badb56..ad8da95 100644 --- a/pytryfi/__init__.py +++ b/pytryfi/__init__.py @@ -92,9 +92,8 @@ def updatePets(self): try: petListJSON = query.getPetList(self._session) updatedPets = [] - h = 0 for house in petListJSON: - for pet in petListJSON[h]['household']['pets']: + for pet in house['household']['pets']: p = FiPet(pet['id']) p.setPetDetailsJSON(pet) #get the current location and set it @@ -108,7 +107,6 @@ def updatePets(self): p.setRestStats(pRestStatsJSON['dailyStat'],pRestStatsJSON['weeklyStat'],pRestStatsJSON['monthlyStat']) LOGGER.debug(f"Adding Pet: {p._name} with Device: {p._device._deviceId}") updatedPets.append(p) - h = h + 1 self._pets = updatedPets except Exception as e: capture_exception(e) @@ -143,13 +141,11 @@ def updateBases(self): try: updatedBases = [] baseListJSON = query.getBaseList(self._session) - h = 0 for house in baseListJSON: - for base in baseListJSON[h]['household']['bases']: + for base in house['household']['bases']: b = FiBase(base['baseId']) b.setBaseDetailsJSON(base) updatedBases.append(b) - h = h + 1 self._bases = updatedBases except Exception as e: LOGGER.error("Error fetching bases", exc_info=e) diff --git a/pytryfi/common/query.py b/pytryfi/common/query.py index b462636..1fe8034 100644 --- a/pytryfi/common/query.py +++ b/pytryfi/common/query.py @@ -1,9 +1,9 @@ from pytryfi.const import * from pytryfi.exceptions import * import json -import requests import logging -from sentry_sdk import capture_exception +import requests +from typing import Literal LOGGER = logging.getLogger(__name__) @@ -95,19 +95,19 @@ def mutation(sessionId, qString, qVariables): jsonObject = execute(url, sessionId, params=params, method='POST').json() return jsonObject -def query(sessionId, qString): +def query(sessionId : requests.Session, qString): jsonObject = None url = getGraphqlURL() params={'query': qString} jsonObject = execute(url, sessionId, params=params).json() return jsonObject -def execute(url, sessionId, method='GET', params=None, cookies=None): +def execute(url : str, sessionId : requests.Session, method: Literal['GET', 'POST'] = 'GET', params=None, cookies=None): response = None if method == 'GET': response = sessionId.get(url, params=params) elif method == 'POST': response = sessionId.post(url, json=params) else: - raise TryFiError(f"Method Passed was invalid: {method}") + raise TryFiError(f"Method Passed was invalid: {method}. Only GET and POST are supported") return response diff --git a/pytryfi/fiPet.py b/pytryfi/fiPet.py index a60eeba..2e7c4a7 100644 --- a/pytryfi/fiPet.py +++ b/pytryfi/fiPet.py @@ -1,9 +1,9 @@ +import datetime import logging -from pytryfi.fiDevice import FiDevice from pytryfi.common import query -from pytryfi.exceptions import * from pytryfi.const import PET_ACTIVITY_ONGOINGWALK -import datetime +from pytryfi.exceptions import * +from pytryfi.fiDevice import FiDevice from sentry_sdk import capture_exception LOGGER = logging.getLogger(__name__) @@ -12,17 +12,9 @@ class FiPet(object): def __init__(self, petId): self._petId = petId - def setPetDetailsJSON(self, petJSON): - try: - self._name = petJSON['name'] - except: - LOGGER.warning(f"Unknown Pet Name") - self._name = "Unknown Pet Name" - try: - self._homeCityState = petJSON['homeCityState'] - except: - LOGGER.warning(f"Unknown City") - self._homeCityState = "FakeCity" + def setPetDetailsJSON(self, petJSON: dict): + self._name = petJSON.get('name') + self._homeCityState = petJSON.get('homeCityState') try: self._yearOfBirth = int(petJSON['yearOfBirth']) except: @@ -37,23 +29,14 @@ def setPetDetailsJSON(self, petJSON): self._dayOfBirth = int(petJSON['dayOfBirth']) except: LOGGER.warning(f"Unknown day of birth") - self._dayOfBirth = 1 - try: - self._gender = petJSON['gender'] - except: - LOGGER.warning(f"Unknown Gender") - self._gender = "Male" - try: - #weight is in kg - self._weight = float(petJSON['weight']) - except: - LOGGER.warning(f"Unknown Weight") - self._weight = float(1.00) + self._dayOfBirth = None + self._gender = petJSON.get('gender') + self._weight = float(petJSON['weight']) if 'weight' in petJSON else None try: self._breed = petJSON['breed']['name'] except: LOGGER.warning(f"Unknown Breed of Dog") - self._breed = "Dog" + self._breed = None #track last updated self._lastUpdated = datetime.datetime.now() try: @@ -78,21 +61,20 @@ def setCurrentLocation(self, activityJSON): try: if activityType == PET_ACTIVITY_ONGOINGWALK: positionSize = len(activityJSON['positions']) - self._currLongitude = float(activityJSON['positions'][positionSize-1]['position']['longitude']) - self._currLatitude = float(activityJSON['positions'][positionSize-1]['position']['latitude']) - self._currStartTime = datetime.datetime.fromisoformat(activityJSON['start'].replace('Z', '+00:00')) + currentPosition = activityJSON['positions'][positionSize-1]['position'] + self._currLongitude = float(currentPosition['longitude']) + self._currLatitude = float(currentPosition['latitude']) else: self._currLongitude = float(activityJSON['position']['longitude']) self._currLatitude = float(activityJSON['position']['latitude']) - self._currStartTime = datetime.datetime.fromisoformat(activityJSON['start'].replace('Z', '+00:00')) - try: + self._currStartTime = datetime.datetime.fromisoformat(activityJSON['start'].replace('Z', '+00:00')) + + if 'place' in activityJSON: self._currPlaceName = activityJSON['place']['name'] self._currPlaceAddress = activityJSON['place']['address'] - except Exception as e: - #capture_exception(e) - LOGGER.warning("Could not set place, defaulting to Unknown") - self._currPlaceName = "UNKNOWN" - self._currPlaceAddress = "UNKNOWN" + else: + self._currPlaceName = None + self._currPlaceAddress = None self._lastUpdated = datetime.datetime.now() except TryFiError as e: capture_exception(e) @@ -103,53 +85,29 @@ def setCurrentLocation(self, activityJSON): def setConnectedTo(self, connectedToJSON): connectedToString = "" - try: - typename = connectedToJSON['__typename'] - if typename == 'ConnectedToUser': - connectedToString = connectedToJSON['user']['firstName'] + " " + connectedToJSON['user']['lastName'] - elif typename == 'ConnectedToCellular': - connectedToString = "Cellular Signal Strength - " + str(connectedToJSON['signalStrengthPercent']) - elif typename == 'ConnectedToBase': - connectedToString = "Base ID - " + connectedToJSON['chargingBase']['id'] - else: - connectedToString = "unknown" - return connectedToString - except: - return "unknown" + typename = connectedToJSON['__typename'] + if typename == 'ConnectedToUser': + connectedToString = connectedToJSON['user']['firstName'] + " " + connectedToJSON['user']['lastName'] + elif typename == 'ConnectedToCellular': + connectedToString = "Cellular Signal Strength - " + str(connectedToJSON['signalStrengthPercent']) + elif typename == 'ConnectedToBase': + connectedToString = "Base ID - " + connectedToJSON['chargingBase']['id'] + else: + connectedToString = None + return connectedToString # set the Pet's current steps, goals and distance details for daily, weekly and monthly def setStats(self, activityJSONDaily, activityJSONWeekly, activityJSONMonthly): - try: #distance is in metres - self._dailyGoal = int(activityJSONDaily['stepGoal']) - self._dailySteps = int(activityJSONDaily['totalSteps']) - self._dailyTotalDistance = float(activityJSONDaily['totalDistance']) - except TryFiError as e: - LOGGER.error(f"Unable to set values Daily Stats for Pet {self.name}.\nException: {e}\nwhile parsing {activityJSONDaily}") - capture_exception(e) - raise TryFiError("Unable to set Pet Daily Stats") - except Exception as e: - capture_exception(e) - try: - self._weeklyGoal = int(activityJSONWeekly['stepGoal']) - self._weeklySteps = int(activityJSONWeekly['totalSteps']) - self._weeklyTotalDistance = float(activityJSONWeekly['totalDistance']) - except TryFiError as e: - LOGGER.error(f"Unable to set values Weekly Stats for Pet {self.name}.\nException: {e}\nwhile parsing {activityJSONWeekly}") - capture_exception(e) - raise TryFiError("Unable to set Pet Weekly Stats") - except Exception as e: - capture_exception(e) - try: - self._monthlyGoal = int(activityJSONMonthly['stepGoal']) - self._monthlySteps = int(activityJSONMonthly['totalSteps']) - self._monthlyTotalDistance = float(activityJSONMonthly['totalDistance']) - except TryFiError as e: - LOGGER.error(f"Unable to set values Monthly Stats for Pet {self.name}.\nException: {e}\nwhile parsing {activityJSONMonthly}") - capture_exception(e) - raise TryFiError("Unable to set Pet Monthly Stats") - except Exception as e: - capture_exception(e) + self._dailyGoal = int(activityJSONDaily['stepGoal']) + self._dailySteps = int(activityJSONDaily['totalSteps']) + self._dailyTotalDistance = float(activityJSONDaily['totalDistance']) + self._weeklyGoal = int(activityJSONWeekly['stepGoal']) + self._weeklySteps = int(activityJSONWeekly['totalSteps']) + self._weeklyTotalDistance = float(activityJSONWeekly['totalDistance']) + self._monthlyGoal = int(activityJSONMonthly['stepGoal']) + self._monthlySteps = int(activityJSONMonthly['totalSteps']) + self._monthlyTotalDistance = float(activityJSONMonthly['totalDistance']) self._lastUpdated = datetime.datetime.now() @@ -293,7 +251,6 @@ def setLostDogMode(self, sessionId, action): capture_exception(e) return True except Exception as e: - LOGGER.error(f"Could not complete Lost Dog Mode request:\n{e}") LOGGER.error(f"Could not complete turn on/off light where ledEnable is {action}.\nException: {e}") capture_exception(e) return False From 4ae6970e27cb0b7dd77a224fecdbfd0017eaeb93 Mon Sep 17 00:00:00 2001 From: sbabcock23 <71794130+sbabcock23@users.noreply.github.com> Date: Fri, 10 Jan 2025 21:00:39 -0600 Subject: [PATCH 6/6] Update const.py --- pytryfi/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytryfi/const.py b/pytryfi/const.py index e3f3184..b4cd40c 100644 --- a/pytryfi/const.py +++ b/pytryfi/const.py @@ -1,6 +1,6 @@ SENTRY_URL = "https://c7618923f758480ca2af05a21123f855@o580516.ingest.sentry.io/5735605" -PYTRYFI_VERSION = "0.0.21" +PYTRYFI_VERSION = "0.0.22" API_HOST_URL_BASE = "https://api.tryfi.com" API_GRAPHQL = "/graphql"