-
Notifications
You must be signed in to change notification settings - Fork 0
/
cypher_backend.py
61 lines (48 loc) · 2.21 KB
/
cypher_backend.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from neo4j import GraphDatabase, graph
from neo4j.exceptions import CypherSyntaxError, CypherTypeError, ConstraintError, DriverError, Neo4jError
from .error import ApiError
class CypherBackend:
def __init__(self, config):
self.driver = GraphDatabase.driver(
config["uri"], auth=(config["user"], config["password"]),
connection_timeout=2, # backend should be reachable, so 2s is enough
)
self.timeout = config["timeout"] if "timeout" in config else None
def close(self):
self.driver.close()
def execute(self, cmd):
with self.driver.session() as session:
try:
result = session.run(cmd, timeout=self.timeout)
except (CypherSyntaxError, CypherTypeError, ConstraintError) as error:
raise ApiError(error.message, 400) # Bad Request
except (DriverError, Neo4jError) as error:
# Bad configuration or network error
raise ApiError(type(error).__name__, 503)
except Exception as error:
raise ApiError(error, 500)
return [outputDict(record) for record in result]
def node2dict(node: graph.Node):
props = dict((key, value) for key, value in node.items())
return {'id': node.element_id, 'labels': list(node.labels), 'type': 'node', 'properties': props}
def rs2dict(rs: graph.Relationship):
props = dict((key, value) for key, value in rs.items())
return {
'type': 'edge', 'id': rs.element_id,
'labels': [rs.type], 'properties': props, 'from': rs.start_node.element_id, 'to': rs.end_node.element_id}
def path2dict(path: graph.Path):
nodes = [node2dict(x) for x in path.nodes]
rss = [rs2dict(x) for x in path.relationships]
return {'type': 'graph', 'nodes': nodes, 'edges': rss}
def outputDict(record):
resultDict = {}
for key, value in record.items():
if isinstance(value, graph.Node):
resultDict[key] = node2dict(value)
elif isinstance(value, graph.Relationship):
resultDict[key] = rs2dict(value)
elif isinstance(value, graph.Path):
resultDict[key] = path2dict(value)
else:
resultDict[key] = value
return resultDict