Source code for data_formats.response_format

"""
Provides functionality for handling the response format.

Examples:

    If you want to validate a dictionary against the response format::

    >>> from data_formats import response_format
    >>> example = {}
    >>> response_format.validate(example)
    Traceback (most recent call last):
        ...
    data_formats.response_format.ResponseValidationError
"""
from typing import Dict, Any, Union

import jsonschema

from energy_hub.param_var import ConstantOrVar
from pylp import Variable, Status

SCHEMA = {
    'type': 'object',
    'properties': {
        'version': {
            'description': 'The SemVer version number for the format',
            'type': 'string',
            'enum': ['0.1.0'],
        },
        'solution': {
            'type': 'object',
        },
        'solver': {
            'type': 'object',
            'properties': {
                'termination_condition': {
                    'type': 'string',
                },
                'time': {
                    'type': 'number',
                    'minimum': 0,
                },
            },
            'required': ['termination_condition', 'time'],
            'additionalProperties': False,
        },
    },
    'required': ['version', 'solution', 'solver'],
    'additionalProperties': False,
}


[docs] class ResponseValidationError(Exception): """The instance failed to validate against the SCHEMA."""
def _is_valid_json_type(json: Any) -> bool: if json is None: return True return any(isinstance(json, t) for t in [str, float, int, dict, list]) def _is_valid(mapping: Union[dict, list, str, float, int]) -> bool: if isinstance(mapping, list): return all(_is_valid(x) for x in mapping) elif isinstance(mapping, dict): return all(_is_valid(key) and _is_valid(value) for key, value in mapping.items()) return _is_valid_json_type(mapping)
[docs] def validate(instance: dict) -> None: """ Validate the instance against the schema. Args: instance: The potential instance of the schema Raises: ValidationError: the instance does not match the schema """ if not _is_valid(instance): raise ResponseValidationError try: jsonschema.validate(instance, SCHEMA) except jsonschema.ValidationError as exc: raise ResponseValidationError from exc
def _get_value(value: Any) -> Any: if isinstance(value, Variable): return value.evaluate() elif isinstance(value, range): return list(value) elif isinstance(value, ConstantOrVar): return _get_value(value.values) elif isinstance(value, dict): return {key: _get_value(value) for key, value in value.items()} return value def _get_stuff(model: Dict) -> Dict[str, Any]: return {name: _get_value(value) for name, value in model.items()}
[docs] def create_response(status: Status, model: Dict) -> Dict[str, Any]: """ Create a new response format dictionary. Args: status: The status of the problem model: A dictionary of the variables and their values that were used in the model """ result = { 'version': '0.1.0', 'solver': { 'termination_condition': status.status, 'time': status.time, }, 'solution': _get_stuff(model), } validate(result) return result