Skip to content
Snippets Groups Projects
workflow_writer.py 3.25 KiB
Newer Older
import json
Stefano Borini's avatar
Stefano Borini committed
from traits.api import HasStrictTraits
from collections import Iterable


class WorkflowWriter(HasStrictTraits):
    """A Writer for writing the Workflow onto disk.
    """
    def write(self, workflow, f):
        """Writes the workflow model object to a file f in JSON format.

        Parameters
        ----------
        workflow: Workflow
            The Workflow instance to write to file

        f: File
            A file object on which to write the workflow, properly serialized
            into JSON.
        """
        data = dict(version="1")
        data["workflow"] = self._workflow_data(workflow)
        json.dump(data, f, indent=4)

    def _workflow_data(self, workflow):
        workflow_data = {
            "mco": self._mco_data(workflow.mco),
            "execution_layers": [
                self._execution_layer_data(el)
                for el in workflow.execution_layers],
            "notification_listeners": [
                self._model_data(nl)
                for nl in workflow.notification_listeners
            ]
        return workflow_data

    def _mco_data(self, mco):
        """Extracts the data from the MCO object and returns its dictionary.
        If the MCO is None, returns None"""
        if mco is None:
            return None

        data = self._model_data(mco)
Stefano Borini's avatar
Stefano Borini committed
        parameters_data = []
        for param in data["model_data"]["parameters"]:
Stefano Borini's avatar
Stefano Borini committed
            state = traits_to_dict(param)
Stefano Borini's avatar
Stefano Borini committed
            parameters_data.append(
                {
                    "id": param.factory.id,
                    "model_data": state
        data["model_data"]["parameters"] = parameters_data
Stefano Borini's avatar
Stefano Borini committed

        kpis_data = []
        for kpi in data["model_data"]["kpis"]:
            kpis_data.append(
                traits_to_dict(kpi)
            )

        data["model_data"]["kpis"] = kpis_data

    def _execution_layer_data(self, layer):
        """Extracts the execution layer list of DataSource models"""
        data = []

            data.append(self._model_data(ds))

        return data

    def _model_data(self, model):
        Extracts the data from an external model and returns its dictionary
Stefano Borini's avatar
Stefano Borini committed
        state = traits_to_dict(model)
            "id": model.factory.id,
Stefano Borini's avatar
Stefano Borini committed


def traits_to_dict(traits_obj):
    """Converts a traits class into a dict, removing the pesky
    traits version."""
Stefano Borini's avatar
Stefano Borini committed
    state = traits_obj.__getstate__()
    state = pop_traits_version(state)
Stefano Borini's avatar
Stefano Borini committed

    return state


def pop_traits_version(dictionary):
    """Recursively remove the __traits_version__ attribute
    from dictionary."""
    try:
        dictionary.pop("__traits_version__")
    except KeyError:
        pass

    for key in dictionary:
        # If we have a dict, remove the traits version
        if isinstance(dictionary[key], dict):
            pop_traits(dictionary[key])
        # If we have a non-dict which contains a dict, remove traits from
        # that as well
        elif isinstance(dictionary[key], Iterable):
            for element in dictionary[key]:
                if isinstance(element, dict):
                    pop_traits(element)

    return dictionary