Skip to content

hololinked.td.interaction_affordance.ActionAffordance

Bases: InteractionAffordance

creates action affordance schema from actions (or methods).

Schema
UML Diagram

Source code in hololinked/hololinked/td/interaction_affordance.py
class ActionAffordance(InteractionAffordance):
    """
    creates action affordance schema from actions (or methods).

    [Schema](https://www.w3.org/TR/wot-thing-description11/#actionaffordance) <br>
    [UML Diagram](https://docs.hololinked.dev/UML/PDF/InteractionAffordance.pdf) <br>
    """

    # [Supported Fields]() <br>
    input: JSON = None
    output: JSON = None
    safe: bool = None
    idempotent: bool = None
    synchronous: bool = None

    def __init__(self):
        super().__init__()

    @property
    def what(self):
        return ResourceTypes.ACTION

    def build(self) -> None:
        action = self.objekt  # type: Action
        if action.obj.__doc__:
            title = get_summary(action.obj.__doc__)
            description = self.format_doc(action.obj.__doc__)
            if title and not description.startswith(title):
                self.title = title
                self.description = description
            else:
                self.description = description
        if action.execution_info.argument_schema:
            if isinstance(action.execution_info.argument_schema, dict):
                self.input = action.execution_info.argument_schema
            elif issubklass(action.execution_info.argument_schema, (BaseModel, RootModel)):
                self.input = type_to_dataschema(action.execution_info.argument_schema)
            else:
                raise ValueError(
                    f"unknown schema definition for action input, given type: {type(action.execution_info.argument_schema)}"
                )
        if action.execution_info.return_value_schema:
            if isinstance(action.execution_info.return_value_schema, dict):
                self.output = action.execution_info.return_value_schema
            elif issubklass(action.execution_info.return_value_schema, (BaseModel, RootModel)):
                self.output = type_to_dataschema(action.execution_info.return_value_schema)
            else:
                raise ValueError(
                    f"unknown schema definition for action output, given type: {type(action.execution_info.return_value_schema)}"
                )
        if (
            not (
                hasattr(self.owner, "state_machine")
                and self.owner.state_machine is not None
                and self.owner.state_machine.contains_object(action)
            )
            and action.execution_info.idempotent
        ):
            self.idempotent = action.execution_info.idempotent
        if action.execution_info.synchronous:
            self.synchronous = action.execution_info.synchronous
        if action.execution_info.safe:
            self.safe = action.execution_info.safe

    @classmethod
    def generate(cls, action: Action, owner, **kwargs) -> "ActionAffordance":
        if not isinstance(action, Action):
            raise TypeError(f"action must be instance of Action, given type {type(action)}")
        affordance = ActionAffordance()
        affordance.owner = owner
        affordance.objekt = action
        affordance.build()
        affordance.build_non_compliant_metadata()
        return affordance
field supported meaning default usage
input ✔️ schema of the input required to invoke action input_schema value of action decorator
output ✔️ schema of the output returned by the action output_schema value of action decorator
safe ✔️ true if the action is safe safe value of action decorator
idempotent ✔️ true if the action is idempotent idempotent value of action decorator
synchronous ✔️ true if the action is synchronous synchronous value of action decorator, (false for async or threaded functions)