-
-
Save versae/1917509 to your computer and use it in GitHub Desktop.
Neo4j REST Traversals Approximating embedded syntax for https://github.com/versae/neo4j-rest-client/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# http://docs.neo4j.org/chunked/snapshot/rest-api-traverse.html#rest-api-traversal-returning-nodes-below-a-certain-depth | |
try: | |
import simplejson as json | |
except ImportError: | |
import json | |
from neo4jrestclient import client | |
from neo4jrestclient.request import Request | |
from neo4jrestclient.request import NotFoundError | |
from neo4jrestclient.request import StatusException | |
class Order(object): | |
BREADTH_FIRST = "breadth_first" | |
DEPTH_FIRST = "depth_first" | |
class Uniqueness(object): | |
NODE_GLOBAL = "node_global" | |
NONE = "none" | |
RELATIONSHIP_GLOBAL = "relationship_global" | |
NODE_PATH = "node_path" | |
RELATIONSHIP_PATH = "relationship_path" | |
class RelationshipDirection(object): | |
ALL = "all" | |
INCOMING = "in" | |
OUTGOING = "out" | |
class Filters(object): | |
"""Filters answer the question (return true/false) | |
Evaluation.INCLUDE_AND_CONTINUE | |
Evaluation.EXCLUDE_AND_CONTINUE | |
""" | |
ALL = {"language":"builtin", "name":"all"} | |
ALL_BUT_START_NODE = {"language":"builtin", "name":"all_but_start_node"} | |
class PruneEvaluators(object): | |
"""PruneEvaluators answer the question (return true/false) | |
Evaluation.INCLUDE_AND_PRUNE | |
Evaluation.EXCLUDE_AND_PRUNE | |
""" | |
pass | |
class Traverser(object): | |
NODE = "node" | |
RELATIONSHIP = "relationship" | |
PATH = "path" | |
FULLPATH = "fullpath" | |
def __init__(self, start_node, data): | |
self._data = data | |
self._endpoint = "http://localhost:7474/db/data/node/" + str(start_node.id) + "/traverse" | |
self._cache = {} | |
def request(self, return_type): | |
try: | |
return self._cache[return_type] | |
except KeyError: | |
response, content = Request().post(self._endpoint + '/' + return_type, data=self._data) | |
if response.status == 200: | |
results_list = json.loads(content) | |
self._cache[return_type] = results_list | |
return results_list | |
elif response.status == 404: | |
raise NotFoundError(response.status, "Node or relationship " \ | |
"not found") | |
raise StatusException(response.status, "Invalid data sent") | |
@property | |
def nodes(self): | |
results = self.request(Traverser.NODE) | |
return client.Iterable(client.Node, results, "self") | |
@property | |
def relationships(self): | |
results = self.request(Traverser.RELATIONSHIP) | |
return client.Iterable(client.Relationship, results, "self") | |
@property | |
def fullpaths(self): | |
raise NotImplementedError() | |
def __iter__(self): | |
results = self.request(Traverser.PATH) | |
return client.Iterable(client.Path, results, "self") | |
class TraversalDescription(object): | |
"""https://github.com/neo4j/community/blob/master/kernel/src/main/java/org/neo4j/graphdb/traversal/TraversalDescription.java""" | |
def __init__(self): | |
self._data = {} | |
self.uniqueness(Uniqueness.NODE_GLOBAL) | |
self.max_depth(1) | |
def uniqueness(self, value): | |
self._data["uniqueness"] = value | |
return self | |
def filter(self, value): | |
try: | |
value["language"] | |
self._data["return_filter"] = value | |
except KeyError: | |
self._data["return_filter"] = {"language":"javascript", "body":value} | |
return self | |
def prune(self, value, language="javascript"): | |
try: | |
value["language"] | |
self._data["prune_evaluator"] = value | |
except KeyError: | |
self._data["prune_evaluator"] = {"language":language, "body":value} | |
def order(self, value): | |
self._data["order"] = value | |
return self | |
def depthFirst(self, value): | |
self.order(Order.DEPTH_FIRST) | |
return self | |
def breadthFirst(self, value): | |
self.order(Order.BREADTH_FIRST) | |
return self | |
def relationships(self, name, direction=RelationshipDirection.ALL): | |
self._data["relationships"] = [] | |
self.relationships_append(name, direction) | |
self.relationships = self.relationships_append | |
return self | |
def relationships_append(self, name, direction=RelationshipDirection.ALL): | |
self._data["relationships"].append({"direction":direction, "type":name}) | |
return self | |
def max_depth(self, value): | |
self._data["max_depth"] = value | |
def traverse(self, start_node): | |
try: | |
self._data['prune_evaluator'] | |
del self._data["max_depth"] | |
except KeyError: | |
pass | |
return Traverser(start_node, self._data) | |
class Traversal(object): | |
def __init__(self, start_node): | |
self._description = Traversal.description() | |
self._start_node = start_node | |
@property | |
def description(self): | |
return self._description | |
def __iter__(self): | |
return self._description.traverse(self._start_node) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment