.. _io: ######### Graph I/O ######### .. testsetup:: >>> from ragraph.graph import Graph This page covers importing and exporting the :obj:`~ragraph.graph.Graph` object from and to different (file) formats using the :obj:`ragraph.io` module. Among the available formats are: * `JSON `_ * `CSV `_ (Comma Separated Values) * `Matrix `_ (a :obj:`numpy.ndarray` or a list of lists) * ESL (Elephant Specification Language) * :obj:`~ragraph.io.yaml` * :obj:`~ragraph.io.xml` (generic) * :obj:`~ragraph.io.archimate` (Archimate XML dialect) The importing and exporting of JSON is probably the most extensive implementation, closely followed by CSV. Some formats are only partly supported, where in most cases it features either importing to a :obj:`~ragraph.graph.Graph` or merely exporting one. .. _io json: **** JSON **** A :obj:`~ragraph.graph.Graph` can be translated both from and to a JSON file or encoded JSON string. These are all based on the JSON dictionary representations of the objects in the graph and handled by the :obj:`ragraph.io.json` module. Let's show a suitable JSON file. .. literalinclude:: ../../../tests/data/json/simple.json :language: json :caption: simple.json Which may seem relatively verbose, but is little more than a JSON dump of the :obj:`~ragraph.graph.Graph.json_dict` property of an otherwise simple :obj:`~ragraph.graph.Graph`. Importing it is as simple as: .. testsetup:: >>> path = datadir / "json" / "simple.json" .. doctest:: >>> from ragraph.io.json import from_json >>> g = from_json(path) # Path points to the JSON file above. Which loads a :obj:`~ragraph.graph.Graph` into ``g`` with six nodes (``"a"`` through ``"f"``) with a couple of edges between them. If you already have a JSON encoded string loaded into a variable, you can also supply this by using: ``from_json(enc=my_string_variable)``. Exporting the graph is equally simple: .. doctest:: >>> from ragraph.io.json import to_json >>> enc = to_json(g, path=None) Which by setting ``path=None`` will give you a JSON string representation of the graph. When actually setting the path to a filepath, the string will not be returned and written to that filepath instead. .. _io csv: *** CSV *** The CSV format is probably one of the most compact formats we support. To import from CSV you need both a **nodes** and an **edges** file. The functionality is included in the :obj:`ragraph.io.csv` module. The minimum requirement to a nodes file is that each node has a ``name``. A basic nodes file thus looks like: .. literalinclude:: ../../../tests/data/csv/simple_nodes.csv :language: csv :caption: simple_nodes.csv This file will generate six nodes named ``"a"`` through ``"f"`` when imported, with all other :obj:`~ragraph.node.Node` arguments left to their defaults. The minimum edges file needs a ``source`` and a ``target`` column. These should refer to the source and target node of each edge, such as: .. literalinclude:: ../../../tests/data/csv/simple_edges.csv :language: csv :caption: simple_edges.csv Importing these can be done using the following snippet: .. testsetup:: >>> nodes_path = datadir / "csv" / "simple_nodes.csv" >>> edges_path = datadir / "csv" / "simple_edges.csv" .. doctest:: >>> from ragraph.io.csv import from_csv >>> g = from_csv(nodes_path, edges_path) # paths to simple_nodes.csv and simple_edges.csv You can tweak some additional settings in the :obj:`~ragraph.io.csv.from_csv` method like the CSV delimiter and some parameters to indicate which column includes which metadata. .. _io matrix: ****** Matrix ****** A :obj:`~ragraph.graph.Graph` and its adjacency matrix are closely related. To facilitate quick transitions between these representations, we included the :obj:`ragraph.io.matrix` module. This allows you to transition back and forth from a list of lists or nested numpy array and a :obj:`~ragraph.graph.Graph` object. A small example: .. doctest:: >>> from ragraph.io.matrix import from_matrix >>> A = [[0, 1, 0], [2, 0, 1], [9, 9, 9]] >>> g = from_matrix(A) And the other way around: .. doctest:: >>> from ragraph.io.matrix import to_matrix >>> to_matrix(g, loops=False) array([[0., 1., 0.], [2., 0., 1.], [9., 9., 0.]]) We usually default to leaving out edges that are self-loops (e.g. the diagonal is 0), but if you would like to include them, just set ``loops=True``. There are some tweaks for hierarchical graphs, too. Please refer to the ``~ragraph.io.matrix`` module's documentation for that. ************************************* ESL (Elephant Specification Language) ************************************* The ESL format is supported in an import-only fashion, as arbitrary :obj:`~ragraph.graph.Graph` objects have no ESL equivalent. However, we can derive a dependency graph from the imported ESL files.