Source code for geoh5py.ui_json.parameters
# Copyright (c) 2024 Mira Geoscience Ltd.
#
# This file is part of geoh5py.
#
# geoh5py is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# geoh5py is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with geoh5py. If not, see <https://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import Any
from uuid import UUID
from geoh5py import Workspace
from geoh5py.groups import PropertyGroup
from geoh5py.shared.utils import SetDict
from geoh5py.ui_json.enforcers import EnforcerPool
Validation = dict[str, Any]
[docs]
class Parameter:
"""
Basic parameter to store key/value data with validation capabilities.
:param name: Parameter name.
:param value: The parameters value.
:param enforcers: A collection of enforcers.
"""
static_validations: dict[str, Any] = {}
def __init__(self, name: str, value: Any = None):
self.name: str = name
self._value: Any | None = None
self._enforcers: EnforcerPool = EnforcerPool.from_validations(
self.name, self.validations
)
if value is not None:
self.value = value
@property
def validations(self):
"""Returns a dictionary of static validations."""
return SetDict(**self.static_validations)
@property
def value(self):
return self._value
@value.setter
def value(self, val):
self._value = val
self.validate()
[docs]
def validate(self):
"""Validates data against the pool of enforcers."""
self._enforcers.enforce(self.value)
def __str__(self):
return f"<{type(self).__name__}> : '{self.name}' -> {self.value}"
[docs]
class DynamicallyRestrictedParameter(Parameter):
"""Parameter whose validations are set at runtime."""
def __init__(
self, name: str, restrictions: Any, enforcer_type="type", value: Any = None
):
self._restrictions = restrictions
self._enforcer_type = enforcer_type
super().__init__(name, value)
@property
def restrictions(self):
if not isinstance(self._restrictions, list):
self._restrictions = {self._restrictions}
return self._restrictions
@property
def validations(self):
return SetDict(**{self._enforcer_type: self.restrictions})
[docs]
class ValueRestrictedParameter(DynamicallyRestrictedParameter):
"""Parameter with a restricted set of values."""
def __init__(self, name: str, restrictions: Any, value: Any = None):
super().__init__(name, restrictions, "value", value)
[docs]
class TypeRestrictedParameter(DynamicallyRestrictedParameter):
"""Parameter with a restricted set of types known at runtime only."""
def __init__(self, name: str, restrictions: list[Any], value: Any = None):
super().__init__(name, restrictions, "type", value)
[docs]
class TypeUIDRestrictedParameter(DynamicallyRestrictedParameter):
"""Parameter with a restricted set of type uids known at runtime only."""
def __init__(self, name: str, restrictions: list[UUID], value: Any = None):
super().__init__(name, restrictions, "type_uid", value)
[docs]
class StringParameter(Parameter):
"""Parameter for string values."""
static_validations = {"type": str}
[docs]
class IntegerParameter(Parameter):
"""Parameter for integer values."""
static_validations = {"type": int}
[docs]
class FloatParameter(Parameter):
"""Parameter for float values."""
static_validations = {"type": float}
[docs]
class NumericParameter(Parameter):
"""Parameter for generic numeric values."""
static_validations = {"type": [int, float]}
[docs]
class BoolParameter(Parameter):
"""Parameter for boolean values."""
static_validations = {"type": bool}
def __init__(self, name: str, value: bool = False):
super().__init__(name, value)
[docs]
class StringListParameter(Parameter):
"""Parameter for list of strings."""
static_validations = {"type": [list, str]}
# TODO: introduce type alias handling so that TypeEnforcer(list[str], str)
# is possible
[docs]
class WorkspaceParameter(Parameter):
"""Parameter for workspace objects."""
static_validations = {"type": Workspace}
[docs]
class PropertyGroupParameter(Parameter):
"""Parameter for property group objects."""
static_validations = {"type": PropertyGroup}