# JSON Configuration Format

JSON is a self-contained, human-readable data-interchange format. It is pure Unicode text and language independent. The main structures objects containing key/value pairs (hash-tables, dictionaries, associative arrays …) and ordered lists (arrays, vectors, sequences …) of objects or values. For a complete description you may refer to the complete reference at json.org.

The configuration of a filter setup is stored in a JSON-encoded text file with a `.json` suffix. The root object must at least contain a `nodes` and an `edges` array

    { "nodes": [], "edges": [] }

## Nodes array

The nodes array contains filter objects that are executed on run-time. Information how they are connected is provided in the Edges array.

### Filter object

A filter consists at least of a `plugin` key string pointing to the filter that is going to be used and a `name` string field for unique identification. Of course, plugins have to be available as a shared object in UFO’s path.

To configure the filter, the `properties` field can be used. This is an object that maps string keys specifying the actual filter property to the value. Therefore, the Python code to set a property

    read = graph.get_filter('read')
    read.set_properties(path='/home/user/data/*.tif', count=5)

translates to

    { "path": "/home/user/data/*.tif", "count": 5 }

### Example nodes array

An example node array looks like this:

    "nodes" : [
        {
            "plugin": "read",
            "name": "read",
            "properties" : { "path": "/home/user/data/*.tif", "count": 5 }
        },
        {
            "plugin": "write",
            "name": "write"
        }
    ]

## Edges array

The edges array specifies how the nodes in a Nodes array are connected. Each entry is an object that contains two objects `from` and `to`. In both objects you have to specify at least the node name with the `name` key. Furthermore, if there are several inputs or outputs on a node, you have to tell which input and output to use with the `input` on the `to` node and the `output` key on the `from` node. If you omit these, they are assumed to be 0.

To connect the nodes defined in the Example nodes array all you have to do is

    "edges" : [
        {
            "from": {"name": "read"},
            "to": {"name": "write", "input": 2}
        }
    ]

Note, that the names specify the name of the node, not the plugin.

## Loading and Saving the Graph

The `UfoGraph` class exports the `ufo_graph_read_from_json` and `ufo_graph_read_save_to_json` methods which are responsible for loading and saving the graph. In Python this would simply be:

    from gi.repository import Ufo

    g1 = Ufo.TaskGraph()

    # set up the filters using graph.get_filter() and filter.connect_to()

    g1.run()
    g1.save_to_json('graph.json')

    g2 = Ufo.TaskGraph()
    g2.load_from_json('graph.json')
    g2.run()