mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
154 lines
5.1 KiB
Python
154 lines
5.1 KiB
Python
import os
|
|
import time
|
|
from epc_api.client import EpcClient
|
|
from utils.logger import setup_logger
|
|
from typing import List
|
|
|
|
logger = setup_logger()
|
|
|
|
|
|
class SearchEpc:
|
|
"""
|
|
Given address information about a home, this class is responsible for retrieving the EPC data associated
|
|
to the property.
|
|
|
|
For a home, we might have address lines 1, 2, 3 and 4, as well as a postcode.
|
|
|
|
Often, simply searching the EPC database with address line 1 and postcode will be enough to find
|
|
the property, but there are some cases where this is not true and we might need to utilise other
|
|
combinations about the home to find the property
|
|
"""
|
|
|
|
MAX_RETRIES = 5
|
|
|
|
SUCCESS = {
|
|
"status": 200,
|
|
"message": "success",
|
|
"error": None
|
|
}
|
|
|
|
NODATA = {
|
|
"status": 201,
|
|
"message": "No data",
|
|
"error": None
|
|
}
|
|
|
|
def __init__(
|
|
self,
|
|
address1: str,
|
|
postcode: str,
|
|
address2: str = None,
|
|
address3: str = None,
|
|
address4: str = None,
|
|
max_retries: int = None
|
|
):
|
|
"""
|
|
Address lines 1 and postcode are mandatory fields. The other address lines are optional
|
|
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
|
|
"""
|
|
|
|
self.address1 = address1
|
|
self.postcode = postcode
|
|
self.address2 = address2
|
|
self.address3 = address3
|
|
self.address4 = address4
|
|
|
|
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.data = None
|
|
|
|
def search(self):
|
|
# Get the EPC data with retries
|
|
response = {}
|
|
for retry in range(self.max_retries):
|
|
try:
|
|
response = self.client.domestic.search(
|
|
params={"address": self.address1, "postcode": self.postcode}
|
|
)
|
|
|
|
if response:
|
|
self.data = response
|
|
return self.SUCCESS
|
|
|
|
if retry > 0:
|
|
print("Failed previous attempt but retry successful")
|
|
# If we got nothing, final try
|
|
if not response:
|
|
raise NotImplementedError("Implement me")
|
|
# response = client.domestic.search(
|
|
# params={"address": " ".join([home["Dwelling num"], home["Street"]]),
|
|
# "postcode": home["Postcode"]}
|
|
# )
|
|
|
|
# TODO: Eventually, if we have nothing, we should exit with a 201 or 202, saying that
|
|
# there is not data for this property
|
|
return {
|
|
"status": 200,
|
|
"message": "success",
|
|
"error": None
|
|
}
|
|
|
|
except Exception as e:
|
|
if retry < self.max_retries - 1:
|
|
# If not the last retry, wait for 3 seconds before retrying
|
|
time.sleep(3)
|
|
else:
|
|
# If it's the last retry, we continue
|
|
return {
|
|
"status": 500,
|
|
"message": "Could not retrieve EPC data",
|
|
"error": str(e)
|
|
}
|
|
|
|
def retrieve(self):
|
|
|
|
"""
|
|
Given a successful search, this method will format the data and return it
|
|
:return:
|
|
"""
|
|
|
|
if self.data is None:
|
|
raise ValueError("data is missing, run search first")
|
|
|
|
rows = self.data["rows"]
|
|
|
|
# We perform some checks on the rows
|
|
# Firstly, we should only have 1 urpn so if we have multiple, we'll need to filter down the
|
|
# property further
|
|
uprns = {r["uprn"] for r in rows}
|
|
|
|
if len(uprns) != 1:
|
|
raise NotImplementedError("More than one unique UPRN, need to handle this case")
|
|
|
|
# We now check for a full sap epc:
|
|
full_sap_epc = [r for r in rows if r["transaction-type"] == "new dwelling"]
|
|
full_sap_epc = full_sap_epc[0] if full_sap_epc else {}
|
|
|
|
# Finally, we identify the newest epc and the rest, and then return
|
|
newest_epc, older_epcs = self.filter_newest_epc(list_of_epcs=rows)
|
|
|
|
return newest_epc, older_epcs, full_sap_epc
|
|
|
|
@staticmethod
|
|
def filter_newest_epc(list_of_epcs: List):
|
|
newest_response = [
|
|
r for r in list_of_epcs if
|
|
r["lodgement-datetime"] == max([x["lodgement-datetime"] for x in list_of_epcs])
|
|
]
|
|
|
|
if not newest_response:
|
|
return {}, []
|
|
|
|
if len(newest_response) != 1:
|
|
raise Exception("More than one result found for this address - investigate me")
|
|
|
|
older_epcs = [epc for epc in list_of_epcs if epc["lmk-key"] != newest_response[0]["lmk-key"]]
|
|
|
|
return newest_response[0], older_epcs
|