Describe the bug
Currently, the Datatype check does not allow good inheritance of ContextAttribute, e.g. to define special scenario specific custom models.
Also support for geo:json ist currently missing.
https://fiware-orion.readthedocs.io/en/master/orion-api.html#geospatial-properties-of-entities
To Reproduce
Steps to reproduce the behavior:
- Create a child class of ContextAttribute and Overwrite the Vlaue type with a PydanticModel
- Create a instance of this model
- Try to serialize as json
Expected behavior
To have more convenience it would be nice to allow the definition of Pydantic Models.
Furthermore, currently the DataType validation removes all Pydantic functionality from submodels but Units.
Originally, this was intended to insure compatibility for the standard JSON library that do not define the specific type.
Hovever, the later issue could be simply omitted by standard serialikzing if type is unknown.
Solution (adds support for geojson)
class BaseValueAttribute(BaseModel):
"""
Model to add the value property to an BaseAttribute Model. The Model
is represented by a JSON object with the following syntax:
The attribute value is specified by the value property, whose value may
be any JSON datatype.
"""
type: Union[DataType, str] = Field(
default=DataType.TEXT,
description="The attribute type represents the NGSI value type of the "
"attribute value. Note that FIWARE NGSI has its own type "
"system for attribute values, so NGSI value types are not "
"the same as JSON types. Allowed characters "
"are the ones in the plain ASCII set, except the following "
"ones: control characters, whitespace, &, ?, / and #.",
max_length=256,
min_length=1,
regex=FiwareRegex.string_protect.value, # Make it FIWARE-Safe
)
value: Optional[Any] = Field(
default=None,
title="Attribute value",
description="the actual data"
)
@validator('value')
def validate_value_type(cls, value, values):
"""
Validator for field 'value'
The validator will try autocast the value based on the given type.
If `DataType.STRUCTUREDVALUE` is used for type it will also serialize
pydantic models. With latter operation all additional features of the
original pydantic model will be dumped.
If the type is unknown it will check json-serializable.
"""
type_ = values['type']
validate_escape_character_free(value)
if value is not None:
if type_ == DataType.TEXT:
if isinstance(value, list):
return [str(item) for item in value]
return str(value)
if type_ == DataType.BOOLEAN:
if isinstance(value, list):
return [bool(item) for item in value]
return bool(value)
if type_ in (DataType.NUMBER, DataType.FLOAT):
if isinstance(value, list):
return [float(item) for item in value]
return float(value)
if type_ == DataType.INTEGER:
if isinstance(value, list):
return [int(item) for item in value]
return int(value)
if type_ == DataType.DATETIME:
return value
if type_ == DataType.ARRAY:
if isinstance(value, list):
return value
raise TypeError(f"{type(value)} does not match "
f"{DataType.ARRAY}")
if type_ == DataType.STRUCTUREDVALUE:
if isinstance(value, dict):
value = json.dumps(value)
return json.loads(value)
elif isinstance(value, BaseModel):
value.json()
return value
raise TypeError(
f"{type(value)} does not match " f"{DataType.STRUCTUREDVALUE}"
)
if isinstance(value, BaseModel):
value.json()
return value
value = json.dumps(value)
return json.loads(value)
custom_attribute.py
from pydantic_geojson import (
PointModel,
MultiPointModel,
LineStringModel,
MultiLineStringModel,
PolygonModel,
MultiPolygonModel,
FeatureModel,
FeatureCollectionModel,
)
class GeoJsonAttribute(ContextAttribute):
"""
https://fiware-orion.readthedocs.io/en/master/orion-api.html#geospatial-properties-of-entities
"""
type: str = Field(default="geo:json", const=True)
value: Union[
PointModel,
MultiPointModel,
LineStringModel,
MultiLineStringModel,
PolygonModel,
MultiPolygonModel,
FeatureModel,
FeatureCollectionModel,
]
main.py
if __name__ == "__main__":
point = PointModel(coordinates=[0, 0])
print(point.json(indent=2))
location_attribute = GeoJsonAttribute(value={"type": "Point", "coordinates": [0, 0]})
print(location_attribute.value.json(indent=2))
Describe the bug
Currently, the Datatype check does not allow good inheritance of ContextAttribute, e.g. to define special scenario specific custom models.
Also support for geo:json ist currently missing.
https://fiware-orion.readthedocs.io/en/master/orion-api.html#geospatial-properties-of-entities
To Reproduce
Steps to reproduce the behavior:
Expected behavior
To have more convenience it would be nice to allow the definition of Pydantic Models.
Furthermore, currently the DataType validation removes all Pydantic functionality from submodels but Units.
Originally, this was intended to insure compatibility for the standard JSON library that do not define the specific type.
Hovever, the later issue could be simply omitted by standard serialikzing if type is unknown.
Solution (adds support for geojson)
custom_attribute.py
main.py