1__all__ = ["Graph"] 2 3from typing import List, Optional, Sequence, Union 4 5from arango.api import ApiGroup 6from arango.collection import EdgeCollection, VertexCollection 7from arango.connection import Connection 8from arango.exceptions import ( 9 EdgeDefinitionCreateError, 10 EdgeDefinitionDeleteError, 11 EdgeDefinitionListError, 12 EdgeDefinitionReplaceError, 13 GraphPropertiesError, 14 GraphTraverseError, 15 VertexCollectionCreateError, 16 VertexCollectionDeleteError, 17 VertexCollectionListError, 18) 19from arango.executor import ApiExecutor 20from arango.formatter import format_graph_properties 21from arango.request import Request 22from arango.response import Response 23from arango.result import Result 24from arango.typings import Json, Jsons 25from arango.utils import get_col_name, get_doc_id 26 27 28class Graph(ApiGroup): 29 """Graph API wrapper.""" 30 31 def __init__( 32 self, connection: Connection, executor: ApiExecutor, name: str 33 ) -> None: 34 super().__init__(connection, executor) 35 self._name = name 36 37 def __repr__(self) -> str: 38 return f"<Graph {self._name}>" 39 40 def _get_col_by_vertex(self, vertex: Union[str, Json]) -> VertexCollection: 41 """Return the vertex collection for the given vertex document. 42 43 :param vertex: Vertex document ID or body with "_id" field. 44 :type vertex: str | dict 45 :return: Vertex collection API wrapper. 46 :rtype: arango.collection.VertexCollection 47 """ 48 return self.vertex_collection(get_col_name(vertex)) 49 50 def _get_col_by_edge(self, edge: Union[str, Json]) -> EdgeCollection: 51 """Return the edge collection for the given edge document. 52 53 :param edge: Edge document ID or body with "_id" field. 54 :type edge: str | dict 55 :return: Edge collection API wrapper. 56 :rtype: arango.collection.EdgeCollection 57 """ 58 return self.edge_collection(get_col_name(edge)) 59 60 @property 61 def name(self) -> str: 62 """Return the graph name. 63 64 :return: Graph name. 65 :rtype: str 66 """ 67 return self._name 68 69 def properties(self) -> Result[Json]: 70 """Return graph properties. 71 72 :return: Graph properties. 73 :rtype: dict 74 :raise arango.exceptions.GraphPropertiesError: If retrieval fails. 75 """ 76 request = Request(method="get", endpoint=f"/_api/gharial/{self._name}") 77 78 def response_handler(resp: Response) -> Json: 79 if resp.is_success: 80 return format_graph_properties(resp.body["graph"]) 81 raise GraphPropertiesError(resp, request) 82 83 return self._execute(request, response_handler) 84 85 ################################ 86 # Vertex Collection Management # 87 ################################ 88 89 def has_vertex_collection(self, name: str) -> Result[bool]: 90 """Check if the graph has the given vertex collection. 91 92 :param name: Vertex collection name. 93 :type name: str 94 :return: True if vertex collection exists, False otherwise. 95 :rtype: bool 96 """ 97 request = Request( 98 method="get", 99 endpoint=f"/_api/gharial/{self._name}/vertex", 100 ) 101 102 def response_handler(resp: Response) -> bool: 103 if resp.is_success: 104 return name in resp.body["collections"] 105 raise VertexCollectionListError(resp, request) 106 107 return self._execute(request, response_handler) 108 109 def vertex_collections(self) -> Result[List[str]]: 110 """Return vertex collections in the graph that are not orphaned. 111 112 :return: Names of vertex collections that are not orphaned. 113 :rtype: [str] 114 :raise arango.exceptions.VertexCollectionListError: If retrieval fails. 115 """ 116 request = Request( 117 method="get", 118 endpoint=f"/_api/gharial/{self._name}/vertex", 119 ) 120 121 def response_handler(resp: Response) -> List[str]: 122 if not resp.is_success: 123 raise VertexCollectionListError(resp, request) 124 return sorted(set(resp.body["collections"])) 125 126 return self._execute(request, response_handler) 127 128 def vertex_collection(self, name: str) -> VertexCollection: 129 """Return the vertex collection API wrapper. 130 131 :param name: Vertex collection name. 132 :type name: str 133 :return: Vertex collection API wrapper. 134 :rtype: arango.collection.VertexCollection 135 """ 136 return VertexCollection(self._conn, self._executor, self._name, name) 137 138 def create_vertex_collection(self, name: str) -> Result[VertexCollection]: 139 """Create a vertex collection in the graph. 140 141 :param name: Vertex collection name. 142 :type name: str 143 :return: Vertex collection API wrapper. 144 :rtype: arango.collection.VertexCollection 145 :raise arango.exceptions.VertexCollectionCreateError: If create fails. 146 """ 147 request = Request( 148 method="post", 149 endpoint=f"/_api/gharial/{self._name}/vertex", 150 data={"collection": name}, 151 ) 152 153 def response_handler(resp: Response) -> VertexCollection: 154 if resp.is_success: 155 return self.vertex_collection(name) 156 raise VertexCollectionCreateError(resp, request) 157 158 return self._execute(request, response_handler) 159 160 def delete_vertex_collection(self, name: str, purge: bool = False) -> Result[bool]: 161 """Remove a vertex collection from the graph. 162 163 :param name: Vertex collection name. 164 :type name: str 165 :param purge: If set to True, the vertex collection is not just deleted 166 from the graph but also from the database completely. 167 :type purge: bool 168 :return: True if vertex collection was deleted successfully. 169 :rtype: bool 170 :raise arango.exceptions.VertexCollectionDeleteError: If delete fails. 171 """ 172 request = Request( 173 method="delete", 174 endpoint=f"/_api/gharial/{self._name}/vertex/{name}", 175 params={"dropCollection": purge}, 176 ) 177 178 def response_handler(resp: Response) -> bool: 179 if resp.is_success: 180 return True 181 raise VertexCollectionDeleteError(resp, request) 182 183 return self._execute(request, response_handler) 184 185 ############################## 186 # Edge Collection Management # 187 ############################## 188 189 def has_edge_definition(self, name: str) -> Result[bool]: 190 """Check if the graph has the given edge definition. 191 192 :param name: Edge collection name. 193 :type name: str 194 :return: True if edge definition exists, False otherwise. 195 :rtype: bool 196 """ 197 request = Request(method="get", endpoint=f"/_api/gharial/{self._name}") 198 199 def response_handler(resp: Response) -> bool: 200 if not resp.is_success: 201 raise EdgeDefinitionListError(resp, request) 202 203 body = resp.body["graph"] 204 return any( 205 edge_definition["collection"] == name 206 for edge_definition in body["edgeDefinitions"] 207 ) 208 209 return self._execute(request, response_handler) 210 211 def has_edge_collection(self, name: str) -> Result[bool]: 212 """Check if the graph has the given edge collection. 213 214 :param name: Edge collection name. 215 :type name: str 216 :return: True if edge collection exists, False otherwise. 217 :rtype: bool 218 """ 219 return self.has_edge_definition(name) 220 221 def edge_collection(self, name: str) -> EdgeCollection: 222 """Return the edge collection API wrapper. 223 224 :param name: Edge collection name. 225 :type name: str 226 :return: Edge collection API wrapper. 227 :rtype: arango.collection.EdgeCollection 228 """ 229 return EdgeCollection(self._conn, self._executor, self._name, name) 230 231 def edge_definitions(self) -> Result[Jsons]: 232 """Return the edge definitions of the graph. 233 234 :return: Edge definitions of the graph. 235 :rtype: [dict] 236 :raise arango.exceptions.EdgeDefinitionListError: If retrieval fails. 237 """ 238 request = Request(method="get", endpoint=f"/_api/gharial/{self._name}") 239 240 def response_handler(resp: Response) -> Jsons: 241 if not resp.is_success: 242 raise EdgeDefinitionListError(resp, request) 243 244 body = resp.body["graph"] 245 return [ 246 { 247 "edge_collection": edge_definition["collection"], 248 "from_vertex_collections": edge_definition["from"], 249 "to_vertex_collections": edge_definition["to"], 250 } 251 for edge_definition in body["edgeDefinitions"] 252 ] 253 254 return self._execute(request, response_handler) 255 256 def create_edge_definition( 257 self, 258 edge_collection: str, 259 from_vertex_collections: Sequence[str], 260 to_vertex_collections: Sequence[str], 261 ) -> Result[EdgeCollection]: 262 """Create a new edge definition. 263 264 An edge definition consists of an edge collection, "from" vertex 265 collection(s) and "to" vertex collection(s). Here is an example entry: 266 267 .. code-block:: python 268 269 { 270 'edge_collection': 'edge_collection_name', 271 'from_vertex_collections': ['from_vertex_collection_name'], 272 'to_vertex_collections': ['to_vertex_collection_name'] 273 } 274 275 :param edge_collection: Edge collection name. 276 :type edge_collection: str 277 :param from_vertex_collections: Names of "from" vertex collections. 278 :type from_vertex_collections: [str] 279 :param to_vertex_collections: Names of "to" vertex collections. 280 :type to_vertex_collections: [str] 281 :return: Edge collection API wrapper. 282 :rtype: arango.collection.EdgeCollection 283 :raise arango.exceptions.EdgeDefinitionCreateError: If create fails. 284 """ 285 request = Request( 286 method="post", 287 endpoint=f"/_api/gharial/{self._name}/edge", 288 data={ 289 "collection": edge_collection, 290 "from": from_vertex_collections, 291 "to": to_vertex_collections, 292 }, 293 ) 294 295 def response_handler(resp: Response) -> EdgeCollection: 296 if resp.is_success: 297 return self.edge_collection(edge_collection) 298 raise EdgeDefinitionCreateError(resp, request) 299 300 return self._execute(request, response_handler) 301 302 def replace_edge_definition( 303 self, 304 edge_collection: str, 305 from_vertex_collections: Sequence[str], 306 to_vertex_collections: Sequence[str], 307 ) -> Result[EdgeCollection]: 308 """Replace an edge definition. 309 310 :param edge_collection: Edge collection name. 311 :type edge_collection: str 312 :param from_vertex_collections: Names of "from" vertex collections. 313 :type from_vertex_collections: [str] 314 :param to_vertex_collections: Names of "to" vertex collections. 315 :type to_vertex_collections: [str] 316 :return: Edge collection API wrapper. 317 :rtype: arango.collection.EdgeCollection 318 :raise arango.exceptions.EdgeDefinitionReplaceError: If replace fails. 319 """ 320 request = Request( 321 method="put", 322 endpoint=f"/_api/gharial/{self._name}/edge/{edge_collection}", 323 data={ 324 "collection": edge_collection, 325 "from": from_vertex_collections, 326 "to": to_vertex_collections, 327 }, 328 ) 329 330 def response_handler(resp: Response) -> EdgeCollection: 331 if resp.is_success: 332 return self.edge_collection(edge_collection) 333 raise EdgeDefinitionReplaceError(resp, request) 334 335 return self._execute(request, response_handler) 336 337 def delete_edge_definition(self, name: str, purge: bool = False) -> Result[bool]: 338 """Delete an edge definition from the graph. 339 340 :param name: Edge collection name. 341 :type name: str 342 :param purge: If set to True, the edge definition is not just removed 343 from the graph but the edge collection is also deleted completely 344 from the database. 345 :type purge: bool 346 :return: True if edge definition was deleted successfully. 347 :rtype: bool 348 :raise arango.exceptions.EdgeDefinitionDeleteError: If delete fails. 349 """ 350 request = Request( 351 method="delete", 352 endpoint=f"/_api/gharial/{self._name}/edge/{name}", 353 params={"dropCollections": purge}, 354 ) 355 356 def response_handler(resp: Response) -> bool: 357 if resp.is_success: 358 return True 359 raise EdgeDefinitionDeleteError(resp, request) 360 361 return self._execute(request, response_handler) 362 363 ################### 364 # Graph Functions # 365 ################### 366 367 def traverse( 368 self, 369 start_vertex: Union[str, Json], 370 direction: str = "outbound", 371 item_order: str = "forward", 372 strategy: Optional[str] = None, 373 order: Optional[str] = None, 374 edge_uniqueness: Optional[str] = None, 375 vertex_uniqueness: Optional[str] = None, 376 max_iter: Optional[int] = None, 377 min_depth: Optional[int] = None, 378 max_depth: Optional[int] = None, 379 init_func: Optional[str] = None, 380 sort_func: Optional[str] = None, 381 filter_func: Optional[str] = None, 382 visitor_func: Optional[str] = None, 383 expander_func: Optional[str] = None, 384 ) -> Result[Json]: 385 """Traverse the graph and return the visited vertices and edges. 386 387 :param start_vertex: Start vertex document ID or body with "_id" field. 388 :type start_vertex: str | dict 389 :param direction: Traversal direction. Allowed values are "outbound" 390 (default), "inbound" and "any". 391 :type direction: str 392 :param item_order: Item iteration order. Allowed values are "forward" 393 (default) and "backward". 394 :type item_order: str 395 :param strategy: Traversal strategy. Allowed values are "depthfirst" 396 and "breadthfirst". 397 :type strategy: str | None 398 :param order: Traversal order. Allowed values are "preorder", 399 "postorder", and "preorder-expander". 400 :type order: str | None 401 :param edge_uniqueness: Uniqueness for visited edges. Allowed values 402 are "global", "path" or "none". 403 :type edge_uniqueness: str | None 404 :param vertex_uniqueness: Uniqueness for visited vertices. Allowed 405 values are "global", "path" or "none". 406 :type vertex_uniqueness: str | None 407 :param max_iter: If set, halt the traversal after the given number of 408 iterations. This parameter can be used to prevent endless loops in 409 cyclic graphs. 410 :type max_iter: int | None 411 :param min_depth: Minimum depth of the nodes to visit. 412 :type min_depth: int | None 413 :param max_depth: Maximum depth of the nodes to visit. 414 :type max_depth: int | None 415 :param init_func: Initialization function in Javascript with signature 416 ``(config, result) -> void``. This function is used to initialize 417 values in the result. 418 :type init_func: str | None 419 :param sort_func: Sorting function in Javascript with signature 420 ``(left, right) -> integer``, which returns ``-1`` if ``left < 421 right``, ``+1`` if ``left > right`` and ``0`` if ``left == right``. 422 :type sort_func: str | None 423 :param filter_func: Filter function in Javascript with signature 424 ``(config, vertex, path) -> mixed``, where ``mixed`` can have one 425 of the following values (or an array with multiple): "exclude" (do 426 not visit the vertex), "prune" (do not follow the edges of the 427 vertex), or "undefined" (visit the vertex and follow its edges). 428 :type filter_func: str | None 429 :param visitor_func: Visitor function in Javascript with signature 430 ``(config, result, vertex, path, connected) -> void``. The return 431 value is ignored, ``result`` is modified by reference, and 432 ``connected`` is populated only when parameter **order** is set to 433 "preorder-expander". 434 :type visitor_func: str | None 435 :param expander_func: Expander function in Javascript with signature 436 ``(config, vertex, path) -> mixed``. The function must return an 437 array of connections for ``vertex``. Each connection is an object 438 with attributes "edge" and "vertex". 439 :type expander_func: str | None 440 :return: Visited edges and vertices. 441 :rtype: dict 442 :raise arango.exceptions.GraphTraverseError: If traversal fails. 443 """ 444 if strategy is not None: 445 if strategy.lower() == "dfs": 446 strategy = "depthfirst" 447 elif strategy.lower() == "bfs": 448 strategy = "breadthfirst" 449 450 uniqueness = {} 451 if vertex_uniqueness is not None: 452 uniqueness["vertices"] = vertex_uniqueness 453 if edge_uniqueness is not None: 454 uniqueness["edges"] = edge_uniqueness 455 456 data: Json = { 457 "startVertex": get_doc_id(start_vertex), 458 "graphName": self._name, 459 "direction": direction, 460 "strategy": strategy, 461 "order": order, 462 "itemOrder": item_order, 463 "uniqueness": uniqueness or None, 464 "maxIterations": max_iter, 465 "minDepth": min_depth, 466 "maxDepth": max_depth, 467 "init": init_func, 468 "filter": filter_func, 469 "visitor": visitor_func, 470 "sort": sort_func, 471 "expander": expander_func, 472 } 473 request = Request( 474 method="post", 475 endpoint="/_api/traversal", 476 data={k: v for k, v in data.items() if v is not None}, 477 ) 478 479 def response_handler(resp: Response) -> Json: 480 if not resp.is_success: 481 raise GraphTraverseError(resp, request) 482 483 result: Json = resp.body["result"]["visited"] 484 return result 485 486 return self._execute(request, response_handler) 487 488 ##################### 489 # Vertex Management # 490 ##################### 491 492 def has_vertex( 493 self, 494 vertex: Union[str, Json], 495 rev: Optional[str] = None, 496 check_rev: bool = True, 497 ) -> Result[bool]: 498 """Check if the given vertex document exists in the graph. 499 500 :param vertex: Vertex document ID or body with "_id" field. 501 :type vertex: str | dict 502 :param rev: Expected document revision. Overrides the value of "_rev" 503 field in **vertex** if present. 504 :type rev: str | None 505 :param check_rev: If set to True, revision of **vertex** (if given) is 506 compared against the revision of target vertex document. 507 :type check_rev: bool 508 :return: True if vertex document exists, False otherwise. 509 :rtype: bool 510 :raise arango.exceptions.DocumentGetError: If check fails. 511 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 512 """ 513 return self._get_col_by_vertex(vertex).has(vertex, rev, check_rev) 514 515 def vertex( 516 self, 517 vertex: Union[str, Json], 518 rev: Optional[str] = None, 519 check_rev: bool = True, 520 ) -> Result[Optional[Json]]: 521 """Return a vertex document. 522 523 :param vertex: Vertex document ID or body with "_id" field. 524 :type vertex: str | dict 525 :param rev: Expected document revision. Overrides the value of "_rev" 526 field in **vertex** if present. 527 :type rev: str | None 528 :param check_rev: If set to True, revision of **vertex** (if given) is 529 compared against the revision of target vertex document. 530 :type check_rev: bool 531 :return: Vertex document or None if not found. 532 :rtype: dict | None 533 :raise arango.exceptions.DocumentGetError: If retrieval fails. 534 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 535 """ 536 return self._get_col_by_vertex(vertex).get(vertex, rev, check_rev) 537 538 def insert_vertex( 539 self, 540 collection: str, 541 vertex: Json, 542 sync: Optional[bool] = None, 543 silent: bool = False, 544 ) -> Result[Union[bool, Json]]: 545 """Insert a new vertex document. 546 547 :param collection: Vertex collection name. 548 :type collection: str 549 :param vertex: New vertex document to insert. If it has "_key" or "_id" 550 field, its value is used as key of the new vertex (otherwise it is 551 auto-generated). Any "_rev" field is ignored. 552 :type vertex: dict 553 :param sync: Block until operation is synchronized to disk. 554 :type sync: bool | None 555 :param silent: If set to True, no document metadata is returned. This 556 can be used to save resources. 557 :type silent: bool 558 :return: Document metadata (e.g. document key, revision) or True if 559 parameter **silent** was set to True. 560 :rtype: bool | dict 561 :raise arango.exceptions.DocumentInsertError: If insert fails. 562 """ 563 return self.vertex_collection(collection).insert(vertex, sync, silent) 564 565 def update_vertex( 566 self, 567 vertex: Json, 568 check_rev: bool = True, 569 keep_none: bool = True, 570 sync: Optional[bool] = None, 571 silent: bool = False, 572 ) -> Result[Union[bool, Json]]: 573 """Update a vertex document. 574 575 :param vertex: Partial or full vertex document with updated values. It 576 must contain the "_id" field. 577 :type vertex: dict 578 :param check_rev: If set to True, revision of **vertex** (if given) is 579 compared against the revision of target vertex document. 580 :type check_rev: bool 581 :param keep_none: If set to True, fields with value None are retained 582 in the document. If set to False, they are removed completely. 583 :type keep_none: bool 584 :param sync: Block until operation is synchronized to disk. 585 :type sync: bool | None 586 :param silent: If set to True, no document metadata is returned. This 587 can be used to save resources. 588 :type silent: bool 589 :return: Document metadata (e.g. document key, revision) or True if 590 parameter **silent** was set to True. 591 :rtype: bool | dict 592 :raise arango.exceptions.DocumentUpdateError: If update fails. 593 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 594 """ 595 return self._get_col_by_vertex(vertex).update( 596 vertex=vertex, 597 check_rev=check_rev, 598 keep_none=keep_none, 599 sync=sync, 600 silent=silent, 601 ) 602 603 def replace_vertex( 604 self, 605 vertex: Json, 606 check_rev: bool = True, 607 sync: Optional[bool] = None, 608 silent: bool = False, 609 ) -> Result[Union[bool, Json]]: 610 """Replace a vertex document. 611 612 :param vertex: New vertex document to replace the old one with. It must 613 contain the "_id" field. 614 :type vertex: dict 615 :param check_rev: If set to True, revision of **vertex** (if given) is 616 compared against the revision of target vertex document. 617 :type check_rev: bool 618 :param sync: Block until operation is synchronized to disk. 619 :type sync: bool | None 620 :param silent: If set to True, no document metadata is returned. This 621 can be used to save resources. 622 :type silent: bool 623 :return: Document metadata (e.g. document key, revision) or True if 624 parameter **silent** was set to True. 625 :rtype: bool | dict 626 :raise arango.exceptions.DocumentReplaceError: If replace fails. 627 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 628 """ 629 return self._get_col_by_vertex(vertex).replace( 630 vertex=vertex, check_rev=check_rev, sync=sync, silent=silent 631 ) 632 633 def delete_vertex( 634 self, 635 vertex: Json, 636 rev: Optional[str] = None, 637 check_rev: bool = True, 638 ignore_missing: bool = False, 639 sync: Optional[bool] = None, 640 ) -> Result[Union[bool, Json]]: 641 """Delete a vertex document. 642 643 :param vertex: Vertex document ID or body with "_id" field. 644 :type vertex: str | dict 645 :param rev: Expected document revision. Overrides the value of "_rev" 646 field in **vertex** if present. 647 :type rev: str | None 648 :param check_rev: If set to True, revision of **vertex** (if given) is 649 compared against the revision of target vertex document. 650 :type check_rev: bool 651 :param ignore_missing: Do not raise an exception on missing document. 652 This parameter has no effect in transactions where an exception is 653 always raised on failures. 654 :type ignore_missing: bool 655 :param sync: Block until operation is synchronized to disk. 656 :type sync: bool | None 657 :return: True if vertex was deleted successfully, False if vertex was 658 not found and **ignore_missing** was set to True (does not apply in 659 transactions). 660 :rtype: bool 661 :raise arango.exceptions.DocumentDeleteError: If delete fails. 662 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 663 """ 664 return self._get_col_by_vertex(vertex).delete( 665 vertex=vertex, 666 rev=rev, 667 check_rev=check_rev, 668 ignore_missing=ignore_missing, 669 sync=sync, 670 ) 671 672 ################### 673 # Edge Management # 674 ################### 675 676 def has_edge( 677 self, edge: Union[str, Json], rev: Optional[str] = None, check_rev: bool = True 678 ) -> Result[bool]: 679 """Check if the given edge document exists in the graph. 680 681 :param edge: Edge document ID or body with "_id" field. 682 :type edge: str | dict 683 :param rev: Expected document revision. Overrides the value of "_rev" 684 field in **edge** if present. 685 :type rev: str | None 686 :param check_rev: If set to True, revision of **edge** (if given) is 687 compared against the revision of target edge document. 688 :type check_rev: bool 689 :return: True if edge document exists, False otherwise. 690 :rtype: bool 691 :raise arango.exceptions.DocumentInError: If check fails. 692 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 693 """ 694 return self._get_col_by_edge(edge).has(edge, rev, check_rev) 695 696 def edge( 697 self, edge: Union[str, Json], rev: Optional[str] = None, check_rev: bool = True 698 ) -> Result[Optional[Json]]: 699 """Return an edge document. 700 701 :param edge: Edge document ID or body with "_id" field. 702 :type edge: str | dict 703 :param rev: Expected document revision. Overrides the value of "_rev" 704 field in **edge** if present. 705 :type rev: str | None 706 :param check_rev: If set to True, revision of **edge** (if given) is 707 compared against the revision of target edge document. 708 :type check_rev: bool 709 :return: Edge document or None if not found. 710 :rtype: dict | None 711 :raise arango.exceptions.DocumentGetError: If retrieval fails. 712 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 713 """ 714 return self._get_col_by_edge(edge).get(edge, rev, check_rev) 715 716 def insert_edge( 717 self, 718 collection: str, 719 edge: Json, 720 sync: Optional[bool] = None, 721 silent: bool = False, 722 ) -> Result[Union[bool, Json]]: 723 """Insert a new edge document. 724 725 :param collection: Edge collection name. 726 :type collection: str 727 :param edge: New edge document to insert. It must contain "_from" and 728 "_to" fields. If it has "_key" or "_id" field, its value is used 729 as key of the new edge document (otherwise it is auto-generated). 730 Any "_rev" field is ignored. 731 :type edge: dict 732 :param sync: Block until operation is synchronized to disk. 733 :type sync: bool | None 734 :param silent: If set to True, no document metadata is returned. This 735 can be used to save resources. 736 :type silent: bool 737 :return: Document metadata (e.g. document key, revision) or True if 738 parameter **silent** was set to True. 739 :rtype: bool | dict 740 :raise arango.exceptions.DocumentInsertError: If insert fails. 741 """ 742 return self.edge_collection(collection).insert(edge, sync, silent) 743 744 def update_edge( 745 self, 746 edge: Json, 747 check_rev: bool = True, 748 keep_none: bool = True, 749 sync: Optional[bool] = None, 750 silent: bool = False, 751 ) -> Result[Union[bool, Json]]: 752 """Update an edge document. 753 754 :param edge: Partial or full edge document with updated values. It must 755 contain the "_id" field. 756 :type edge: dict 757 :param check_rev: If set to True, revision of **edge** (if given) is 758 compared against the revision of target edge document. 759 :type check_rev: bool 760 :param keep_none: If set to True, fields with value None are retained 761 in the document. If set to False, they are removed completely. 762 :type keep_none: bool | None 763 :param sync: Block until operation is synchronized to disk. 764 :type sync: bool | None 765 :param silent: If set to True, no document metadata is returned. This 766 can be used to save resources. 767 :type silent: bool 768 :return: Document metadata (e.g. document key, revision) or True if 769 parameter **silent** was set to True. 770 :rtype: bool | dict 771 :raise arango.exceptions.DocumentUpdateError: If update fails. 772 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 773 """ 774 return self._get_col_by_edge(edge).update( 775 edge=edge, 776 check_rev=check_rev, 777 keep_none=keep_none, 778 sync=sync, 779 silent=silent, 780 ) 781 782 def replace_edge( 783 self, 784 edge: Json, 785 check_rev: bool = True, 786 sync: Optional[bool] = None, 787 silent: bool = False, 788 ) -> Result[Union[bool, Json]]: 789 """Replace an edge document. 790 791 :param edge: New edge document to replace the old one with. It must 792 contain the "_id" field. It must also contain the "_from" and "_to" 793 fields. 794 :type edge: dict 795 :param check_rev: If set to True, revision of **edge** (if given) is 796 compared against the revision of target edge document. 797 :type check_rev: bool 798 :param sync: Block until operation is synchronized to disk. 799 :type sync: bool | None 800 :param silent: If set to True, no document metadata is returned. This 801 can be used to save resources. 802 :type silent: bool 803 :return: Document metadata (e.g. document key, revision) or True if 804 parameter **silent** was set to True. 805 :rtype: bool | dict 806 :raise arango.exceptions.DocumentReplaceError: If replace fails. 807 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 808 """ 809 return self._get_col_by_edge(edge).replace( 810 edge=edge, check_rev=check_rev, sync=sync, silent=silent 811 ) 812 813 def delete_edge( 814 self, 815 edge: Union[str, Json], 816 rev: Optional[str] = None, 817 check_rev: bool = True, 818 ignore_missing: bool = False, 819 sync: Optional[bool] = None, 820 ) -> Result[Union[bool, Json]]: 821 """Delete an edge document. 822 823 :param edge: Edge document ID or body with "_id" field. 824 :type edge: str | dict 825 :param rev: Expected document revision. Overrides the value of "_rev" 826 field in **edge** if present. 827 :type rev: str | None 828 :param check_rev: If set to True, revision of **edge** (if given) is 829 compared against the revision of target edge document. 830 :type check_rev: bool 831 :param ignore_missing: Do not raise an exception on missing document. 832 This parameter has no effect in transactions where an exception is 833 always raised on failures. 834 :type ignore_missing: bool 835 :param sync: Block until operation is synchronized to disk. 836 :type sync: bool | None 837 :return: True if edge was deleted successfully, False if edge was not 838 found and **ignore_missing** was set to True (does not apply in 839 transactions). 840 :rtype: bool 841 :raise arango.exceptions.DocumentDeleteError: If delete fails. 842 :raise arango.exceptions.DocumentRevisionError: If revisions mismatch. 843 """ 844 return self._get_col_by_edge(edge).delete( 845 edge=edge, 846 rev=rev, 847 check_rev=check_rev, 848 ignore_missing=ignore_missing, 849 sync=sync, 850 ) 851 852 def link( 853 self, 854 collection: str, 855 from_vertex: Union[str, Json], 856 to_vertex: Union[str, Json], 857 data: Optional[Json] = None, 858 sync: Optional[bool] = None, 859 silent: bool = False, 860 ) -> Result[Union[bool, Json]]: 861 """Insert a new edge document linking the given vertices. 862 863 :param collection: Edge collection name. 864 :type collection: str 865 :param from_vertex: "From" vertex document ID or body with "_id" field. 866 :type from_vertex: str | dict 867 :param to_vertex: "To" vertex document ID or body with "_id" field. 868 :type to_vertex: str | dict 869 :param data: Any extra data for the new edge document. If it has "_key" 870 or "_id" field, its value is used as key of the new edge document 871 (otherwise it is auto-generated). 872 :type data: dict 873 :param sync: Block until operation is synchronized to disk. 874 :type sync: bool | None 875 :param silent: If set to True, no document metadata is returned. This 876 can be used to save resources. 877 :type silent: bool 878 :return: Document metadata (e.g. document key, revision) or True if 879 parameter **silent** was set to True. 880 :rtype: bool | dict 881 :raise arango.exceptions.DocumentInsertError: If insert fails. 882 """ 883 return self.edge_collection(collection).link( 884 from_vertex=from_vertex, 885 to_vertex=to_vertex, 886 data=data, 887 sync=sync, 888 silent=silent, 889 ) 890 891 def edges( 892 self, collection: str, vertex: Union[str, Json], direction: Optional[str] = None 893 ) -> Result[Json]: 894 """Return the edge documents coming in and/or out of given vertex. 895 896 :param collection: Edge collection name. 897 :type collection: str 898 :param vertex: Vertex document ID or body with "_id" field. 899 :type vertex: str | dict 900 :param direction: The direction of the edges. Allowed values are "in" 901 and "out". If not set, edges in both directions are returned. 902 :type direction: str 903 :return: List of edges and statistics. 904 :rtype: dict 905 :raise arango.exceptions.EdgeListError: If retrieval fails. 906 """ 907 return self.edge_collection(collection).edges(vertex, direction) 908