Quick Start =========== This library introduces a ``Graph`` object. It will contain all the nodes and connections of your graph. It can also contain any additional data. A ``Graph`` can be *directed* (the link between two nodes has a single direction) or *undirected* (any link between two nodes is symmetrical). By default, it is directed. .. code:: python from galaxy_graph import Graph # Family tree can be considered as directed graph, a relationship is not symmetrical family_tree = Graph( data="This graph stores my family tree. As I did not specify `is_directed`, it is directed, which is nice for a family graph" ) # create a directed graph with a description in its data # A hiking trail with nodes for intersection, relationships are symmetrical hiking_trails = Graph( is_directed=False, ) # create a undirected graph without any data There is also a ``Node`` object, that can contain any data. .. code:: python from galaxy_graph import Node # In these example, data contains a dictionary, but data can contains any value ! # For the family tree michel = Node(data={"Name": "Michel", "age": 48}) alberto = Node(data={"Name": "Alberto", "age": 46}) alice = Node(data={"Name": "Alice", "age": 20}) # For the hiking trail city_entrance = Node(data={"x": 5, "y": 10}) rocky_promontory = Node(data={"x": 18, "y": 13}) oak_forest = Node(data={"x": 10, "y": 10}) lake = Node(data={"x": -3, "y": 4}) Without ``Connection``, there is no link between ``Node`` and your graphs would be boring… Again, these can contain any data. .. code:: python from galaxy_graph import Connection # For the hiking trail straight_road = Connection(data={"ground type": "dirt"}) You can then add your nodes to the graph and connect them. .. code:: python hiking_trails.add(city_entrance) # add city entrance to the graph city_entrance.connect(straight_road, rocky_promontory) # the city entrance # and the rocky promontory are linked together. The straight road allows # traversal in both direction because hiking_trails is an undirected graph. .. warning:: Adding a node to the graph is mandatory for adding connection to it. Any node connected to this one will be automatically added to the graph. .. note:: It is also possible to create the connection in the ``connect`` call. .. code:: python rocky_promontory.connect( Connection(data={"ground type": "dirt"}), oak_forest, ) city_entrance.connect( Connection(data={"ground type": "asphalt"}), oak_forest, ) oak_forest.connect( Connection(data={"ground type": "dirt"}), lake, ) lake.connect( Connection(data={"ground type": "dirt"}), city_entrance, ) .. code:: python family_tree.add(michel) michel.connect(Connection(data="is married to"), alberto) # Michel and Alberto are married alberto.connect(Connection(data="is married to"), michel) # symmetrical link # here, so we add a connection in the other direction. michel.connect(Connection(data="is parent of"), alice) alberto.connect(Connection(data="is parent of"), alice) alice.connect(Connection(data="is child of"), michel) alice.connect(Connection(data="is child of"), alberto) .. warning:: As family tree is a directed graph, the connection Michel->Alberto is different than the connection Alberto->Michel. .. code:: python michel_alberto = Connection(data="is married to") michel.connect(michel_alberto, alberto) alberto.connect(michel_alberto, michel) # will fail: the connection is # already used. If you run all the python code above, your hiking_trails graph will look like this: .. mermaid:: :title: Hiking trails graph TD A[City entrance] <-->|dirt road| B[Rocky promontory] B <-->|dirt road| C[Oak forest] C <-->|dirt road| D[Lake] D <-->|dirt road| A A <-->|asphalt road| C For the family tree, the resulting graph will be: .. mermaid:: :title: Family tree graph TD Michel -->|is married to| Alberto Alberto -->|is married to| Michel Michel -->|is parent of| Alice Alberto -->|is parent of| Alice Alice -->|is child of| Michel Alice -->|is child of| Alberto