From 0df82ed00ff9b84b2b61235e6745da353e7383fd Mon Sep 17 00:00:00 2001 From: Luke Carr Date: Mon, 16 Dec 2024 16:24:58 +0000 Subject: [PATCH] feat: added ISO 8601 validation for `MeasurementType.duration` field --- src/edr_pydantic/parameter.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/edr_pydantic/parameter.py b/src/edr_pydantic/parameter.py index 8102c59..c23ef42 100644 --- a/src/edr_pydantic/parameter.py +++ b/src/edr_pydantic/parameter.py @@ -1,21 +1,44 @@ +from datetime import timedelta +from typing import Annotated from typing import Dict from typing import List from typing import Literal from typing import Optional +from pydantic import AfterValidator from pydantic import model_validator from pydantic import RootModel +from pydantic import TypeAdapter from .base_model import EdrBaseModel from .extent import Extent from .observed_property import ObservedProperty from .unit import Unit +duration_adapter = TypeAdapter(timedelta) + + +def check_iso8601_duration(value: str) -> str: + if "/" in value: + parts = value.split("/") + + if len(parts) != 2: + raise ValueError("Duration must have two parts if it contains a '/'") + + duration_adapter.validate_python(parts[0]) + duration_adapter.validate_python(parts[1]) + else: + duration_adapter.validate_python(value) + + return value + + +ISO8601Duration = Annotated[str, AfterValidator(check_iso8601_duration)] + class MeasurementType(EdrBaseModel): method: str - # TODO: Add validation of ISO 8601 duration (including leading minus sign) - duration: str + duration: ISO8601Duration class Parameter(EdrBaseModel, extra="allow"):