Skip to content

Commit

Permalink
Add new parameters for graph API methods
Browse files Browse the repository at this point in the history
  • Loading branch information
joowani committed Jul 23, 2017
1 parent 2d79c2a commit d754590
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 72 deletions.
66 changes: 52 additions & 14 deletions arango/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -701,13 +701,17 @@ def graphs(self):
res = self._conn.get('/_api/gharial')
if res.status_code not in HTTP_OK:
raise GraphListError(res)

return [
{
'name': graph['_key'],
'revision': graph['_rev'],
'edge_definitions': graph['edgeDefinitions'],
'orphan_collections': graph['orphanCollections']
} for graph in map(dict, res.body['graphs'])
'name': record['_key'],
'revision': record['_rev'],
'edge_definitions': record['edgeDefinitions'],
'orphan_collections': record['orphanCollections'],
'smart': record.get('isSmart'),
'smart_field': record.get('smartGraphAttribute'),
'shard_count': record.get('numberOfShards')
} for record in map(dict, res.body['graphs'])
]

def graph(self, name):
Expand All @@ -723,7 +727,10 @@ def graph(self, name):
def create_graph(self,
name,
edge_definitions=None,
orphan_collections=None):
orphan_collections=None,
smart=None,
smart_field=None,
shard_count=None):
"""Create a new graph in the database.
An edge definition should look like this:
Expand All @@ -736,12 +743,25 @@ def create_graph(self,
'to_collections': ['to_vertex_collection_name']
}
:param name: name of the new graph
:param name: The name of the new graph.
:type name: str | unicode
:param edge_definitions: list of edge definitions
:param edge_definitions: The list of edge definitions.
:type edge_definitions: list
:param orphan_collections: names of additional vertex collections
:param orphan_collections: The names of additional vertex collections.
:type orphan_collections: list
:param smart: Whether or not the graph is smart. Set this to ``True``
to enable sharding (see parameter **smart_field** below). This
parameter only has an effect for the enterprise version of ArangoDB.
:type smart: bool
:param smart_field: The document field used to shard the vertices of
the graph. To use this option, parameter **smart** must be set to
``True`` and every vertex in the graph must contain the smart field.
:type smart_field: str | unicode
:param shard_count: The number of shards used for every collection in
the graph. To use this option, parameter **smart** must be set to
``True`` and every vertex in the graph must contain the smart field.
This number cannot be modified later once set.
:type shard_count: int
:returns: the graph object
:rtype: arango.graph.Graph
:raises arango.exceptions.GraphCreateError: if the graph cannot be
Expand All @@ -756,25 +776,43 @@ def create_graph(self,
} for definition in edge_definitions]
if orphan_collections is not None:
data['orphanCollections'] = orphan_collections
if smart is not None:
data['isSmart'] = smart
if smart_field is not None:
data['smartGraphAttribute'] = smart_field
if shard_count is not None:
data['numberOfShards'] = shard_count

res = self._conn.post('/_api/gharial', data=data)
if res.status_code not in HTTP_OK:
raise GraphCreateError(res)
return Graph(self._conn, name)

def delete_graph(self, name, ignore_missing=False):
def delete_graph(self, name, ignore_missing=False, drop_collections=None):
"""Drop the graph of the given name from the database.
:param name: the name of the graph to delete
:param name: The name of the graph to delete/drop.
:type name: str | unicode
:param ignore_missing: ignore HTTP 404
:param ignore_missing: Ignore HTTP 404 (graph not found) from the
server. If this is set to ``True`` an exception is not raised.
:type ignore_missing: bool
:returns: whether the drop was successful
:param drop_collections: Whether to drop the collections of the graph
as well. The collections can only be dropped if they are not in use
by other graphs.
:type drop_collections: bool
:returns: Whether the deletion was successful.
:rtype: bool
:raises arango.exceptions.GraphDeleteError: if the graph cannot be
deleted from the database
"""
res = self._conn.delete('/_api/gharial/{}'.format(name))
params = {}
if drop_collections is not None:
params['dropCollections'] = drop_collections

res = self._conn.delete(
'/_api/gharial/{}'.format(name),
params=params
)
if res.status_code not in HTTP_OK:
if not (res.status_code == 404 and ignore_missing):
raise GraphDeleteError(res)
Expand Down
60 changes: 36 additions & 24 deletions arango/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Graph(APIWrapper):
:param connection: ArangoDB connection object
:type connection: arango.connection.Connection
:param name: the name of the graph
:type name: str
:type name: str | unicode
"""

def __init__(self, connection, name):
Expand All @@ -41,7 +41,7 @@ def vertex_collection(self, name):
"""Return the vertex collection object.
:param name: the name of the vertex collection
:type name: str
:type name: str | unicode
:returns: the vertex collection object
:rtype: arango.collections.vertex.VertexCollection
"""
Expand All @@ -51,7 +51,7 @@ def edge_collection(self, name):
"""Return the edge collection object.
:param name: the name of the edge collection
:type name: str
:type name: str | unicode
:returns: the edge collection object
:rtype: arango.collections.edge.EdgeCollection
"""
Expand All @@ -74,11 +74,23 @@ def properties(self):
def handler(res):
if res.status_code not in HTTP_OK:
raise GraphPropertiesError(res)
graph = res.body['graph']
record = res.body['graph']
return {
'id': graph['_id'],
'name': graph['name'],
'revision': graph['_rev']
'id': record['_id'],
'name': record['name'],
'revision': record['_rev'],
'orphan_collections': record['orphanCollections'],
'edge_definitions': [
{
'name': edge_definition['collection'],
'to_collections': edge_definition['to'],
'from_collections': edge_definition['from']
}
for edge_definition in record['edgeDefinitions']
],
'smart': record.get('isSmart'),
'smart_field': record.get('smartGraphAttribute'),
'shard_count': record.get('numberOfShards')
}
return request, handler

Expand Down Expand Up @@ -133,7 +145,7 @@ def create_vertex_collection(self, name):
"""Create a vertex collection for the graph.
:param name: the name of the new vertex collection to create
:type name: str
:type name: str | unicode
:returns: the vertex collection object
:rtype: arango.collections.vertex.VertexCollection
:raises arango.exceptions.VertexCollectionCreateError: if the vertex
Expand All @@ -157,7 +169,7 @@ def delete_vertex_collection(self, name, purge=False):
"""Remove the vertex collection from the graph.
:param name: the name of the vertex collection to remove
:type name: str
:type name: str | unicode
:param purge: delete the vertex collection completely
:type purge: bool
:returns: whether the operation was successful
Expand Down Expand Up @@ -219,7 +231,7 @@ def create_edge_definition(self, name, from_collections, to_collections):
vertex collections, one or more "to" vertex collections.
:param name: the name of the new edge collection
:type name: str
:type name: str | unicode
:param from_collections: the name(s) of the "from" vertex collections
:type from_collections: list
:param to_collections: the names of the "to" vertex collections
Expand Down Expand Up @@ -251,7 +263,7 @@ def replace_edge_definition(self, name, from_collections, to_collections):
"""Replace an edge definition in the graph.
:param name: the name of the edge definition to replace
:type name: str
:type name: str | unicode
:param from_collections: the names of the "from" vertex collections
:type from_collections: list
:param to_collections: the names of the "to" vertex collections
Expand Down Expand Up @@ -285,7 +297,7 @@ def delete_edge_definition(self, name, purge=False):
"""Remove an edge definition from the graph.
:param name: the name of the edge collection
:type name: str
:type name: str | unicode
:param purge: delete the edge collection completely
:type purge: bool
:returns: whether the operation was successful
Expand Down Expand Up @@ -331,20 +343,20 @@ def traverse(self,
:param start_vertex: the collection and the key of the start vertex in
the format ``"collection/key"``
:type start_vertex: str
:type start_vertex: str | unicode
:param direction: ``"outbound"`` (default), ``"inbound"`` or ``"any"``
:type direction: str
:type direction: str | unicode
:param item_order: ``"forward"`` (default) or ``"backward"``
:type item_order: str
:type item_order: str | unicode
:param strategy: ``"dfs"`` or ``"bfs"``
:type strategy: str
:type strategy: str | unicode
:param order: ``"preorder"``, ``"postorder"``, ``"preorder-expander"``
or ``None`` (default)
:type order: str
:type order: str | unicode
:param vertex_uniqueness: ``"global"``, ``"path"`` or ``None``
:type vertex_uniqueness: str
:type vertex_uniqueness: str | unicode
:param edge_uniqueness: ``"global"``, ``"path"`` or ``None``
:type edge_uniqueness: str
:type edge_uniqueness: str | unicode
:param min_depth: the minimum depth of the nodes to visit
:type min_depth: int
:param max_depth: the maximum depth of the nodes to visit
Expand All @@ -354,30 +366,30 @@ def traverse(self,
:type max_iter: int
:param init_func: init function in Javascript with signature
``(config, result) -> void``, which is used to initialize values
:type init_func: str
:type init_func: str | unicode
:param sort_func: sort function in Javascript with signature
``(left, right) -> integer``, which returns ``-1`` if ``left <
right``, ``+1`` if ``left > right``, and ``0`` if ``left == right``
:type sort_func: str
:type sort_func: str | unicode
:param filter_func: filter function in Javascript with signature
``(config, vertex, path) -> mixed``, where mixed can be one of four
possible values: ``"exclude"`` (do not visit the vertex),
``"prune"`` (do not follow the edges of the vertex), ``""`` or
``undefined`` (visit the vertex and its edges), or an Array
(any combinations of the ``"mixed"``, ``"prune"``, ``""`` or
``undefined``).
:type filter_func: str
:type filter_func: str | unicode
:param visitor_func: visitor function in Javascript with signature
``(config, result, vertex, path, connected) -> void``, where the
return value is ignored, ``result`` is modified by reference, and
``connected`` is populated only when argument **order** is set to
``"preorder-expander"``
:type visitor_func: str
:type visitor_func: str | unicode
:param expander_func: expander function in Javascript with signature
``(config, vertex, path) -> mixed``, which must return an array of
the connections for vertex where each connection is an object with
attributes edge and vertex
:type expander_func: str
:type expander_func: str | unicode
:returns: the visited edges and vertices
:rtype: dict
:raises arango.exceptions.GraphTraverseError: if the graph traversal
Expand Down
2 changes: 1 addition & 1 deletion arango/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = '3.8.0'
VERSION = '3.9.0'
6 changes: 3 additions & 3 deletions scripts/setup_arangodb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR

VERSION=3.1.21
VERSION=3.2.0
NAME=ArangoDB-$VERSION

if [ ! -d "$DIR/$NAME" ]; then
# download ArangoDB
echo "wget http://www.arangodb.org/repositories/travisCI/$NAME.tar.gz"
wget http://www.arangodb.org/repositories/travisCI/$NAME.tar.gz
echo "curl -L -o $NAME.tar.gz https://www.arangodb.org/repositories/travisCI/$NAME.tar.gz"
curl -L -o $NAME.tar.gz https://www.arangodb.org/repositories/travisCI/$NAME.tar.gz
echo "tar zxf $NAME.tar.gz"
tar zvxf $NAME.tar.gz
fi
Expand Down
14 changes: 9 additions & 5 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,15 @@ def test_sleep():


def test_execute():
assert arango_client.execute('return 1') == '1'
assert arango_client.execute('return "test"') == '"test"'
with pytest.raises(ServerExecuteError) as err:
arango_client.execute('return invalid')
assert 'Internal Server Error' in err.value.message
major, minor = arango_version(arango_client)

# TODO ArangoDB 3.2 seems to be missing this API endpoint
if not (major == 3 and minor == 2):
assert arango_client.execute('return 1') == '1'
assert arango_client.execute('return "test"') == '"test"'
with pytest.raises(ServerExecuteError) as err:
arango_client.execute('return invalid')
assert 'Internal Server Error' in err.value.message


# TODO test parameters
Expand Down
Loading

0 comments on commit d754590

Please sign in to comment.