started work on peabody

This commit is contained in:
Khalim Conn-Kowlessar 2025-11-25 12:15:06 +00:00
parent fd2d893499
commit caeb776428
7 changed files with 37 additions and 17 deletions

View file

@ -2,7 +2,6 @@ import time
import random
import pandas as pd
from adhoc.investigation import newest_epc
from backend.SearchEpc import SearchEpc
from etl.find_my_epc.RetrieveFindMyEpc import RetrieveFindMyEpc
from tqdm import tqdm

View file

@ -3,7 +3,6 @@ from pydantic_settings import BaseSettings
from typing import Optional
class Settings(BaseSettings):
API_KEY: str
API_KEY_NAME: str = "X-API-KEY"
@ -43,7 +42,8 @@ class Settings(BaseSettings):
AWS_DEFAULT_REGION: Optional[str] = None
class Config:
env_file = "backend.env"
env_file = "backend/.env"
@lru_cache()
def get_settings():

View file

@ -14,6 +14,7 @@ db_string = connection_string.format(
db_engine = create_engine(db_string, pool_size=5, max_overflow=5)
def get_db_session():
if db_engine is None:
raise RuntimeError("Database is not configured. Set DATABASE_URL in environment variables.")

View file

@ -64,7 +64,7 @@ def extract_property_request_data(
x for x in already_installed if
(x["address"] == config["address"]) and (x["postcode"] == config["postcode"])
), [])
# Because we have some non-invasive recommendations that match on address and postcode, but not UPRN
# we need to check existence of uprn
has_uprn = "uprn" in non_invasive_recommendations[0] if non_invasive_recommendations else False

View file

@ -392,6 +392,26 @@ def parse_heating_system(config):
return None
def check_duplicate_uprns(plan_input):
"""
Simple function to check if the input data contains duplicated UPRNS.
If there are duplicates, an exception will be rasied
:return:
"""
# Check for duplicate UPRNS
input_uprns = [x.get("uprn") for x in plan_input if "uprn" in x and x.get("uprn")]
if input_uprns:
# Check for dupes
if len(input_uprns) != len(set(input_uprns)):
# Find the duplicate UPRNs
duplicates = set([x for x in input_uprns if input_uprns.count(x) > 1])
# de-dupe input_uprns
raise ValueError(f"Duplicate UPRNs in the input data: {duplicates}")
return True
async def model_engine(body: PlanTriggerRequest):
logger.info("Model Engine triggered with body: %s", json.loads(body.model_dump_json()))
@ -480,16 +500,8 @@ async def model_engine(body: PlanTriggerRequest):
if body.index_start is not None and body.index_end is not None:
plan_input = plan_input[body.index_start:body.index_end]
# Check for duplicate UPRNS
input_uprns = [x.get("uprn") for x in plan_input if "uprn" in x and x.get("uprn")]
if input_uprns:
# Check for dupes
if len(input_uprns) != len(set(input_uprns)):
# Find the duplicate UPRNs
duplicates = set([x for x in input_uprns if input_uprns.count(x) > 1])
# de-dupe input_uprns
raise ValueError(f"Duplicate UPRNs in the input data: {duplicates}")
# Confirm no duplicate UPRNS
check_duplicate_uprns(plan_input)
# If we have patches or overrides, we should read them in here
patches, already_installed, non_invasive_recommendations, valuation_data = get_request_property_data(body)
@ -528,9 +540,7 @@ async def model_engine(body: PlanTriggerRequest):
if (body.event_type == "remote_assessment") and config.get("property_type") == "Flat":
# We're running a remote assessment for a flat - we go and grab the associated
# UPRNS for other units in the same building
associated_uprns = get_associated_uprns(
session, postcode=config["postcode"], uprn=uprn
)
associated_uprns = get_associated_uprns(session, postcode=config["postcode"], uprn=uprn)
epc_searcher = SearchEpc(
address1=address1,
@ -1140,6 +1150,7 @@ async def model_engine(body: PlanTriggerRequest):
)
property_value_increase_ranges[p.id] = valuations
# TODO - this is not right, especially if the existing run failed
if p.is_new:
property_details_epc = p.get_property_details_epc(
portfolio_id=body.portfolio_id, rating_lookup=rating_lookup,

View file

@ -77,6 +77,14 @@ archetypes = sustainability_data[
"Floor Area Band"]
].drop_duplicates()
# Potential reductions:
# 1) Split roof insulation into > 100mm loft and <= 100mm loft
# 2) Group all of the glazed together (e.g. double glazed, secondary glazed, triple glazed)
# 3) Group up boiler efficiency A-C, D - F, G? or someting like this
# 4) Group up main fuel into gas, electric, oil, other?
# 5) Wall Construction - group up Sandstone and Granite into one category
# 6) Reduce or remove floor construction
# Maps the property types to the format recognised by the EPC api
property_type_map = {}
# Maps the build form to the format recognised by the OS api

View file

@ -398,6 +398,7 @@ class RetrieveFindMyEpc:
extracted_address_cleaned = (
extracted_address.replace(",", "").replace(" ", "").lower()
)
if not extracted_address_cleaned.startswith(self.address_cleaned):
continue