arangodb / python-arango

The official ArangoDB Python driver.
https://docs.python-arango.com
MIT License
446 stars 74 forks source link

`arango.exceptions.GraphTraverseError: [HTTP 404][ERR 404] unknown path '/_api/traversal'` when using `traverse` (arangodb 3.12) #333

Closed tomchop closed 6 months ago

tomchop commented 7 months ago

(running python 3.10) We recently upgraded to arangodb 3.12 and now calling traverse() yields the following error:

Traceback (most recent call last):
  File "/app/test.py", line 47, in <module>
    result = graph.traverse(
  File "/root/.cache/pypoetry/virtualenvs/yeti-9TtSrW0h-py3.10/lib/python3.10/site-packages/arango/graph.py", line 486, in traverse
    return self._execute(request, response_handler)
  File "/root/.cache/pypoetry/virtualenvs/yeti-9TtSrW0h-py3.10/lib/python3.10/site-packages/arango/api.py", line 74, in _execute
    return self._executor.execute(request, response_handler)
  File "/root/.cache/pypoetry/virtualenvs/yeti-9TtSrW0h-py3.10/lib/python3.10/site-packages/arango/executor.py", line 66, in execute
    return response_handler(resp)
  File "/root/.cache/pypoetry/virtualenvs/yeti-9TtSrW0h-py3.10/lib/python3.10/site-packages/arango/graph.py", line 481, in response_handler
    raise GraphTraverseError(resp, request)
arango.exceptions.GraphTraverseError: [HTTP 404][ERR 404] unknown path '/_api/traversal'

Looks like the endpoint was deprecated: https://docs.arangodb.com/3.12/release-notes/version-3.12/api-changes-in-3-12/#javascript-based-traversal-using-_apitraversal

You can reproduce this by running the python code from the readme:

from arango import ArangoClient

# Initialize the client for ArangoDB.
client = ArangoClient(hosts="http://arangodb:8529")

sys_db = client.db("_system", username="root", password="")
sys_db.delete_database("test")
sys_db.create_database("test")

# Connect to "test" database as root user.

db = client.db("test", username="root", password="")

# Create a new graph named "school".
graph = db.create_graph("school")

# Create vertex collections for the graph.
students = graph.create_vertex_collection("students")
lectures = graph.create_vertex_collection("lectures")

# Create an edge definition (relation) for the graph.
edges = graph.create_edge_definition(
    edge_collection="register",
    from_vertex_collections=["students"],
    to_vertex_collections=["lectures"]
)

# Insert vertex documents into "students" (from) vertex collection.
students.insert({"_key": "01", "full_name": "Anna Smith"})
students.insert({"_key": "02", "full_name": "Jake Clark"})
students.insert({"_key": "03", "full_name": "Lisa Jones"})

# Insert vertex documents into "lectures" (to) vertex collection.
lectures.insert({"_key": "MAT101", "title": "Calculus"})
lectures.insert({"_key": "STA101", "title": "Statistics"})
lectures.insert({"_key": "CSC101", "title": "Algorithms"})

# Insert edge documents into "register" edge collection.
edges.insert({"_from": "students/01", "_to": "lectures/MAT101"})
edges.insert({"_from": "students/01", "_to": "lectures/STA101"})
edges.insert({"_from": "students/01", "_to": "lectures/CSC101"})
edges.insert({"_from": "students/02", "_to": "lectures/MAT101"})
edges.insert({"_from": "students/02", "_to": "lectures/STA101"})
edges.insert({"_from": "students/03", "_to": "lectures/CSC101"})

# Traverse the graph in outbound direction, breadth-first.
result = graph.traverse(
    start_vertex="students/01",
    direction="outbound",
    strategy="breadthfirst"
)
apetenchea commented 6 months ago

Hey @tomchop,

Indeed, that was long deprecated since 3.4, thanks for pointing that out! Ideally, we would've emitted a warning from the driver, but this one slipped past, sorry about that. Right now, since the method has been completely removed from the main ArangoDB implementation, there's not much the driver can do. However, the functionality of the traversal method can be replaced by an AQL query.

For now, we will be replacing the documentation examples (and readme) accordingly in this PR: https://github.com/arangodb/python-arango/pull/335 It should at least give you some idea on how to work around it. Later on, if we find the resources, we might try to come up with a more generic AQL query which can be wrapped by this method.

tomchop commented 6 months ago

Excellent, thanks for the pointers! Fortunately the migration to AQL was fairly straightforward in our case.