コード例 #1
0
    def deserialize(data, graph, parser_classes, dkey='root', rnid=None):
        """
        Deserialize the items in an ordered list to nodes.

        The same method is also used to deserialize Python tuple and set types
        by using the ParseListType as base class.
        Lists, tuples and sets are the same from a graph perspective as
        mutability and order are not considered in graphs although it could be.

        :param data:            list data to deserialize
        :type data:             :py:list
        :param graph:           graph to add nodes to
        :type graph:            :graphit:GraphAxis
        :param parser_classes:  parser classes used to deserialize list items
        :param dkey:            list node key_tag
        :type dkey:             :py:str
        :param rnid:            nid of node to connect list node to
        :type rnid:             :py:int
        """

        nid = graph.add_node(dkey, format=return_instance_type(data), type='array')
        if rnid:
            graph.add_edge(rnid, nid)

        # Deserialize all list items in order
        for i, value in enumerate(data, start=1):
            parser = parser_classes.get(return_instance_type(value), parser_classes['fallback'])
            p = parser()
            p.deserialize(value, graph, parser_classes, dkey='item-{0}'.format(i), rnid=nid)
コード例 #2
0
    def deserialize(data, graph, parser_classes, dkey='root', rnid=None):

        nid = graph.add_node(dkey, format=return_instance_type(data), type='object')
        if rnid:
            graph.add_edge(rnid, nid)
        
        for key, value in sorted(data.items(), key=lambda x: str(x[0])):
            parser = parser_classes.get(return_instance_type(value), parser_classes['fallback'])
            p = parser()
            p.deserialize(value, graph, parser_classes, dkey=key, rnid=nid)
コード例 #3
0
 def deserialize(data, graph, parser_classes, dkey='root', rnid=None):
     
     nid = graph.add_node(dkey, format=return_instance_type(data), type='array')
     if rnid:
         graph.add_edge(rnid, nid)
     
     for i, value in enumerate(data, start=1):
         parser = parser_classes.get(return_instance_type(value), ParseListItem)
         p = parser()
         p.deserialize(value, graph, parser_classes, dkey='item-{0}'.format(i), rnid=nid)
コード例 #4
0
    def deserialize(data, graph, parser_classes, dkey=None, rnid=None):
        """
        Deserialize Python primitives or objects to nodes

        :param data:            data to deserialize
        :param graph:           graph to add nodes to
        :type graph:            :graphit:GraphAxis
        :param parser_classes:  parser classes used to deserialize list items
        :param dkey:            data node key_tag
        :type dkey:             :py:str
        :param rnid:            nid of node to connect list node to
        :type rnid:             :py:int
        """

        dtype = 'primative' if isinstance(data, PY_PRIMITIVES) else 'object'
        nid = graph.add_node(dkey, format=type(data).__name__, type=dtype)
        if rnid:
            graph.add_edge(rnid, nid)

        if not isinstance(data, PY_DATA_OBJECTS) and hasattr(data, '__iter__'):
            for i, value in enumerate(data, start=1):
                parser = parser_classes.get(return_instance_type(value), parser_classes['fallback'])
                p = parser()
                p.deserialize(value, graph, parser_classes, dkey='item-{0}'.format(i), rnid=nid)
        else:
            node = graph.getnodes(nid)
            node.set(graph.data.value_tag, data)
コード例 #5
0
    def deserialize(data, graph, parser_classes, dkey='root', rnid=None):
        """
        Level based deserialize key/value pairs in a dictionary

        All key/value pairs at the same level in a (nested) dictionary for
        for which the value itself is not a dictionary are stored in the
        same node.

        :param data:            dictionary data to deserialize
        :type data:             :py:dict
        :param graph:           graph to add nodes to
        :type graph:            :graphit:GraphAxis
        :param parser_classes:  parser classes used to deserialize list items
        :param dkey:            dictionary item node key_tag
        :type dkey:             :py:str
        :param rnid:            nid of node to connect list node to
        :type rnid:             :py:int
        """

        nid = graph.add_node(dkey, format=return_instance_type(data), type='object')
        if rnid:
            graph.add_edge(rnid, nid)

        for key, value in sorted(data.items(), key=lambda x: str(x[0])):
            if isinstance(value, dict):
                parser = parser_classes['dict']
                p = parser()
                p.deserialize(value, graph, parser_classes, dkey=key, rnid=nid)
            else:
                graph.nodes[nid][key] = value
コード例 #6
0
    def deserialize(data, graph, parser_classes, dkey='root', rnid=None):
        """
        Deserialize key/value pairs in a dictionary to nodes

        :param data:            list data to deserialize
        :type data:             :py:list
        :param graph:           graph to add nodes to
        :type graph:            :graphit:GraphAxis
        :param parser_classes:  parser classes used to deserialize list items
        :param dkey:            list node key_tag
        :type dkey:             :py:str
        :param rnid:            nid of node to connect list node to
        :type rnid:             :py:int
        """

        nid = graph.add_node(dkey, format=return_instance_type(data), type='object')
        if rnid:
            graph.add_edge(rnid, nid)

        for key, value in sorted(data.items(), key=lambda x: str(x[0])):
            parser = parser_classes.get(return_instance_type(value), parser_classes['fallback'])
            p = parser()
            p.deserialize(value, graph, parser_classes, dkey=key, rnid=nid)
コード例 #7
0
def read_pydata(data, graph=None, parser_classes=None, level=0):
    """
    Parse (hierarchical) python data structures to a graph

    Many data formats are first parsed to a python structure before they are
    converted to a graph using the `read_pydata` function.
    The function supports any object that is an instance of, or behaves as, a
    Python dictionary, list, tuple or set and converts these (nested)
    structures to graph nodes and edges for connectivity. Data is stored in
    nodes using the node and edge 'key_tag' and 'value_tag' attributes in the
    Graph class.

    Data type and format information are also stored as part of the nodes to
    enable reconstruction of the Python data structure on export using the
    `write_pydata` function. Changing type and format on a node or edge
    allows for customized data export.

    Parsing of data structures to nodes and edges is handled by parser classes
    that need to define the methods `deserialize` for reading and `serialize`
    for writing. In `write_pydata` these classes are registered with the ORM
    to fully customize the use of the `serialize` method. In the `read_pydata`
    function the ORM cannot be used because the nodes/edges themselves do not
    yet exist. Instead they are provided as a dictionary through the
    `parser_classes` argument. The dictionary defines the string representation
    of the Python data type as key and parser class as value.

    Parser customization is important as Python data structures can be
    represented as a graph structure in different ways. This is certainly true
    for dictionaries where key/value pairs can be part of the node attributes,
    as separate nodes or as a combination of the two.
    `read_pydata` has quick support for two scenario's using the `level`
    argument:

        * level 0: every dictionary key/value pair is represented as a node
          regardless of its position in the nested data structure
        * level 1: all keys at the same level in the hierarchy that have a
          primitive type value are stored as part of the node attributes.

    If the `graph` is empty, the first node added to the graph is assigned
    as root node. If the `graph` is not empty, new nodes and edges will be
    added to it as subgraph. Edge connections between the two will have to be
    made afterwards.

    :param data:            Python (hierarchical) data structure
    :param graph:           GraphAxis object to import dictionary data in
    :type graph:            :graphit:GraphAxis
    :param parser_classes:  parser class definition for different Python data
                            types. Updates default classes for level 0 or 1
    :type parser_classes:   :py:dict
    :param level:           dictionary parsing mode
    :type level:            :py:int

    :return:                GraphAxis object
    :rtype:                 :graphit:GraphAxis
    """

    # User defined or default GraphAxis object
    if graph is None:
        graph = GraphAxis()
    elif not isinstance(graph, GraphAxis):
        raise GraphitException('Unsupported graph type {0}'.format(type(graph)))

    # Determine parser classes to use based on level
    assert level in (0, 1), GraphitException('Unsupported level {0}. Required to be 0 or 1'.format(level))
    if level == 0:
        parser_class_dict = copy.copy(ORMDEFS_LEVEL0)
    else:
        parser_class_dict = copy.copy(ORMDEFS_LEVEL1)

    # Update parser_class_dict with custom classes if any
    if isinstance(parser_classes, dict):
        parser_class_dict.update(parser_classes)

    # Define root
    if graph.empty():
        graph.root = graph.data.nodeid

    # Start recursive parsing by calling the `deserialize` method on the parser object
    parser = parser_class_dict.get(return_instance_type(data), parser_class_dict['fallback'])
    p = parser()
    p.deserialize(data, graph, parser_class_dict)

    return graph