Skip to content

Commit d754590

Browse files
committed
Add new parameters for graph API methods
1 parent 2d79c2a commit d754590

File tree

8 files changed

+204
-72
lines changed

8 files changed

+204
-72
lines changed

arango/database.py

+52-14
Original file line numberDiff line numberDiff line change
@@ -701,13 +701,17 @@ def graphs(self):
701701
res = self._conn.get('/_api/gharial')
702702
if res.status_code not in HTTP_OK:
703703
raise GraphListError(res)
704+
704705
return [
705706
{
706-
'name': graph['_key'],
707-
'revision': graph['_rev'],
708-
'edge_definitions': graph['edgeDefinitions'],
709-
'orphan_collections': graph['orphanCollections']
710-
} for graph in map(dict, res.body['graphs'])
707+
'name': record['_key'],
708+
'revision': record['_rev'],
709+
'edge_definitions': record['edgeDefinitions'],
710+
'orphan_collections': record['orphanCollections'],
711+
'smart': record.get('isSmart'),
712+
'smart_field': record.get('smartGraphAttribute'),
713+
'shard_count': record.get('numberOfShards')
714+
} for record in map(dict, res.body['graphs'])
711715
]
712716

713717
def graph(self, name):
@@ -723,7 +727,10 @@ def graph(self, name):
723727
def create_graph(self,
724728
name,
725729
edge_definitions=None,
726-
orphan_collections=None):
730+
orphan_collections=None,
731+
smart=None,
732+
smart_field=None,
733+
shard_count=None):
727734
"""Create a new graph in the database.
728735
729736
An edge definition should look like this:
@@ -736,12 +743,25 @@ def create_graph(self,
736743
'to_collections': ['to_vertex_collection_name']
737744
}
738745
739-
:param name: name of the new graph
746+
:param name: The name of the new graph.
740747
:type name: str | unicode
741-
:param edge_definitions: list of edge definitions
748+
:param edge_definitions: The list of edge definitions.
742749
:type edge_definitions: list
743-
:param orphan_collections: names of additional vertex collections
750+
:param orphan_collections: The names of additional vertex collections.
744751
:type orphan_collections: list
752+
:param smart: Whether or not the graph is smart. Set this to ``True``
753+
to enable sharding (see parameter **smart_field** below). This
754+
parameter only has an effect for the enterprise version of ArangoDB.
755+
:type smart: bool
756+
:param smart_field: The document field used to shard the vertices of
757+
the graph. To use this option, parameter **smart** must be set to
758+
``True`` and every vertex in the graph must contain the smart field.
759+
:type smart_field: str | unicode
760+
:param shard_count: The number of shards used for every collection in
761+
the graph. To use this option, parameter **smart** must be set to
762+
``True`` and every vertex in the graph must contain the smart field.
763+
This number cannot be modified later once set.
764+
:type shard_count: int
745765
:returns: the graph object
746766
:rtype: arango.graph.Graph
747767
:raises arango.exceptions.GraphCreateError: if the graph cannot be
@@ -756,25 +776,43 @@ def create_graph(self,
756776
} for definition in edge_definitions]
757777
if orphan_collections is not None:
758778
data['orphanCollections'] = orphan_collections
779+
if smart is not None:
780+
data['isSmart'] = smart
781+
if smart_field is not None:
782+
data['smartGraphAttribute'] = smart_field
783+
if shard_count is not None:
784+
data['numberOfShards'] = shard_count
759785

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

765-
def delete_graph(self, name, ignore_missing=False):
791+
def delete_graph(self, name, ignore_missing=False, drop_collections=None):
766792
"""Drop the graph of the given name from the database.
767793
768-
:param name: the name of the graph to delete
794+
:param name: The name of the graph to delete/drop.
769795
:type name: str | unicode
770-
:param ignore_missing: ignore HTTP 404
796+
:param ignore_missing: Ignore HTTP 404 (graph not found) from the
797+
server. If this is set to ``True`` an exception is not raised.
771798
:type ignore_missing: bool
772-
:returns: whether the drop was successful
799+
:param drop_collections: Whether to drop the collections of the graph
800+
as well. The collections can only be dropped if they are not in use
801+
by other graphs.
802+
:type drop_collections: bool
803+
:returns: Whether the deletion was successful.
773804
:rtype: bool
774805
:raises arango.exceptions.GraphDeleteError: if the graph cannot be
775806
deleted from the database
776807
"""
777-
res = self._conn.delete('/_api/gharial/{}'.format(name))
808+
params = {}
809+
if drop_collections is not None:
810+
params['dropCollections'] = drop_collections
811+
812+
res = self._conn.delete(
813+
'/_api/gharial/{}'.format(name),
814+
params=params
815+
)
778816
if res.status_code not in HTTP_OK:
779817
if not (res.status_code == 404 and ignore_missing):
780818
raise GraphDeleteError(res)

arango/graph.py

+36-24
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Graph(APIWrapper):
1818
:param connection: ArangoDB connection object
1919
:type connection: arango.connection.Connection
2020
:param name: the name of the graph
21-
:type name: str
21+
:type name: str | unicode
2222
"""
2323

2424
def __init__(self, connection, name):
@@ -41,7 +41,7 @@ def vertex_collection(self, name):
4141
"""Return the vertex collection object.
4242
4343
:param name: the name of the vertex collection
44-
:type name: str
44+
:type name: str | unicode
4545
:returns: the vertex collection object
4646
:rtype: arango.collections.vertex.VertexCollection
4747
"""
@@ -51,7 +51,7 @@ def edge_collection(self, name):
5151
"""Return the edge collection object.
5252
5353
:param name: the name of the edge collection
54-
:type name: str
54+
:type name: str | unicode
5555
:returns: the edge collection object
5656
:rtype: arango.collections.edge.EdgeCollection
5757
"""
@@ -74,11 +74,23 @@ def properties(self):
7474
def handler(res):
7575
if res.status_code not in HTTP_OK:
7676
raise GraphPropertiesError(res)
77-
graph = res.body['graph']
77+
record = res.body['graph']
7878
return {
79-
'id': graph['_id'],
80-
'name': graph['name'],
81-
'revision': graph['_rev']
79+
'id': record['_id'],
80+
'name': record['name'],
81+
'revision': record['_rev'],
82+
'orphan_collections': record['orphanCollections'],
83+
'edge_definitions': [
84+
{
85+
'name': edge_definition['collection'],
86+
'to_collections': edge_definition['to'],
87+
'from_collections': edge_definition['from']
88+
}
89+
for edge_definition in record['edgeDefinitions']
90+
],
91+
'smart': record.get('isSmart'),
92+
'smart_field': record.get('smartGraphAttribute'),
93+
'shard_count': record.get('numberOfShards')
8294
}
8395
return request, handler
8496

@@ -133,7 +145,7 @@ def create_vertex_collection(self, name):
133145
"""Create a vertex collection for the graph.
134146
135147
:param name: the name of the new vertex collection to create
136-
:type name: str
148+
:type name: str | unicode
137149
:returns: the vertex collection object
138150
:rtype: arango.collections.vertex.VertexCollection
139151
:raises arango.exceptions.VertexCollectionCreateError: if the vertex
@@ -157,7 +169,7 @@ def delete_vertex_collection(self, name, purge=False):
157169
"""Remove the vertex collection from the graph.
158170
159171
:param name: the name of the vertex collection to remove
160-
:type name: str
172+
:type name: str | unicode
161173
:param purge: delete the vertex collection completely
162174
:type purge: bool
163175
:returns: whether the operation was successful
@@ -219,7 +231,7 @@ def create_edge_definition(self, name, from_collections, to_collections):
219231
vertex collections, one or more "to" vertex collections.
220232
221233
:param name: the name of the new edge collection
222-
:type name: str
234+
:type name: str | unicode
223235
:param from_collections: the name(s) of the "from" vertex collections
224236
:type from_collections: list
225237
:param to_collections: the names of the "to" vertex collections
@@ -251,7 +263,7 @@ def replace_edge_definition(self, name, from_collections, to_collections):
251263
"""Replace an edge definition in the graph.
252264
253265
:param name: the name of the edge definition to replace
254-
:type name: str
266+
:type name: str | unicode
255267
:param from_collections: the names of the "from" vertex collections
256268
:type from_collections: list
257269
:param to_collections: the names of the "to" vertex collections
@@ -285,7 +297,7 @@ def delete_edge_definition(self, name, purge=False):
285297
"""Remove an edge definition from the graph.
286298
287299
:param name: the name of the edge collection
288-
:type name: str
300+
:type name: str | unicode
289301
:param purge: delete the edge collection completely
290302
:type purge: bool
291303
:returns: whether the operation was successful
@@ -331,20 +343,20 @@ def traverse(self,
331343
332344
:param start_vertex: the collection and the key of the start vertex in
333345
the format ``"collection/key"``
334-
:type start_vertex: str
346+
:type start_vertex: str | unicode
335347
:param direction: ``"outbound"`` (default), ``"inbound"`` or ``"any"``
336-
:type direction: str
348+
:type direction: str | unicode
337349
:param item_order: ``"forward"`` (default) or ``"backward"``
338-
:type item_order: str
350+
:type item_order: str | unicode
339351
:param strategy: ``"dfs"`` or ``"bfs"``
340-
:type strategy: str
352+
:type strategy: str | unicode
341353
:param order: ``"preorder"``, ``"postorder"``, ``"preorder-expander"``
342354
or ``None`` (default)
343-
:type order: str
355+
:type order: str | unicode
344356
:param vertex_uniqueness: ``"global"``, ``"path"`` or ``None``
345-
:type vertex_uniqueness: str
357+
:type vertex_uniqueness: str | unicode
346358
:param edge_uniqueness: ``"global"``, ``"path"`` or ``None``
347-
:type edge_uniqueness: str
359+
:type edge_uniqueness: str | unicode
348360
:param min_depth: the minimum depth of the nodes to visit
349361
:type min_depth: int
350362
:param max_depth: the maximum depth of the nodes to visit
@@ -354,30 +366,30 @@ def traverse(self,
354366
:type max_iter: int
355367
:param init_func: init function in Javascript with signature
356368
``(config, result) -> void``, which is used to initialize values
357-
:type init_func: str
369+
:type init_func: str | unicode
358370
:param sort_func: sort function in Javascript with signature
359371
``(left, right) -> integer``, which returns ``-1`` if ``left <
360372
right``, ``+1`` if ``left > right``, and ``0`` if ``left == right``
361-
:type sort_func: str
373+
:type sort_func: str | unicode
362374
:param filter_func: filter function in Javascript with signature
363375
``(config, vertex, path) -> mixed``, where mixed can be one of four
364376
possible values: ``"exclude"`` (do not visit the vertex),
365377
``"prune"`` (do not follow the edges of the vertex), ``""`` or
366378
``undefined`` (visit the vertex and its edges), or an Array
367379
(any combinations of the ``"mixed"``, ``"prune"``, ``""`` or
368380
``undefined``).
369-
:type filter_func: str
381+
:type filter_func: str | unicode
370382
:param visitor_func: visitor function in Javascript with signature
371383
``(config, result, vertex, path, connected) -> void``, where the
372384
return value is ignored, ``result`` is modified by reference, and
373385
``connected`` is populated only when argument **order** is set to
374386
``"preorder-expander"``
375-
:type visitor_func: str
387+
:type visitor_func: str | unicode
376388
:param expander_func: expander function in Javascript with signature
377389
``(config, vertex, path) -> mixed``, which must return an array of
378390
the connections for vertex where each connection is an object with
379391
attributes edge and vertex
380-
:type expander_func: str
392+
:type expander_func: str | unicode
381393
:returns: the visited edges and vertices
382394
:rtype: dict
383395
:raises arango.exceptions.GraphTraverseError: if the graph traversal

arango/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION = '3.8.0'
1+
VERSION = '3.9.0'

scripts/setup_arangodb.sh

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
44
cd $DIR
55

6-
VERSION=3.1.21
6+
VERSION=3.2.0
77
NAME=ArangoDB-$VERSION
88

99
if [ ! -d "$DIR/$NAME" ]; then
1010
# download ArangoDB
11-
echo "wget http://www.arangodb.org/repositories/travisCI/$NAME.tar.gz"
12-
wget http://www.arangodb.org/repositories/travisCI/$NAME.tar.gz
11+
echo "curl -L -o $NAME.tar.gz https://www.arangodb.org/repositories/travisCI/$NAME.tar.gz"
12+
curl -L -o $NAME.tar.gz https://www.arangodb.org/repositories/travisCI/$NAME.tar.gz
1313
echo "tar zxf $NAME.tar.gz"
1414
tar zvxf $NAME.tar.gz
1515
fi

tests/test_client.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,15 @@ def test_sleep():
123123

124124

125125
def test_execute():
126-
assert arango_client.execute('return 1') == '1'
127-
assert arango_client.execute('return "test"') == '"test"'
128-
with pytest.raises(ServerExecuteError) as err:
129-
arango_client.execute('return invalid')
130-
assert 'Internal Server Error' in err.value.message
126+
major, minor = arango_version(arango_client)
127+
128+
# TODO ArangoDB 3.2 seems to be missing this API endpoint
129+
if not (major == 3 and minor == 2):
130+
assert arango_client.execute('return 1') == '1'
131+
assert arango_client.execute('return "test"') == '"test"'
132+
with pytest.raises(ServerExecuteError) as err:
133+
arango_client.execute('return invalid')
134+
assert 'Internal Server Error' in err.value.message
131135

132136

133137
# TODO test parameters

0 commit comments

Comments
 (0)