Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/layer name time #1593

Merged
merged 19 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 60 additions & 36 deletions python/tests/notebook.ipynb

Large diffs are not rendered by default.

71 changes: 59 additions & 12 deletions python/tests/test_graphdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,65 @@ def test_layer_name():
assert g.edge(0, 1).layer_names == ["_default"]
assert g.edge(0, 2).layer_names == ["awesome layer"]

error_msg = ("The layer_name function is only available once an edge has been exploded via .explode_layers() or .explode(). "
"If you want to retrieve the layers for this edge you can use .layer_names")
with pytest.raises(Exception) as e:
g.edges.layer_name()
assert str(e.value) == error_msg

assert list(g.edges.explode().layer_name) == ['_default', 'awesome layer']
assert list(g.edges.explode_layers().layer_name) == ['_default', 'awesome layer']

with pytest.raises(Exception) as e:
g.edge(0, 2).layer_name()
assert str(e.value) == error_msg

assert list(g.edge(0, 2).explode().layer_name) == ['awesome layer']
assert list(g.edge(0, 2).explode_layers().layer_name) == ['awesome layer']

with pytest.raises(Exception) as e:
g.nodes.neighbours.edges.layer_name()
assert str(e.value) == error_msg

assert [list(iterator) for iterator in g.nodes.neighbours.edges.explode().layer_name] == [
["_default", "awesome layer"],
["_default", "awesome layer"],
["_default", "awesome layer"]
]
assert [list(iterator) for iterator in g.nodes.neighbours.edges.explode_layers().layer_name] == [
["_default", "awesome layer"],
["_default", "awesome layer"],
["_default", "awesome layer"]
]

def test_time():
g = Graph()
g.add_constant_properties({"name": "graph"})

g.add_edge(0, 0, 1)
g.add_edge(0, 0, 2)
g.add_edge(1, 0, 2)

error_msg = ("The time function is only available once an edge has been exploded via .explode(). "
"You may want to retrieve the history for this edge via .history(), or the earliest/latest time via earliest_time or latest_time")
with pytest.raises(Exception) as e:
g.edges.time()
assert str(e.value) == error_msg

assert list(g.edges.explode().time) == [0, 0, 1]

with pytest.raises(Exception) as e:
g.edge(0, 2).time()
assert str(e.value) == error_msg

assert list(g.edge(0, 2).explode().time) == [0, 1]

with pytest.raises(Exception) as e:
g.nodes.neighbours.edges.time()
assert str(e.value) == error_msg

assert [list(iterator) for iterator in g.nodes.neighbours.edges.explode().time] == [[0, 0, 1], [0, 0, 1], [0, 0, 1]]


def test_window_size():
g = Graph()
Expand Down Expand Up @@ -1841,11 +1900,6 @@ def test_starend_edges():
g.add_edge(2, 1, 2)
g.add_edge(3, 1, 2)

old_time_way = []
shivam-880 marked this conversation as resolved.
Show resolved Hide resolved
for e in g.edges:
old_time_way.append(e.time)
assert old_time_way == list(g.edges.time)

old_latest_time_way = []
for e in g.edges:
old_latest_time_way.append(e.latest_time)
Expand All @@ -1857,20 +1911,13 @@ def test_starend_edges():
old_earliest_time_way.append(e.earliest_time)
assert old_earliest_time_way == list(g.edges.earliest_time)

old_start_nested_way = []
old_end_nested_way = []
old_time_nested_way = []
old_latest_time_nested_way = []
old_earliest_time_nested_way = []
for edges in g.nodes.edges:
for edge in edges:
old_time_nested_way.append(edge.time)
old_latest_time_nested_way.append(edge.latest_time)
old_earliest_time_nested_way.append(edge.earliest_time)

assert old_time_nested_way == [
item for sublist in g.nodes.edges.time.collect() for item in sublist
]
assert old_latest_time_nested_way == [
item for sublist in g.nodes.edges.latest_time.collect() for item in sublist
]
Expand Down
88 changes: 46 additions & 42 deletions python/tests/test_graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ def test_windows_and_layers():
from raphtory.graphql import RaphtoryServer

g_lotr = graph_loader.lotr_graph()
g_lotr.add_constant_properties({"name": "lotr"})
g_layers = Graph()
g_layers.add_constant_properties({"name": "layers"})
g_layers.add_edge(1, 1, 2, layer="layer1")
g_layers.add_edge(1, 2, 3, layer="layer2")
hm = {"lotr": g_lotr, "layers": g_layers}
Expand All @@ -248,11 +250,11 @@ def test_windows_and_layers():
after(time: 500) {
history
neighbours {
list {
name
before(time: 300) {
history
}
list {
name
before(time: 300) {
history
}
}
}
}
Expand All @@ -263,41 +265,41 @@ def test_windows_and_layers():
"""
ra = """
{
"graph": {
"window": {
"node": {
"after": {
"history": [
555,
562
],
"neighbours": {
"list": [
{
"name": "Gandalf",
"before": {
"history": [
270
]
}
},
{
"name": "Bilbo",
"before": {
"history": [
205,
270,
286
]
}
"graph": {
"window": {
"node": {
"after": {
"history": [
555,
562
],
"neighbours": {
"list": [
{
"name": "Gandalf",
"before": {
"history": [
270
]
}
},
{
"name": "Bilbo",
"before": {
"history": [
205,
270,
286
]
}
}
]
}
]
}
}
}
}
}
}
}
"""
a = json.dumps(server.query(q))
json_a = json.loads(a)
Expand Down Expand Up @@ -352,7 +354,7 @@ def test_windows_and_layers():
}
}
}
}
}
"""

a = json.dumps(server.query(q))
Expand All @@ -369,6 +371,7 @@ def test_properties():
from raphtory.graphql import RaphtoryServer

g = Graph()
g.add_constant_properties({"name": "graph"})
g.add_node(
1,
1,
Expand Down Expand Up @@ -402,6 +405,7 @@ def test_properties():
n.add_constant_properties(
{"prop5": "val4", "prop6": "val4", "prop7": "val4", "prop8": "val4"}
)

hm = {"graph": g}
server = RaphtoryServer(hm).start()
server.wait_for_online()
Expand All @@ -410,7 +414,7 @@ def test_properties():
graph(name: "graph") {
nodes {
list{
properties{
properties {
values(keys:["prop1","prop2"]){
key
asString
Expand Down Expand Up @@ -454,15 +458,15 @@ def test_properties():
"temporal": {
"values": [
{
"key": "prop3",
"key": "prop4",
"history": [
1,
2,
3
]
},
{
"key": "prop4",
"key": "prop3",
"history": [
1,
2,
Expand All @@ -474,11 +478,11 @@ def test_properties():
"constant": {
"values": [
{
"key": "prop6",
"key": "prop5",
"value": "val4"
},
{
"key": "prop5",
"key": "prop6",
"value": "val4"
}
]
Expand All @@ -488,7 +492,7 @@ def test_properties():
]
}
}
}
}
"""
s = server.query(q)
json_a = json.loads(json.dumps(s))
Expand Down
8 changes: 5 additions & 3 deletions raphtory-graphql/src/model/graph/edge.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::model::graph::{node::Node, property::GqlProperties};
use async_graphql::Error;
use dynamic_graphql::{ResolvedObject, ResolvedObjectFields};
use itertools::Itertools;
use raphtory::{
core::utils::errors::GraphError,
db::{
api::view::{DynamicGraph, EdgeViewOps, IntoDynamic, StaticGraphViewOps},
graph::edge::EdgeView,
Expand Down Expand Up @@ -94,8 +96,8 @@ impl Edge {
self.ee.history().last().cloned()
}

async fn time(&self) -> Option<i64> {
self.ee.time()
async fn time(&self) -> Result<i64, GraphError> {
self.ee.time().map(|x| x.into())
}

async fn start(&self) -> Option<i64> {
Expand All @@ -122,7 +124,7 @@ impl Edge {
self.ee.layer_names().map(|x| x.into()).collect()
}

async fn layer_name(&self) -> Option<String> {
async fn layer_name(&self) -> Result<String, GraphError> {
self.ee.layer_name().map(|x| x.into())
}

Expand Down
6 changes: 6 additions & 0 deletions raphtory/src/core/utils/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ pub enum GraphError {
"Failed to load the graph as the bincode version {0} is different to installed version {1}"
)]
BincodeVersionError(u32, u32),

#[error("The layer_name function is only available once an edge has been exploded via .explode_layers() or .explode(). If you want to retrieve the layers for this edge you can use .layer_names")]
LayerNameAPIError,

#[error("The time function is only available once an edge has been exploded via .explode(). You may want to retrieve the history for this edge via .history(), or the earliest/latest time via earliest_time or latest_time")]
TimeAPIError,
}

#[derive(thiserror::Error, Debug, PartialEq)]
Expand Down
Loading
Loading