Move actions to pydantic

This commit is contained in:
Marek Wolan
2023-09-04 10:20:06 +01:00
parent d55fd835c7
commit 33b4911cb1

View File

@@ -1,3 +1,4 @@
# flake8: noqa
"""Core of the PrimAITE Simulator."""
from abc import ABC, abstractmethod
from typing import Callable, Dict, List, Optional, Union
@@ -10,7 +11,7 @@ from primaite import getLogger
_LOGGER = getLogger(__name__)
class ActionPermissionValidator(ABC):
class ActionPermissionValidator(BaseModel):
"""
Base class for action validators.
@@ -33,7 +34,7 @@ class AllowAllValidator(ActionPermissionValidator):
return True
class Action:
class Action(BaseModel):
"""
This object stores data related to a single action.
@@ -41,34 +42,22 @@ class Action:
the action can be performed or not.
"""
def __init__(
self, func: Callable[[List[str], Dict], None], validator: ActionPermissionValidator = AllowAllValidator()
) -> None:
"""
Save the functions that are for this action.
Here's a description for the intended use of both of these.
``func`` is a function that accepts a request and a context dict. Typically this would be a lambda function
that invokes a class method of your SimComponent. For example if the component is a node and the action is for
turning it off, then the SimComponent should have a turn_off(self) method that does not need to accept any args.
Then, this Action will be given something like ``func = lambda request, context: self.turn_off()``.
``validator`` is an instance of a subclass of `ActionPermissionValidator`. This is essentially a callable that
accepts `request` and `context` and returns a boolean to represent whether the permission is granted to perform
the action.
:param func: Function that performs the request.
:type func: Callable[[List[str], Dict], None]
:param validator: Function that checks if the request is authenticated given the context. By default, if no
validator is provided, an 'allow all' validator is added which permits all requests.
:type validator: ActionPermissionValidator
"""
self.func: Callable[[List[str], Dict], None] = func
self.validator: ActionPermissionValidator = validator
func: Callable[[List[str], Dict], None]
"""
``func`` is a function that accepts a request and a context dict. Typically this would be a lambda function
that invokes a class method of your SimComponent. For example if the component is a node and the action is for
turning it off, then the SimComponent should have a turn_off(self) method that does not need to accept any args.
Then, this Action will be given something like ``func = lambda request, context: self.turn_off()``.
"""
validator: ActionPermissionValidator = AllowAllValidator()
"""
``validator`` is an instance of `ActionPermissionValidator`. This is essentially a callable that
accepts `request` and `context` and returns a boolean to represent whether the permission is granted to perform
the action. The default validator will allow
"""
class ActionManager:
class ActionManager(BaseModel):
"""
ActionManager is used by `SimComponent` instances to keep track of actions.
@@ -76,9 +65,8 @@ class ActionManager:
class is responsible for providing a consistent API for processing actions as well as helpful error messages.
"""
def __init__(self) -> None:
"""Initialise ActionManager with an empty action lookup."""
self.actions: Dict[str, Action] = {}
actions: Dict[str, Action] = {}
"""maps action verb to an action object."""
def process_request(self, request: List[str], context: Dict) -> None:
"""Process an action request.
@@ -125,6 +113,11 @@ class ActionManager:
self.actions[name] = action
def list_actions(self) -> List[List[str]]:
actions = []
for act_name, act in self.actions.items():
pass # TODO:
class SimComponent(BaseModel):
"""Extension of pydantic BaseModel with additional methods that must be defined by all classes in the simulator."""
@@ -178,6 +171,14 @@ class SimComponent(BaseModel):
}
return state
def possible_actions(self) -> List[List[str]]:
"""Enumerate all actions that this component can accept.
:return: List of all action strings that can be passed to this component.
:rtype: List[Dict[str]]
"""
action_list = ActionManager # TODO: extract possible actions? how to do this neatly?
def apply_action(self, action: List[str], context: Dict = {}) -> None:
"""
Apply an action to a simulation component. Action data is passed in as a 'namespaced' list of strings.
@@ -230,7 +231,3 @@ class SimComponent(BaseModel):
_LOGGER.warn(msg)
raise RuntimeWarning(msg)
self._parent = new_parent
@parent.deleter
def parent(self) -> None:
self._parent = None