Source code for domprob.sensors.validate.orch

from __future__ import annotations

from typing import TYPE_CHECKING

from domprob.sensors.validate.base_val import BaseValidator
from domprob.sensors.validate.chain import ValidationChain
from domprob.sensors.validate.vals import (
    InstrumentParamExistsValidator,
    InstrumentTypeValidator,
    SupportedInstrumentsExistValidator,
)

if TYPE_CHECKING:
    from domprob.sensors.meth import (  # pragma: no cover
        BoundSensorMethod,
    )


[docs] class SensorValidationOrchestrator: # pylint: disable=line-too-long """Orchestrates validation of `BoundSensorMethod` instances using a chain of validators. The orchestrator is initialised with a `ValidationChain`, which can either be customised or use the default set of validators. Validators are applied sequentially to ensure that the `BoundSensorMethod` adheres to defined rules and constraints. Attributes: DEFAULT_VALIDATORS (tuple[type[BaseValidator], ...]): A tuple of default validator classes used to initialise the chain. _chain (ValidationChain): The validate chain that manages the sequence of validators. Args: chain (ValidationChain | None, optional): A custom validate chain. If not provided, a default chain is created with `DEFAULT_VALIDATORS`. Examples: >>> from domprob.sensors.validate.orch import SensorValidationOrchestrator >>> from domprob.sensors.meth import SensorMethod >>> >>> class SomeInstrument: ... pass ... >>> class Example: ... def method(self, instrument: SomeInstrument) -> None: ... pass ... >>> method = SensorMethod(Example.method) >>> method.supp_instrums.record(SomeInstrument, required=True) Instruments(metadata=SensorMetadata(method=<function Example.method at 0x...>)) >>> >>> bound_method = method.bind(Example(), SomeInstrument()) >>> >>> orchestrator = SensorValidationOrchestrator() >>> orchestrator.validate(bound_method) """ DEFAULT_VALIDATORS: tuple[type[BaseValidator], ...] = ( SupportedInstrumentsExistValidator, InstrumentParamExistsValidator, InstrumentTypeValidator, ) def __init__(self, chain: ValidationChain | None = None): self._chain = chain or ValidationChain(BaseValidator) self.register(*self.DEFAULT_VALIDATORS)
[docs] def register( self, *validators: type[BaseValidator] ) -> SensorValidationOrchestrator: # pylint: disable=line-too-long """Registers additional validators to the validate chain. Validators are appended to the existing chain, and their instances are created dynamically. Args: *validators (type[BaseValidator]): Validator classes to be added to the chain. Examples: >>> from domprob.sensors.validate.orch import SensorValidationOrchestrator >>> from domprob.sensors.validate.vals import InstrumentTypeValidator >>> >>> orchestrator = SensorValidationOrchestrator() >>> orchestrator.register(InstrumentTypeValidator) SensorValidationOrchestrator(ValidationChain(base='BaseValidator')) """ self._chain.extend((v() for v in validators)) return self
[docs] def validate(self, method: BoundSensorMethod): # pylint: disable=line-too-long """Executes the validate chain on a `BoundSensorMethod` instance. This method ensures that all registered validators are applied sequentially to the method. Args: method (BoundSensorMethod): The method instance to validate. Raises: ValidatorException: If any of the validators in the chain fails. Examples: >>> from domprob.sensors.validate.orch import SensorValidationOrchestrator >>> from domprob.sensors.meth import SensorMethod >>> >>> class SomeInstrument: ... pass ... >>> class Example: ... def method(self, instrument: SomeInstrument) -> None: ... pass ... >>> meth = SensorMethod(Example.method) >>> bound_meth = meth.bind(Example(), SomeInstrument()) >>> bound_meth.supp_instrums.record(SomeInstrument, required=True) Instruments(metadata=SensorMetadata(method=<function Example.method at 0x...>)) >>> >>> orchestrator = SensorValidationOrchestrator() >>> orchestrator.validate(bound_meth) """ self._chain.validate_chain(method)
[docs] def __repr__(self) -> str: """Returns a string representation of the orchestrator. The representation includes the class name and the associated validate chain. Returns: str: A string representation of the orchestrator. Examples: >>> orchestrator = SensorValidationOrchestrator() >>> repr(orchestrator) "SensorValidationOrchestrator(ValidationChain(base='BaseValidator'))" """ return f"{self.__class__.__name__}({self._chain!r})"