From 9ec5b940c8823fad05228a91026b651d6a23398c Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Fri, 31 Oct 2025 21:37:37 +0800 Subject: [PATCH 1/4] Adding aql-queries endpoint --- arango/aql.py | 18 ++++++++++++++++++ arango/exceptions.py | 4 ++++ starter.sh | 4 ++-- tests/test_aql.py | 9 ++++++++- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/arango/aql.py b/arango/aql.py index 25786302..fdf92f84 100644 --- a/arango/aql.py +++ b/arango/aql.py @@ -17,6 +17,7 @@ AQLQueryClearError, AQLQueryExecuteError, AQLQueryExplainError, + AQLQueryHistoryError, AQLQueryKillError, AQLQueryListError, AQLQueryRulesGetError, @@ -627,6 +628,23 @@ def response_handler(resp: Response) -> Json: return self._execute(request, response_handler) + def history(self) -> Result[Json]: + """Return recently executed AQL queries (admin only). + + :return: AQL query history. + :rtype: dict + :raise arango.exceptions.AQLQueryHistoryError: If retrieval fails. + """ + request = Request(method="get", endpoint="/_admin/server/aql-queries") + + def response_handler(resp: Response) -> Json: + if not resp.is_success: + raise AQLQueryHistoryError(resp, request) + res: Json = resp.body["result"] + return res + + return self._execute(request, response_handler) + def functions(self) -> Result[Jsons]: """List the AQL functions defined in the database. diff --git a/arango/exceptions.py b/arango/exceptions.py index 891c813e..21a157cb 100644 --- a/arango/exceptions.py +++ b/arango/exceptions.py @@ -121,6 +121,10 @@ class AQLQueryTrackingGetError(ArangoServerError): """Failed to retrieve AQL tracking properties.""" +class AQLQueryHistoryError(ArangoServerError): + """Failed to retrieve recent AQL queries.""" + + class AQLQueryTrackingSetError(ArangoServerError): """Failed to configure AQL tracking properties.""" diff --git a/starter.sh b/starter.sh index a5126f54..faf8561f 100755 --- a/starter.sh +++ b/starter.sh @@ -8,8 +8,8 @@ # Example: # ./starter.sh cluster enterprise 3.12.5 -setup="${1:-single}" -license="${2:-community}" +setup="${1:-cluster}" +license="${2:-enterprise}" version="${3:-latest}" extra_ports="" diff --git a/tests/test_aql.py b/tests/test_aql.py index 6c1d3ea3..f4074d63 100644 --- a/tests/test_aql.py +++ b/tests/test_aql.py @@ -13,6 +13,7 @@ AQLQueryClearError, AQLQueryExecuteError, AQLQueryExplainError, + AQLQueryHistoryError, AQLQueryKillError, AQLQueryListError, AQLQueryTrackingGetError, @@ -30,7 +31,7 @@ def test_aql_attributes(db, username): assert repr(db.aql.cache) == f"" -def test_aql_query_management(db_version, db, bad_db, col, docs): +def test_aql_query_management(db_version, db, sys_db, bad_db, col, docs): explain_fields = [ "estimatedNrItems", "estimatedCost", @@ -192,6 +193,12 @@ def test_aql_query_management(db_version, db, bad_db, col, docs): db.begin_async_execution().aql.execute("RETURN SLEEP(100)") db.begin_async_execution().aql.execute("RETURN SLEEP(50)") + # Test query history + with assert_raises(AQLQueryHistoryError): + bad_db.aql.history() + history = sys_db.aql.history() + assert isinstance(history, dict) + # Test list queries queries = db.aql.queries() for query in queries: From 4334b0f9bc371042d58c6cf8ad6871398bcfa963 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Fri, 31 Oct 2025 21:48:19 +0800 Subject: [PATCH 2/4] Adding api-calls endpoint --- arango/database.py | 21 +++++++++++++++++++++ arango/exceptions.py | 4 ++++ tests/test_database.py | 7 +++++++ 3 files changed, 32 insertions(+) diff --git a/arango/database.py b/arango/database.py index 766161df..d1e3bb8a 100644 --- a/arango/database.py +++ b/arango/database.py @@ -44,6 +44,7 @@ PermissionListError, PermissionResetError, PermissionUpdateError, + ServerAPICallsError, ServerAvailableOptionsGetError, ServerCheckAvailabilityError, ServerCurrentOptionsGetError, @@ -463,6 +464,26 @@ def response_handler(resp: Response) -> Json: return self._execute(request, response_handler) + def api_calls(self) -> Result[Json]: + """Return recent API calls. + + :return: API calls history. + :rtype: dict + :raise arango.exceptions.ServerAPICallsError: If retrieval fails. + """ + request = Request( + method="get", + endpoint="/_admin/server/api-calls", + ) + + def response_handler(resp: Response) -> Json: + if not resp.is_success: + raise ServerAPICallsError(resp, request) + res: Json = resp.body["result"] + return res + + return self._execute(request, response_handler) + def status(self) -> Result[Json]: """Return ArangoDB server status. diff --git a/arango/exceptions.py b/arango/exceptions.py index 21a157cb..7fc62983 100644 --- a/arango/exceptions.py +++ b/arango/exceptions.py @@ -642,6 +642,10 @@ class ServerDetailsError(ArangoServerError): """Failed to retrieve server details.""" +class ServerAPICallsError(ArangoServerError): + """Failed to retrieve recent API calls.""" + + class ServerLicenseGetError(ArangoServerError): """Failed to retrieve server license.""" diff --git a/tests/test_database.py b/tests/test_database.py index 4e8a160e..1006df3b 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -20,6 +20,7 @@ DatabaseListError, DatabasePropertiesError, DatabaseSupportInfoError, + ServerAPICallsError, ServerCheckAvailabilityError, ServerDetailsError, ServerEchoError, @@ -314,6 +315,12 @@ def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret, db_v with assert_raises(ServerLogLevelResetError): bad_db.reset_log_levels() + # Test api calls history + with assert_raises(ServerAPICallsError): + bad_db.api_calls() + history = sys_db.api_calls() + assert isinstance(history, dict) + # Test get storage engine engine = db.engine() assert engine["name"] in ["rocksdb"] From af2faea460df91d8ff16c0b1cce00484804bd909 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Fri, 31 Oct 2025 21:49:50 +0800 Subject: [PATCH 3/4] bumped driver version --- arango/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arango/request.py b/arango/request.py index 4bb135a5..1c0e6ccb 100644 --- a/arango/request.py +++ b/arango/request.py @@ -12,7 +12,7 @@ def normalize_headers( if driver_flags is not None: for flag in driver_flags: flags = flags + flag + ";" - driver_version = "8.2.2" + driver_version = "8.2.3" driver_header = "python-arango/" + driver_version + " (" + flags + ")" normalized_headers: Headers = { "charset": "utf-8", From af98fe91776609f9164946ba3c1ed53faa0ad81c Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Fri, 31 Oct 2025 21:51:12 +0800 Subject: [PATCH 4/4] bumped driver version --- arango/database.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arango/database.py b/arango/database.py index d1e3bb8a..130b7b5a 100644 --- a/arango/database.py +++ b/arango/database.py @@ -465,7 +465,7 @@ def response_handler(resp: Response) -> Json: return self._execute(request, response_handler) def api_calls(self) -> Result[Json]: - """Return recent API calls. + """Return recent API calls (admin only). :return: API calls history. :rtype: dict