-
Notifications
You must be signed in to change notification settings - Fork 5
Internal API
The origins.graph.core contains the core API of Origins that the higher-level types build upon.
Module: origins.graph.core.nodes
-
uuid- An auto-generated UUID for the node. -
id- An ID that is persisted across revisions of this node. This may be supplied by the client, otherwise one will be auto-generated. -
properties- A map of key/value pairs that represent the data of node.
Adds a node to the graph.
-
attrs- Attributes for the node. -
labels- Set of labels to give the node. Labels act as a minimal schema to differentiate nodes in the graph such asPersonorBook.
Patches the attributes of the node with the passed attributes. The semantics of patching are as follows:
- Attributes with a
Nonevalue will be unset (if present) in the output - The nested
propertiesmap will be patched using the same semantics - All other attributes will be added or changed in the output
If the patched output is different from the prior state, a new revision is created, otherwise it exits.
-
uuid(required) - The UUID of the node whose attributes are being set. -
attrs- Attributes being set on the node. -
force- If true, forces a change to be recorded.
Invalidates a node in the graph and invalidates all edges pointing to it.
-
uuid(required) - The UUID of the node being removed.
Module: origins.graph.core.edges
Edges connect two nodes with an optional dependence.
-
uuid- An auto-generated UUID for the edge. -
id- An ID that is persisted across revisions of this edge. This may be supplied by the client, otherwise one will be auto-generated. -
properties- A map of key/value pairs that represent the data of edge. -
dependence- Declares the type of dependence between the two nodes:0declares no dependence,1is uni-directional (start to end),2is bi-directional. Default is1.
Defines an edge between two nodes in the graph. The physical representation of this a node (representing the edge) with origins:start and origins:end edges to the respective nodes. It is modeled this way so provenance can be linked to the edge as it changes.
In addition to this verbose representation, a native edge is formed between the nodes with a type specified by the type attribute. The edge exists as long as the node-based edge is valid. This provides a native representation of the nodes and edges in the graph for query purposes.
-
start(required) - The UUID of a node which is the start of the edge. -
end(required) - The UUID of a node which is the end of the edge. -
attrs- Attributes for the edge.
Patches the attributes of the edge with the passed attributes. The semantics of patching are as follows:
- Attributes with a
Nonevalue will be unset (if present) in the output - The nested
propertiesmap will be patched using the same semantics - All other attributes will be added or changed in the output
If the patched output is different from the prior state, a new revision is created, otherwise it exits.
-
uuid(required) - The UUID of the edge whose attributes are being set. -
attrs- Attributes being set on the edge. -
force- If true, forces a change to be recorded.
Invalidates an edge in the graph.
-
uuid(required) - The UUID of the edge being removed.
joe = nodes.add({'label': 'Joe'}){
'data': {
'properties': {},
'label': 'Joe',
'time': 1409246079588,
'uuid': 'eae9ae0f-ea13-4af2-a1cb-cd5239e1a1f3',
'id': 'eae9ae0f-ea13-4af2-a1cb-cd5239e1a1f3'
},
'time': 1409246079604,
'prov': {
'wasGeneratedBy': {
'wgb': {
'origins:uuid': '910b0b43-ce0e-45a7-b575-55ece7285019'
}
},
'entity': {
'entity': {
'origins:uuid': 'eae9ae0f-ea13-4af2-a1cb-cd5239e1a1f3'
}
}
},
'perf': {
'exec': 8.783249999396503,
'total': 16.736075980588794,
'prov': 7.655357010662556,
'prep': 0.2974689705297351
}
}
Another node graphs is created to be linked to. The formed edge is "Joe uses graphs".
graphs = nodes.add({'label': 'graphs'})
joe_uses_graphs = edges.add(joe, graphs, {'label': 'uses'})Edges have their start and end nodes embedded in the output.
{
'data': {
'properties': {},
'end': {
'id': 'f8b415aa-ed7d-466d-a21b-e667f571aa60',
'properties': {},
'time': 1409246079626,
'label': 'graphs',
'uuid': 'f8b415aa-ed7d-466d-a21b-e667f571aa60'
},
'start': {
'id': 'eae9ae0f-ea13-4af2-a1cb-cd5239e1a1f3',
'properties': {},
'time': 1409246079588,
'label': 'Joe',
'uuid': 'eae9ae0f-ea13-4af2-a1cb-cd5239e1a1f3'
},
'label': 'uses',
'time': 1409246079669,
'uuid': 'eec93213-9962-4a8c-b3f8-ed25c7d3689b',
'id': 'eec93213-9962-4a8c-b3f8-ed25c7d3689b'
},
'time': 1409246079688,
'prov': {
'wasGeneratedBy': {
'wgb': {
'origins:uuid': '03c0f32e-e137-4ecd-82b4-9e1d43d45b8a'
}
},
'entity': {
'entity': {
'origins:uuid': 'eec93213-9962-4a8c-b3f8-ed25c7d3689b'
}
}
},
'perf': {
'exec': 8.26109800254926,
'total': 19.8202200117521,
'prov': 11.044259008485824,
'prep': 0.5148630007170141
}
}
Actually, Joe abuses graphs, so we will update the edge.
joe_abuses_graphs = edges.set(joe_uses_graphs, {'type': 'abuses'})The notable parts to this is that a new edge is formed with the update type attribute between the same start and end nodes, joe and graphs. The previous edge is invalidated as implied by the wasInvalidatedBy declaration in the prov output.
{
'data': {
'properties': {},
'end': {
'id': 'f8b415aa-ed7d-466d-a21b-e667f571aa60',
'properties': {},
'time': 1409246079626,
'label': 'graphs',
'uuid': 'f8b415aa-ed7d-466d-a21b-e667f571aa60'
},
'start': {
'id': 'eae9ae0f-ea13-4af2-a1cb-cd5239e1a1f3',
'properties': {},
'time': 1409246079588,
'label': 'Joe',
'uuid': 'eae9ae0f-ea13-4af2-a1cb-cd5239e1a1f3'
},
'label': 'abuses',
'time': 1409246079720,
'uuid': '9fc19b69-c01e-4810-adbf-97218f952957',
'id': 'eec93213-9962-4a8c-b3f8-ed25c7d3689b'
},
'time': 1409246079752,
'prov': {
'wasInvalidatedBy': {
'wib': {
'origins:uuid': '238ebc76-adbc-43e1-94e5-2b6903ffa59f'
}
},
'wasGeneratedBy': {
'wgb': {
'origins:uuid': '48629f0b-7f5e-4874-b7ae-894bf91d5697'
}
},
'entity': {
'entity': {
'origins:uuid': '9fc19b69-c01e-4810-adbf-97218f952957'
},
'previous': {
'origins:uuid': 'eec93213-9962-4a8c-b3f8-ed25c7d3689b'
}
},
'wasDerivedFrom': {
'wdf': {
'origins:uuid': 'b954c4f3-5b23-484d-95b6-162f0502e6cd'
}
}
},
'perf': {
'total': 42.75646596215665,
'prov': 9.88005695398897,
'add_edge': {
'exec': 7.928737031761557,
'total': 21.936770994216204,
'prov': 13.81991000380367,
'prep': 0.18812395865097642
},
'get': 10.919241001829505,
'prep': 0.020397012121975422
}
}
Joe mistakenly generalized graphs for graph databases. We should update this term.
graph_dbs = nodes.set(graphs, {'label': 'graph databases'}){
'data': {
'properties': {},
'label': 'graph databases',
'time': 1409246079781,
'uuid': 'aee22fd1-abe0-46ac-b358-a5be322bb3f1',
'id': 'f8b415aa-ed7d-466d-a21b-e667f571aa60'
},
'time': 1409246079811,
'prov': {
'wasInvalidatedBy': {
'wib': {
'origins:uuid': '2c02a754-293f-41a4-acee-dea4187de376'
}
},
'wasGeneratedBy': {
'wgb': {
'origins:uuid': '21b1afd7-5e3c-4edb-bba8-c0f726b086c7'
}
},
'entity': {
'entity': {
'origins:uuid': 'aee22fd1-abe0-46ac-b358-a5be322bb3f1'
},
'previous': {
'origins:uuid': 'f8b415aa-ed7d-466d-a21b-e667f571aa60'
}
},
'wasDerivedFrom': {
'wdf': {
'origins:uuid': '22e3e6db-898b-4ce5-817f-b7f367dc5f14'
}
}
},
'perf': {
'total': 57.56482103606686,
'prov': 6.9136389647610486,
'add': 17.835922015365213,
'get': 9.680492978077382,
'update_edges': 5.3289890056476,
'prep': 0.020351028069853783
}
}Joe still abuses graphs, why not graph databases? This is where the notion of a dependency graph comes in. The edge from Joe to graphs is directed therefore implicitly declaring a dependency on graphs by joe. Since Joe didn't confirm this change from his perspective, the edge was not updated.

The name "Joe" may be not be recognizable to some, so Joe decides to change his name to include his surname.
joe_smith = nodes.set(joe, {'label': 'Joe Smith'}){
'data': {
'properties': {},
'label': 'Joe Smith',
'time': 1409246079836,
'uuid': 'a06a8617-57ac-4a3b-8ff4-63829d8f9577',
'id': 'eae9ae0f-ea13-4af2-a1cb-cd5239e1a1f3'
},
'time': 1409246079895,
'prov': {
'wasInvalidatedBy': {
'wib': {
'origins:uuid': 'f97939e8-2fd7-4af0-a9fd-5de89ed0c403'
}
},
'wasGeneratedBy': {
'wgb': {
'origins:uuid': 'f4560375-51e0-48af-b8c8-9c03cd74b7ad'
}
},
'entity': {
'entity': {
'origins:uuid': 'a06a8617-57ac-4a3b-8ff4-63829d8f9577'
},
'previous': {
'origins:uuid': 'eae9ae0f-ea13-4af2-a1cb-cd5239e1a1f3'
}
},
'wasDerivedFrom': {
'wdf': {
'origins:uuid': 'c6e142d1-2f57-4b26-be6d-9b1373fc1e62'
}
}
},
'perf': {
'total': 84.33187287300825,
'prov': 7.962606963701546,
'add': 16.77478099009022,
'get': 8.776464965194464,
'update_edges': 34.07454496482387,
'prep': 0.007753027603030205
}
}Look at that, "Joe Smith" still uses graphs! This demonstrates that changes to nodes having dependencies are always re-linked.
The prov:Generation nodes have been omitted for clarity.
