From 0366a1e2a1d22269db887a4ff4d55959a67a44a1 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Tue, 15 Jul 2025 04:17:13 +0300 Subject: [PATCH 1/3] Adding support for /key-generators (#375) --- arango/database.py | 18 ++++++++++++++++++ arango/exceptions.py | 4 ++++ tests/test_database.py | 7 +++++++ 3 files changed, 29 insertions(+) diff --git a/arango/database.py b/arango/database.py index 8a145910..20e771d2 100644 --- a/arango/database.py +++ b/arango/database.py @@ -27,6 +27,7 @@ AsyncJobListError, CollectionCreateError, CollectionDeleteError, + CollectionKeyGeneratorsError, CollectionListError, DatabaseCompactError, DatabaseCreateError, @@ -1623,6 +1624,23 @@ def response_handler(resp: Response) -> bool: return self._execute(request, response_handler) + def key_generators(self) -> Result[List[str]]: + """Returns the available key generators for collections. + + :return: List of available key generators. + :rtype: [str] + :raise arango.exceptions.CollectionKeyGeneratorsError: If retrieval fails. + """ # noqa: E501 + request = Request(method="get", endpoint="/_api/key-generators") + + def response_handler(resp: Response) -> List[str]: + if not resp.is_success: + raise CollectionKeyGeneratorsError(resp, request) + result: List[str] = resp.body["keyGenerators"] + return result + + return self._execute(request, response_handler) + #################### # Graph Management # #################### diff --git a/arango/exceptions.py b/arango/exceptions.py index cdea90c5..789468ed 100644 --- a/arango/exceptions.py +++ b/arango/exceptions.py @@ -298,6 +298,10 @@ class CollectionTruncateError(ArangoServerError): """Failed to truncate collection.""" +class CollectionKeyGeneratorsError(ArangoServerError): + """Failed to retrieve key generators.""" + + class CollectionLoadError(ArangoServerError): """Failed to load collection.""" diff --git a/tests/test_database.py b/tests/test_database.py index d6595a4d..014f0235 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -13,6 +13,7 @@ USE_SYSTEM_DATABASE, ) from arango.exceptions import ( + CollectionKeyGeneratorsError, DatabaseCompactError, DatabaseCreateError, DatabaseDeleteError, @@ -348,6 +349,12 @@ def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret, db_v result = db_superuser.compact() assert result == {} + if db_version >= version.parse("3.12.0"): + key_generators = db.key_generators() + assert isinstance(key_generators, list) + with pytest.raises(CollectionKeyGeneratorsError): + bad_db.key_generators() + def test_database_management(db, sys_db, bad_db): # Test list databases From 08a2e54a69d7b0603bed7552fe0dc715d8632ef0 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Mon, 4 Aug 2025 13:15:43 +0800 Subject: [PATCH 2/3] Deprecate load/unload methods (#376) * Deprecating load method * Deprecating unload method * Minor comment correction --- arango/backup.py | 2 +- arango/collection.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/arango/backup.py b/arango/backup.py index c06e4e15..d82e8e2c 100644 --- a/arango/backup.py +++ b/arango/backup.py @@ -33,7 +33,7 @@ def get(self, backup_id: Optional[str] = None) -> Result[Json]: :type backup_id: str :return: Backup details. :rtype: dict - :raise arango.exceptions.BackupGetError: If delete fails. + :raise arango.exceptions.BackupGetError: If the operation fails. """ request = Request( method="post", diff --git a/arango/collection.py b/arango/collection.py index a48bfd2a..2b13884a 100644 --- a/arango/collection.py +++ b/arango/collection.py @@ -537,10 +537,18 @@ def response_handler(resp: Response) -> Json: def load(self) -> Result[bool]: """Load the collection into memory. + .. note:: + The load function is deprecated from version 3.8.0 onwards and is a + no-op from version 3.9.0 onwards. It should no longer be used, as it + may be removed in a future version of ArangoDB. + :return: True if collection was loaded successfully. :rtype: bool :raise arango.exceptions.CollectionLoadError: If operation fails. """ + m = "The load function is deprecated from version 3.8.0 onwards and is a no-op from version 3.9.0 onwards." # noqa: E501 + warn(m, DeprecationWarning, stacklevel=2) + request = Request(method="put", endpoint=f"/_api/collection/{self.name}/load") def response_handler(resp: Response) -> bool: @@ -553,10 +561,18 @@ def response_handler(resp: Response) -> bool: def unload(self) -> Result[bool]: """Unload the collection from memory. + .. note:: + The unload function is deprecated from version 3.8.0 onwards and is a + no-op from version 3.9.0 onwards. It should no longer be used, as it + may be removed in a future version of ArangoDB. + :return: True if collection was unloaded successfully. :rtype: bool :raise arango.exceptions.CollectionUnloadError: If operation fails. """ + m = "The unload function is deprecated from version 3.8.0 onwards and is a no-op from version 3.9.0 onwards." # noqa: E501 + warn(m, DeprecationWarning, stacklevel=2) + request = Request(method="put", endpoint=f"/_api/collection/{self.name}/unload") def response_handler(resp: Response) -> bool: From 453f74b667c4d634196bed15cba2531957dfa7dd Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Mon, 18 Aug 2025 14:18:03 +0800 Subject: [PATCH 3/3] Getting the driver up-to-date (#377) * Adding missing parts * Bumping driver version --- arango/cluster.py | 2 +- arango/database.py | 23 ++++++++++++++++++++++- arango/exceptions.py | 4 ++++ arango/request.py | 2 +- docs/foxx.rst | 4 ++-- tests/test_database.py | 6 ++++++ 6 files changed, 36 insertions(+), 5 deletions(-) diff --git a/arango/cluster.py b/arango/cluster.py index ea13279d..78fd3ac9 100644 --- a/arango/cluster.py +++ b/arango/cluster.py @@ -261,7 +261,7 @@ def endpoints(self) -> Result[List[str]]: :return: List of endpoints. :rtype: [str] - :raise arango.exceptions.ServerEndpointsError: If retrieval fails. + :raise arango.exceptions.ClusterEndpointsError: If retrieval fails. """ request = Request(method="get", endpoint="/_api/cluster/endpoints") diff --git a/arango/database.py b/arango/database.py index 20e771d2..766161df 100644 --- a/arango/database.py +++ b/arango/database.py @@ -45,6 +45,7 @@ PermissionResetError, PermissionUpdateError, ServerAvailableOptionsGetError, + ServerCheckAvailabilityError, ServerCurrentOptionsGetError, ServerDetailsError, ServerEchoError, @@ -445,7 +446,7 @@ def set_license(self, license: str, force: bool = False) -> Result[Json]: :type force: bool :return: Server license. :rtype: dict - :raise arango.exceptions.ServerLicenseError: If retrieval fails. + :raise arango.exceptions.ServerLicenseSetError: If retrieval fails. """ request = Request( method="put", @@ -481,6 +482,25 @@ def response_handler(resp: Response) -> Json: return self._execute(request, response_handler) + def check_availability(self) -> Result[str]: + """Return ArangoDB server availability mode. + + :return: Server availability mode ("readonly" or "default"). + :rtype: str + :raise arango.exceptions.ServerCheckAvailabilityError: If retrieval fails. + """ + request = Request( + method="get", + endpoint="/_admin/server/availability", + ) + + def response_handler(resp: Response) -> str: + if not resp.is_success: + raise ServerCheckAvailabilityError(resp, request) + return str(resp.body["mode"]) + + return self._execute(request, response_handler) + def compact( self, change_level: Optional[bool] = None, @@ -1069,6 +1089,7 @@ def metrics(self) -> Result[str]: :return: Server metrics in Prometheus format. :rtype: str + :raise arango.exceptions.ServerMetricsError: If operation fails. """ request = Request(method="get", endpoint="/_admin/metrics/v2") diff --git a/arango/exceptions.py b/arango/exceptions.py index 789468ed..891c813e 100644 --- a/arango/exceptions.py +++ b/arango/exceptions.py @@ -654,6 +654,10 @@ class ServerTimeError(ArangoServerError): """Failed to retrieve server system time.""" +class ServerCheckAvailabilityError(ArangoServerError): + """Failed to retrieve server availability mode.""" + + class ServerEchoError(ArangoServerError): """Failed to retrieve details on last request.""" diff --git a/arango/request.py b/arango/request.py index 8735afe6..4bb135a5 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.1" + driver_version = "8.2.2" driver_header = "python-arango/" + driver_version + " (" + flags + ")" normalized_headers: Headers = { "charset": "utf-8", diff --git a/docs/foxx.rst b/docs/foxx.rst index 4f6ce35e..734a3168 100644 --- a/docs/foxx.rst +++ b/docs/foxx.rst @@ -83,9 +83,9 @@ information, refer to `ArangoDB manual`_. foxx.readme(service_mount) foxx.swagger(service_mount) foxx.download(service_mount) - foxx.commit(service_mount) + foxx.commit() foxx.scripts(service_mount) - foxx.run_script(service_mount, 'setup', []) + foxx.run_script(service_mount, 'setup', {}) foxx.run_tests(service_mount, reporter='xunit', output_format='xml') # Delete a service. diff --git a/tests/test_database.py b/tests/test_database.py index 014f0235..4e8a160e 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -20,6 +20,7 @@ DatabaseListError, DatabasePropertiesError, DatabaseSupportInfoError, + ServerCheckAvailabilityError, ServerDetailsError, ServerEchoError, ServerEngineError, @@ -355,6 +356,11 @@ def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret, db_v with pytest.raises(CollectionKeyGeneratorsError): bad_db.key_generators() + with pytest.raises(ServerCheckAvailabilityError): + bad_db.check_availability() + availability = db.check_availability() + assert isinstance(availability, str) + def test_database_management(db, sys_db, bad_db): # Test list databases