From 855581c1890eb15ba63cbbc59dbcd8439e7df55e Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Thu, 21 May 2026 16:00:59 +0000 Subject: [PATCH] =?UTF-8?q?GoogleSolarApi=20delegates=20get=5Fbuilding=5Fi?= =?UTF-8?q?nsights=20to=20GoogleSolarApiClient=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/apis/GoogleSolarApi.py | 65 ++++++---------------------------- 1 file changed, 11 insertions(+), 54 deletions(-) diff --git a/backend/apis/GoogleSolarApi.py b/backend/apis/GoogleSolarApi.py index 6fc5daa6..589d3a04 100644 --- a/backend/apis/GoogleSolarApi.py +++ b/backend/apis/GoogleSolarApi.py @@ -8,6 +8,10 @@ from sklearn.preprocessing import MinMaxScaler from tqdm import tqdm from math import sin, cos, sqrt, atan2, radians +from infrastructure.solar.google_solar_api_client import ( + BuildingInsightsNotFoundError, + GoogleSolarApiClient, +) from utils.logger import setup_logger from recommendations.Costs import Costs from backend.ml_models.AnnualBillSavings import AnnualBillSavings @@ -57,19 +61,9 @@ class GoogleSolarApi: # that we calcualte based on the property dimensions, we will correct the roof area ROOF_AREA_TOLERANCE = 1.25 - # Error Messages - ENTITY_NOT_FOUND_ERROR = 'Requested entity was not found.' - - def __init__(self, api_key, solar_materials: list, max_retries=5): - """ - Initialize the GoogleSolarApi class with the provided API key and maximum retries. - - :param api_key: The API key to authenticate requests to the Google Solar API. - :param max_retries: The maximum number of retries for the API request (default is 5). - """ + def __init__(self, api_key: str, solar_materials: list) -> None: self.api_key = api_key - self.max_retries = max_retries - self.base_url = "https://solar.googleapis.com/v1" + self._solar_client = GoogleSolarApiClient(api_key) self.insights_data = None self.roof_segments = [] @@ -90,48 +84,11 @@ class GoogleSolarApi: self.allowed_segment_indices = None - def get_building_insights(self, longitude, latitude, required_quality="MEDIUM", max_retries=None): - """ - Make an API request to retrieve building insights based on the given longitude and latitude, with retry - mechanism. - - :param longitude: The longitude of the location. - :param latitude: The latitude of the location. - :param required_quality: The required quality of the data (default is "MEDIUM"). - :param max_retries: The maximum number of retries for the API request (default is None, which uses the - instance's max_retries). - :return: The JSON response containing the building insights data. - """ - if max_retries is None: - max_retries = self.max_retries - - insights_url = f"{self.base_url}/buildingInsights:findClosest" - params = { - 'location.latitude': f'{latitude:.5f}', - 'location.longitude': f'{longitude:.5f}', - 'requiredQuality': required_quality, - 'key': self.api_key - } - - attempt = 0 - while attempt < max_retries: - try: - response = requests.get(insights_url, params=params) - response.raise_for_status() # Raise an error for bad status codes - return response.json() - except requests.exceptions.RequestException as e: - if ( - (e.response.status_code == 404) & - (e.response.json()["error"]["message"] == self.ENTITY_NOT_FOUND_ERROR) - ): - logger.warning("No building insights found for the given location.") - return {"error": self.ENTITY_NOT_FOUND_ERROR} - - attempt += 1 - print(f"Attempt {attempt} failed: {e}") - time.sleep(2 ** attempt) # Exponential backoff - if attempt >= max_retries: - raise + def get_building_insights(self, longitude: float, latitude: float, required_quality: str = "MEDIUM") -> dict: + try: + return self._solar_client.get_building_insights(longitude, latitude, required_quality) # type: ignore[arg-type] + except BuildingInsightsNotFoundError: + return {"error": GoogleSolarApiClient.ENTITY_NOT_FOUND_ERROR} @lru_cache(maxsize=128) def get(