"""This class contains methods related to service management. It contains all type of services proposed in theFunctional View of RAMI 4.0."""importinspectimportloggingimporttypes_logger=logging.getLogger(__name__)
[docs]classAgentServiceUtils:""" This class contains utility methods related to the Agent Services. """
[docs]@staticmethodasyncdefget_agent_service_parameters(service_method):""" This method gets the required information about the parameters of the agent service: the names and types of service method parameters. Args: service_method (method): method of the agent service. Returns: dict: dictionary with all information about the parameters of the agent service. """ifservice_methodisNone:raiseKeyError(f"The service method {service_method} does not exist in this DT.")else:# Obtain the signature of the methodsig=inspect.signature(service_method)params=sig.parameters# Construct the dictionary with the information of the parametersparams_details={nombre:{'annotation':parametro.annotation,'type':parametro.annotationifparametro.annotationisnotinspect.Parameter.emptyelsestr,}fornombre,parametroinparams.items()}returnparams_details
[docs]@staticmethodasyncdefget_adapted_service_parameters(service_method,**kwargs):""" This method adapts the received parameters values to the required types of the service method, in order to be correctly executed. Args: service_method (method): method of the agent service. **kwargs: received parameters with the values. Returns: dict: parameters correctly adapted to the method. """ifservice_methodisNone:ValueError(f"A null object has been offered for the {service_method} method, its parameters cannot be "f"obtained.")# The information of the required method parameters is obtainedrequired_params_info=awaitAgentServiceUtils.get_agent_service_parameters(service_method)adapted_params={}# The received parameters with the values are available in kwargsiflen(required_params_info)!=0and((kwargsisNone)or(len(kwargs)==0)):raiseValueError(f"The service method cannot be executed because the required parameters have not been "f"provided.")forparam_name,valueinkwargs.items():ifparam_nameinrequired_params_info:tipo=required_params_info[param_name]['type']try:iftipo==bool:# bool(value) is true as long as the string is not empty, son it cannot be used.adapted_params[param_name]=value.lower()in('yes','true','t','1')else:adapted_params[param_name]=tipo(value)exceptValueErrorase:raiseValueError(f"Could not transform the value {value} for the parameter '{param_name}',"f" reason: {e}")else:raiseValueError(f"Parameter {param_name} not found in method {service_method}.")returnadapted_params
[docs]@staticmethodasyncdefsafe_execute_agent_service(service_method,**kwargs):""" This method executes the agent service securely, regardless of the execution method, synchronous or asynchronous. Args: service_method: executable method of the agent service. **kwargs: in case the execution method has parameters, they are passed as kwargs. Returns: result of the execution of the agent service. """ifinspect.iscoroutinefunction(service_method):returnawaitservice_method(**kwargs)else:returnservice_method(**kwargs)