def is_identifier(value: str) -> str: if not _IDENTIFIER_REGEXP.fullmatch(value): raise errors.PropertyConstraintViolationError( "Input is not a valid identifier", pattern=_IDENTIFIER_REGEXP.pattern, ) return value
def max_length(length: int, value: typing.Any) -> typing.Any: """Validates that an input doesn't exceed a given length.""" actual_length = len(value) if actual_length > length: raise errors.PropertyConstraintViolationError( "Input is too long", max_length=length, actual_length=actual_length, ) return value
def from_json(self, json_value): try: enum_instance = self.enum_class(json_value) except ValueError as exc: raise errors.PropertyConstraintViolationError( f"Input '{json_value}' is not a valid entry of enum {self.enum_class.__name__}", value=json_value, enum_class=self.enum_class, ) from exc else: return enum_instance
def from_json(self, json_value: str) -> datetime.datetime: try: dt = dateutil.parser.isoparse(json_value) except (ValueError, OverflowError) as exc: raise errors.PropertyConstraintViolationError( f"Date input isn't formatted appropriately", value=json_value, ) from exc else: # Assume naive datetime are UTC, so that we don't reject charge points who expect to speak UTC by default if not dt.tzinfo: dt = dt.replace(tzinfo=pytz.UTC) if dt.tzinfo.tzname( dt ) != 'UTC': # type: ignore # mypy doesn't catch that dt.replace call sets tzinfo raise errors.PropertyConstraintViolationError( f"Date input must use the UTC timezone, not '{dt.tzinfo}'", value=dt, ) return dt
def to_json(self, value: datetime.datetime) -> str: if not isinstance(value, datetime.datetime): raise errors.TypeConstraintViolationError( f"Input '{value}' is not a datetime.datetime instance", value=value, ) if not value.tzinfo or value.tzinfo.tzname(value) != 'UTC': raise errors.PropertyConstraintViolationError( f"Date input must use the UTC timezone, not '{value.tzinfo}'", value=value, ) return value.isoformat()
def is_not_zero(value: typing.Union[int, float]) -> typing.Union[int, float]: if value == 0: raise errors.PropertyConstraintViolationError("Input is zero") return value
def is_positive(value: typing.Union[int, float]) -> typing.Union[int, float]: if value < 0: raise errors.PropertyConstraintViolationError("Input is negative") return value
def decimal_validator(precision: int, value: float) -> float: components = str(value).split('.') if len(components[-1]) > precision: raise errors.PropertyConstraintViolationError( "Decimal value precision is too big", precision=precision) return value