Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate project location string in model_validator #1534

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/backend/app/db/postgis_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,9 @@ def get_address_from_lat_lon(latitude, longitude):
}
headers = {"Accept-Language": "en"} # Set the language to English

log.debug("Getting Nominatim address from project centroid")
log.debug(
f"Getting Nominatim address from project lat ({latitude}) lon ({longitude})"
)
response = requests.get(base_url, params=params, headers=headers)
if (status_code := response.status_code) != 200:
log.error(f"Getting address string failed: {status_code}")
Expand Down
35 changes: 22 additions & 13 deletions src/backend/app/projects/project_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ class ProjectIn(BaseModel):
task_num_buildings: Optional[int] = None
data_extract_type: Optional[str] = None
outline_geojson: Union[FeatureCollection, Feature, Polygon]
# city: str
# country: str
location_str: Optional[str] = None

@computed_field
@property
Expand All @@ -170,17 +169,6 @@ def centroid(self) -> Optional[Any]:
return None
return write_wkb(read_wkb(self.outline).centroid)

@computed_field
@property
def location_str(self) -> Optional[str]:
"""Compute geocoded location string from centroid."""
if not self.centroid:
return None
geom = read_wkb(self.centroid)
latitude, longitude = geom.y, geom.x
address = get_address_from_lat_lon(latitude, longitude)
return address if address is not None else ""

@computed_field
@property
def project_name_prefix(self) -> str:
Expand All @@ -201,6 +189,27 @@ def prepend_hash_to_tags(cls, hashtags: List[str]) -> Optional[List[str]]:

return hashtags_with_hash

@model_validator(mode="after")
def generate_location_str(self) -> Self:
"""Generate location string after centroid is generated.

NOTE chaining computed_field didn't seem to work here so a
model_validator was used for final stage validation.
"""
if not self.centroid:
log.warning("Project has no centroid, location string not determined")
return self

if self.location_str is not None:
# Prevent running triggering multiple times if already set
return self

geom = read_wkb(self.centroid)
latitude, longitude = geom.y, geom.x
address = get_address_from_lat_lon(latitude, longitude)
self.location_str = address if address is not None else ""
return self


class ProjectUpload(ProjectIn, ODKCentralIn):
"""Project upload details, plus ODK credentials."""
Expand Down
Loading