Skip to content

Commit

Permalink
new: post /_admin/execute (#309)
Browse files Browse the repository at this point in the history
* new: `Database.execute()`

* fix lint

* fix end of file

* fix: lint
  • Loading branch information
aMahanna authored Jan 26, 2024
1 parent 70548d9 commit 1265881
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 7 deletions.
31 changes: 31 additions & 0 deletions arango/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
ServerEchoError,
ServerEncryptionError,
ServerEngineError,
ServerExecuteError,
ServerLicenseGetError,
ServerLicenseSetError,
ServerLogLevelError,
Expand Down Expand Up @@ -229,6 +230,36 @@ def response_handler(resp: Response) -> Json:

return self._execute(request, response_handler)

def execute(self, command: str) -> Result[Any]:
"""Execute raw Javascript command on the server.
Executes the JavaScript code in the body on the server as
the body of a function with no arguments. If you have a
return statement then the return value you produce will be returned
as 'application/json'.
NOTE: this method endpoint will only be usable if the server
was started with the option `--javascript.allow-admin-execute true`.
The default value of this option is false, which disables the execution
of user-defined code and disables this API endpoint entirely.
This is also the recommended setting for production.
:param command: Javascript command to execute.
:type command: str
:return: Return value of **command**, if any.
:rtype: Any
:raise arango.exceptions.ServerExecuteError: If execution fails.
"""
request = Request(method="post", endpoint="/_admin/execute", data=command)

def response_handler(resp: Response) -> Any:
if not resp.is_success:
raise ServerExecuteError(resp, request)

return resp.body

return self._execute(request, response_handler)

def execute_transaction(
self,
command: str,
Expand Down
4 changes: 4 additions & 0 deletions arango/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,10 @@ class ServerEncryptionError(ArangoServerError):
"""Failed to reload user-defined encryption keys."""


class ServerExecuteError(ArangoServerError):
"""Failed to execute raw JavaScript command."""


#####################
# Task Exceptions #
#####################
Expand Down
16 changes: 9 additions & 7 deletions arango/replication.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,15 @@ def response_handler(resp: Response) -> Json:
if resp.is_success:
result = format_replication_header(resp.headers)
result["content"] = [
[
self._conn.deserialize(line)
for line in resp.body.split("\n")
if line
]
if deserialize
else resp.body
(
[
self._conn.deserialize(line)
for line in resp.body.split("\n")
if line
]
if deserialize
else resp.body
)
]
return result

Expand Down
1 change: 1 addition & 0 deletions tests/static/cluster-3.10.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ jwt-secret = /tests/static/keyfile
[args]
all.database.password = passwd
all.log.api-enabled = true
all.javascript.allow-admin-execute = true
1 change: 1 addition & 0 deletions tests/static/cluster.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ jwt-secret = /tests/static/keyfile
all.database.password = passwd
all.database.extended-names = true
all.log.api-enabled = true
all.javascript.allow-admin-execute = true
1 change: 1 addition & 0 deletions tests/static/single-3.10.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ jwt-secret = /tests/static/keyfile

[args]
all.database.password = passwd
all.javascript.allow-admin-execute = true
1 change: 1 addition & 0 deletions tests/static/single.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ jwt-secret = /tests/static/keyfile
[args]
all.database.password = passwd
all.database.extended-names = true
all.javascript.allow-admin-execute = true
6 changes: 6 additions & 0 deletions tests/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret):
bad_db.engine()
assert err.value.error_code in {11, 1228}

# Test execute JavaScript code
assert db.execute(1) is None
assert db.execute(None) == {"error": False, "code": 200}
assert db.execute("") == {"error": False, "code": 200}
assert db.execute("return 1") == 1

# Test database compact
with assert_raises(DatabaseCompactError) as err:
db.compact()
Expand Down

0 comments on commit 1265881

Please sign in to comment.