Skip to content

Commit

Permalink
Add request model for custom input data
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasschaub committed Feb 3, 2022
1 parent 111e7e0 commit c8bdc53
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 22 deletions.
3 changes: 2 additions & 1 deletion workers/ohsome_quality_analyst/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
INDICATOR_EXAMPLES,
REPORT_EXAMPLES,
IndicatorBpolys,
IndicatorData,
IndicatorDatabase,
ReportBpolys,
ReportDatabase,
Expand Down Expand Up @@ -130,7 +131,7 @@ async def get_indicator(parameters=Depends(IndicatorDatabase)):

@app.post("/indicator")
async def post_indicator(
parameters: Union[IndicatorBpolys, IndicatorDatabase] = Body(
parameters: Union[IndicatorBpolys, IndicatorDatabase, IndicatorData] = Body(
...,
examples=INDICATOR_EXAMPLES,
)
Expand Down
71 changes: 52 additions & 19 deletions workers/ohsome_quality_analyst/api/request_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from geojson import Feature, FeatureCollection
from pydantic import BaseModel

from ohsome_quality_analyst.base.layer import LayerData
from ohsome_quality_analyst.utils.definitions import (
INDICATOR_LAYER,
get_dataset_names_api,
Expand All @@ -35,25 +36,8 @@ class BaseIndicator(BaseModel):
name: IndicatorEnum = pydantic.Field(
..., title="Indicator Name", example="GhsPopComparisonBuildings"
)
layer_name: LayerEnum = pydantic.Field(
..., title="Layer Name", example="building_count"
)
include_svg: bool = False

@pydantic.root_validator
@classmethod
def validate_indicator_layer(cls, values):
try:
indicator_layer = (values["name"].value, values["layer_name"].value)
except KeyError:
raise ValueError("An issue with the layer or indicator name occurred.")
if indicator_layer not in INDICATOR_LAYER:
raise ValueError(
"Indicator layer combination is invalid: " + str(indicator_layer)
)
else:
return values

class Config:
"""Pydantic config class."""

Expand All @@ -74,6 +58,28 @@ class Config:
extra = "forbid"


class BaseLayerName(BaseModel):
"""Model for the `layer_name` parameter."""

layer_name: LayerEnum = pydantic.Field(
..., title="Layer Name", example="building_count"
)

@pydantic.root_validator
@classmethod
def validate_indicator_layer(cls, values):
try:
indicator_layer = (values["name"].value, values["layer_name"].value)
except KeyError:
raise ValueError("An issue with the layer or indicator name occurred.")
if indicator_layer not in INDICATOR_LAYER:
raise ValueError(
"Indicator layer combination is invalid: " + str(indicator_layer)
)
else:
return values


class BaseBpolys(BaseModel):
"""Model for the `bpolys` parameter."""

Expand Down Expand Up @@ -116,11 +122,24 @@ class BaseDatabase(BaseModel):
fid_field: Optional[FidFieldEnum]


class IndicatorBpolys(BaseIndicator, BaseBpolys):
class BaseLayerData(BaseModel):
"""Model for the parameter `layer`.
The parameter contains layer name, description and data.
"""

layer: LayerData


class IndicatorBpolys(BaseIndicator, BaseLayerName, BaseBpolys):
pass


class IndicatorDatabase(BaseIndicator, BaseDatabase):
class IndicatorDatabase(BaseIndicator, BaseLayerName, BaseDatabase):
pass


class IndicatorData(BaseIndicator, BaseLayerData, BaseBpolys):
pass


Expand Down Expand Up @@ -176,6 +195,20 @@ class ReportDatabase(BaseReport, BaseDatabase):
"feature_id": 3,
},
},
"Custom AOI and custom Layer": {
"summary": (
"Request an Indicator for a custom AOI (`bpolys`) and a custom Layer "
"(`layer`)."
),
"description": (
"The Layer must have a name and description. The data associated with this "
"Layer must be provided as well. "
),
"value": {
"name": "GhsPopComparisonBuildings",
"layer": {"name": "Building Count", "description": "", "data": {}},
},
},
}

REPORT_EXAMPLES = {
Expand Down
8 changes: 6 additions & 2 deletions workers/tests/unittests/test_api_request_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,20 @@ def test_dataset_invalid(self):
request_models.BaseDatabase(dataset="foo", feature_id="3")

def test_valid_layer(self):
request_models.BaseIndicator(
request_models.IndicatorDatabase(
name="GhsPopComparisonBuildings",
layerName="building_count",
dataset="regions",
featureId=3,
)

def test_invalid_layer(self):
with self.assertRaises(ValueError):
request_models.BaseIndicator(
request_models.IndicatorDatabase(
name="GhsPopComparisonBuildings",
layerName="foo",
dataset="regions",
featureId=3,
)

def test_invalid_indicator_layer_combination(self):
Expand Down

0 comments on commit c8bdc53

Please sign in to comment.