diff --git a/backend/SearchEpc.py b/backend/SearchEpc.py index a63437dd..11ddec09 100644 --- a/backend/SearchEpc.py +++ b/backend/SearchEpc.py @@ -6,6 +6,7 @@ import usaddress import pandas as pd import numpy as np from epc_api.client import EpcClient +from backend.OrdnanceSurvey import OrdnanceSuveyClient from utils.logger import setup_logger from typing import List from fuzzywuzzy import process @@ -138,9 +139,9 @@ class SearchEpc: self, address1: str, postcode: str, - address2: str = None, - address3: str = None, - address4: str = None, + auth_token: str, + os_api_key: str, + full_address: str | None = None, max_retries: int = None, uprn: [int, None] = None, size=None, @@ -150,9 +151,7 @@ class SearchEpc: but can be used to find the epc for the home, if address1 and postcode are insufficient :param address1: string, propery's address line 1 :param postcode: string, propery's postcode - :param address2: string, optional, propery's address line 2 - :param address3: string, optional, propery's address line 3 - :param address4: string, optional, propery's address line 4 + :param full_address: string, optional parameter, the full address of the property :param max_retries: int, optional, number of retries to make when searching the api :param uprn: int, optional, the uprn of the property :param size: int, optional, the number of results to return. If not provided, defaults to 25 which is the api's @@ -161,16 +160,17 @@ class SearchEpc: self.address1 = address1 self.postcode = postcode - self.address2 = address2 - self.address3 = address3 - self.address4 = address4 + self.full_address = full_address self.uprn = uprn self.house_number = self.get_house_number(self.address1) self.numeric_house_number = self.extract_numeric_housenumber_part(self.house_number) self.max_retries = max_retries if max_retries is not None else self.MAX_RETRIES - self.client = EpcClient(auth_token=os.getenv("EPC_AUTH_TOKEN")) + self.client = EpcClient(auth_token=auth_token) + self.ordnance_survey_client = OrdnanceSuveyClient( + address=self.address1, postcode=self.postcode, api_key=os_api_key + ) self.data = None @@ -241,12 +241,9 @@ class SearchEpc: return self.SUCCESS if retry > 0: - print("Failed previous attempt but retry successful") + logger.info("Failed previous attempt but retry successful") # If we got nothing, final try if not response: - # TODO: Make a call to OS uprn service and get the address' uprn, just in case there is an - # issue with how we are searching the api - return { "status": 204, "message": "no data", @@ -2004,9 +2001,7 @@ class SearchEpc: # types for the estimation property_os_place = os_data[0]["DPA"] - from backend.OrdnanceSurvey import OrdnanceSuveyClient - - os_property_type, os_built_form = OrdnanceSuveyClient.parse_classification_code( + os_property_type, os_built_form = self.ordnance_survey_client.parse_classification_code( property_os_place["CLASSIFICATION_CODE"] ) @@ -2096,3 +2091,16 @@ class SearchEpc: raise NotImplementedError("implement me") return agg[key].values[0] + + def find_property(self): + """ + This method will attempt to identify a property. It will, at first, use the EPC api to try and + find the EPC for the property and the associated UPRN. If this fails, it will use the Ordnance Survey API to + find the UPRN of the address. + + Because no result may have been provided by the EPC api because of formatting issues with the address, + if the ordnance survey api is used and the uprn retrieved, the EPC api is queried again with the UPRN, just + as a final check to see if there is any EPC data. + + If there is no EPC data, the epc data will be estimated based on the surrounding properties + """ diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py index a284e50b..4100e47d 100644 --- a/backend/app/plan/router.py +++ b/backend/app/plan/router.py @@ -3,6 +3,7 @@ from datetime import datetime import numpy as np import pandas as pd from epc_api.client import EpcClient +from backend.OrdnanceSurvey import OrdnanceSuveyClient from fastapi import APIRouter, Depends from sqlalchemy.exc import IntegrityError, OperationalError from sqlalchemy.orm import sessionmaker @@ -74,6 +75,7 @@ async def trigger_plan(body: PlanTriggerRequest): # We validate each record in the file. If the record is NOT valid, we need to handle this accordingly # TODO: implment validation. We should also standardise postcode and address in some fashion as # a postcode of abcdef would be considered different to ABCDEF + # TODO: Search for the property # Create a record in db property_id, is_new = create_property( session, portfolio_id=body.portfolio_id, address=config['address'], postcode=config['postcode']