parse to strongly typed dict. will map to excel row later

This commit is contained in:
Daniel Roth 2026-04-14 16:37:49 +00:00
parent 9ccbfc2d11
commit 648fff29af
2 changed files with 54 additions and 17 deletions

View file

@ -49,7 +49,7 @@ SAMPLE_XML = """<RdSAP-Report xmlns="https://epbr.digital.communities.gov.uk/xsd
"""
def test_parse_rdsap_wide_flat_contract():
def test_parse_rdsap_contract():
# arrange + act
result = parse_rdsap(SAMPLE_XML)
@ -57,18 +57,28 @@ def test_parse_rdsap_wide_flat_contract():
assert result == {
"address": "1, Fake Avenue, Random, AB24 5CD",
"property_type": "House",
# Main Dwelling - floor 0
"main_dwelling_floor_index_0_area_m2": 43.61,
"main_dwelling_floor_index_0_height_m": 2.46,
"main_dwelling_floor_index_0_heat_loss_perimeter_m": 25.31,
"main_dwelling_floor_index_0_party_wall_length_m": 0.0,
# Main Dwelling - floor 1
"main_dwelling_floor_index_1_area_m2": 42.33,
"main_dwelling_floor_index_1_height_m": 2.44,
"main_dwelling_floor_index_1_heat_loss_perimeter_m": 26.16,
"main_dwelling_floor_index_1_party_wall_length_m": 0.0,
# Roof (building-level, repeated across floors or stored once)
"main_dwelling_roof_construction": "4",
"main_dwelling_roof_insulation_location": "2",
"main_dwelling_roof_insulation_thickness": "100mm",
"building_parts": [
{
"identifier": "Main Dwelling",
"floors": [
{
"area_m2": 43.61,
"height_m": 2.46,
"heat_loss_perimeter_m": 25.31,
"party_wall_length_m": 0.0,
},
{
"area_m2": 42.33,
"height_m": 2.44,
"heat_loss_perimeter_m": 26.16,
"party_wall_length_m": 0.0,
},
],
"roof": {
"construction": 4,
"insulation_location": 2,
"insulation_thickness_mm": 100.0,
},
}
],
}

View file

@ -1,8 +1,35 @@
from typing import Any
from typing import Any, List, Optional, TypedDict
from etl.xml_survey_extraction.XmlParser import PROPERTY_TYPE_LOOKUP
class Floor(TypedDict):
area_m2: float
height_m: float
heat_loss_perimeter_m: float
party_wall_length_m: float
class Roof(TypedDict, total=False):
construction: int # TODO: map to str
insulation_location: int # TODO: map to str
insulation_thickness_mm: float
class BuildingPart(TypedDict):
identifier: str # e.g. "Main Dwelling", "Extension"
floors: List[Floor]
roof: Optional[Roof]
class SapPropertyDetails(TypedDict):
address: str
property_type: str
building_parts: List[BuildingPart]
# This file should ultimately live somewhere different, probably
def parse_rdsap(xml_string: str) -> Any: # TODO: define shape of return object
def parse_rdsap(
xml_string: str,
) -> SapPropertyDetails:
raise NotImplementedError