refactoring backend to incorporate model_data parts

This commit is contained in:
Khalim Conn-Kowlessar 2023-07-19 09:45:23 +01:00
parent 7a091842c9
commit 8c609d282a
9 changed files with 63 additions and 33 deletions

1
.dockerignore Normal file
View file

@ -0,0 +1 @@
model_data/local_data/*

View file

@ -5,19 +5,22 @@ FROM python:3.10.12-slim-buster
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /app
# Set work directory to the root of your project
WORKDIR /Model
# Install system dependencies
RUN apt-get update && apt-get install -y netcat-openbsd
# Install python dependencies
COPY ./requirements/base.txt ./requirements/base.txt
COPY ./backend/requirements/base.txt ./backend/requirements/base.txt
COPY ./model_data/requirements/requirements.txt ./model_data/requirements/requirements.txt
RUN pip install --upgrade pip
RUN pip install -r requirements/base.txt
RUN pip install -r backend/requirements/base.txt
RUN pip install -r model_data/requirements/requirements.txt
# Copy project
COPY . .
COPY ./backend ./backend
COPY ./model_data ./model_data
# command to run on container start
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
CMD ["uvicorn", "backend.app.main:app", "--host", "0.0.0.0", "--port", "8000"]

View file

@ -1,6 +1,7 @@
anyio==3.7.1
cffi==1.15.1
click==8.1.3
cryptography==37.0.4
ecdsa==0.18.0
exceptiongroup==1.1.2
fastapi==0.99.1
@ -15,4 +16,13 @@ PyJWT==2.7.0
python-dotenv==1.0.0
python-jose==3.3.0
PyYAML==6.0
cryptography==37.0.4
rsa==4.9
six==1.16.0
sniffio==1.3.0
starlette==0.27.0
typing_extensions==4.7.1
uvicorn==0.22.0
uvloop==0.17.0
watchfiles==0.19.0
websockets==11.0.3
boto3

View file

@ -1,4 +1,4 @@
import pandas as pd
from enum import Enum
import geopandas as gpd
from shapely.geometry import Point
from model_data.utils import setup_logger
@ -39,6 +39,31 @@ class ConservationAreaClient:
self.gov_data = gpd.read_file(self.gov_path)
self.gov_data = self.gov_data.drop(columns=["dataset"])
def is_in_conservation_area(self, coordinates: dict):
if not coordinates:
raise ValueError("Coordinates have not been set, run get_coordinates() first")
is_in_conservation_area = self.is_in_conservation_area_historic_england(
x_bng=coordinates["x_coordinate"],
y_bng=coordinates["y_coordinate"]
)
if is_in_conservation_area != "unknown":
return is_in_conservation_area
if is_in_conservation_area == "unknown":
# We double check the secondary data source
backup = self.is_in_conservation_area_historic_gov(
longitude=coordinates["longitude"],
latitude=coordinates["latitude"]
)
if backup:
return ConservationAreaClient.IN_CONSERVATION_AREA
else:
return ConservationAreaClient.UNKNOWN
def is_in_conservation_area_historic_england(self, x_bng: float, y_bng: float) -> str:
"""
Check if a property is in a conservation area
@ -103,3 +128,9 @@ class ConservationAreaClient:
distance_meters = distances.min()
return distance_meters
class InConservationArea(Enum):
IN_CONSERVATION_AREA = ConservationAreaClient.IN_CONSERVATION_AREA
NOT_IN_CONSERVATION_AREA = ConservationAreaClient.NOT_IN_CONSERVATION_AREA
UNKNOWN = ConservationAreaClient.UNKNOWN

View file

@ -5,7 +5,6 @@ from model_data.config import EPC_AUTH_TOKEN
from model_data.OpenUprnClient import OpenUprnClient
from model_data.EpcClean import EpcClean
from model_data.BaseUtility import BaseUtility
from model_data.ConservationAreaClient import ConservationAreaClient
class Property(BaseUtility):
@ -117,28 +116,12 @@ class Property(BaseUtility):
raise ValueError("Either No attributes or multiple found for %s" % description)
setattr(self, self.ATTRIBUTE_MAP[description], attributes[0])
def set_is_in_conservation_area(self, conservation_area_client: ConservationAreaClient):
if not self.coordinates:
raise ValueError("Coordinates have not been set, run get_coordinates() first")
is_in_conservation_area = conservation_area_client.is_in_conservation_area_historic_england(
x_bng=self.coordinates["x_coordinate"],
y_bng=self.coordinates["y_coordinate"]
)
self.in_conservation_area = is_in_conservation_area
if is_in_conservation_area == "unknown":
# We double check the secondary data source
backup = conservation_area_client.is_in_conservation_area_historic_gov(
longitude=self.coordinates["longitude"],
latitude=self.coordinates["latitude"]
)
if backup:
self.in_conservation_area = ConservationAreaClient.IN_CONSERVATION_AREA
else:
self.in_conservation_area = ConservationAreaClient.UNKNOWN
def set_is_in_conservation_area(self, in_conservation_area):
"""
Sets whether the property is in a conservation area given the output of the ConservationAreaClient
:param in_conservation_area: string value, indicating whether the property is in a conservation area
"""
self.in_conservation_area = in_conservation_area
def set_year_built(self):
"""

View file

@ -67,7 +67,8 @@ def handler():
# Check if the property is in a conversation area
for p in input_properties:
p.set_is_in_conservation_area(conservation_area_client)
in_conservation_area = conservation_area_client.is_in_conservation_area(p.coordinates)
p.set_is_in_conservation_area(in_conservation_area)
local_authorities = {p.data['local-authority'] for p in input_properties}
# TODO: Do this at a constituency level

View file

@ -3,3 +3,4 @@ pytest
mock
pytest-cov
pytest-mock
pip-check-reqs

View file

@ -10,7 +10,6 @@ python-Levenshtein
dbfread
pyproj
pint
geopandas
mip
seaborn
statsmodels

View file

@ -0,0 +1 @@
geopandas