Skip to content

Commit c42c54d

Browse files
committed
Merge branch 'main' into DE-741
2 parents 85e1266 + d5d867c commit c42c54d

40 files changed

+1204
-164
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ workflows:
1515
python_version: ["3.8", "3.9", "3.10", "3.11"] # "3.12"
1616
arangodb_config: ["single", "cluster"]
1717
arangodb_license: ["community", "enterprise"]
18-
arangodb_version: ["3.10.10", "3.11.4", "latest"]
18+
arangodb_version: ["3.11", "latest"]
1919

2020
jobs:
2121
lint:

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
![Logo](https://user-images.githubusercontent.com/2701938/108583516-c3576680-72ee-11eb-883f-2d9b52e74e45.png)
22

3-
[![CircleCI](https://dl.circleci.com/status-badge/img/gh/ArangoDB-Community/python-arango/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/ArangoDB-Community/python-arango/tree/main)
4-
[![CodeQL](https://github.com/ArangoDB-Community/python-arango/actions/workflows/codeql.yaml/badge.svg)](https://github.com/ArangoDB-Community/python-arango/actions/workflows/codeql.yaml)
5-
[![Docs](https://github.com/ArangoDB-Community/python-arango/actions/workflows/docs.yaml/badge.svg)](https://github.com/ArangoDB-Community/python-arango/actions/workflows/docs.yaml)
6-
[![Coverage Status](https://codecov.io/gh/ArangoDB-Community/python-arango/branch/main/graph/badge.svg?token=M8zrjrzsUY)](https://codecov.io/gh/ArangoDB-Community/python-arango)
7-
[![Last commit](https://img.shields.io/github/last-commit/ArangoDB-Community/python-arango)](https://github.com/ArangoDB-Community/python-arango/commits/master)
3+
[![CircleCI](https://dl.circleci.com/status-badge/img/gh/arangodb/python-arango/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/arangodb/python-arango/tree/main)
4+
[![CodeQL](https://github.com/arangodb/python-arango/actions/workflows/codeql.yaml/badge.svg)](https://github.com/arangodb/python-arango/actions/workflows/codeql.yaml)
5+
[![Docs](https://github.com/arangodb/python-arango/actions/workflows/docs.yaml/badge.svg)](https://github.com/arangodb/python-arango/actions/workflows/docs.yaml)
6+
[![Coverage Status](https://codecov.io/gh/arangodb/python-arango/branch/main/graph/badge.svg?token=M8zrjrzsUY)](https://codecov.io/gh/arangodb/python-arango)
7+
[![Last commit](https://img.shields.io/github/last-commit/arangodb/python-arango)](https://github.com/arangodb/python-arango/commits/master)
88

99
[![PyPI version badge](https://img.shields.io/pypi/v/python-arango?color=3775A9&style=for-the-badge&logo=pypi&logoColor=FFD43B)](https://pypi.org/project/python-arango/)
1010
[![Python versions badge](https://img.shields.io/badge/3.8%2B-3776AB?style=for-the-badge&logo=python&logoColor=FFD43B&label=Python)](https://pypi.org/project/python-arango/)
1111

12-
[![License](https://img.shields.io/github/license/ArangoDB-Community/python-arango?color=9E2165&style=for-the-badge)](https://github.com/ArangoDB-Community/python-arango/blob/master/LICENSE)
12+
[![License](https://img.shields.io/github/license/arangodb/python-arango?color=9E2165&style=for-the-badge)](https://github.com/arangodb/python-arango/blob/master/LICENSE)
1313
[![Code style: black](https://img.shields.io/static/v1?style=for-the-badge&label=code%20style&message=black&color=black)](https://github.com/psf/black)
1414
[![Downloads](https://img.shields.io/pepy/dt/python-arango?style=for-the-badge&color=282661
1515
)](https://pepy.tech/project/python-arango)
@@ -21,7 +21,7 @@ database natively supporting documents, graphs and search.
2121

2222
## Requirements
2323

24-
- ArangoDB version 3.9+
24+
- ArangoDB version 3.11+
2525
- Python version 3.8+
2626

2727
## Installation

arango/client.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@
1313
)
1414
from arango.database import StandardDatabase
1515
from arango.exceptions import ServerConnectionError
16-
from arango.http import DEFAULT_REQUEST_TIMEOUT, DefaultHTTPClient, HTTPClient
16+
from arango.http import (
17+
DEFAULT_REQUEST_TIMEOUT,
18+
DefaultHTTPClient,
19+
HTTPClient,
20+
RequestCompression,
21+
)
1722
from arango.resolver import (
1823
FallbackHostResolver,
1924
HostResolver,
@@ -33,7 +38,7 @@ def default_serializer(x: Any) -> str:
3338
:return: The object serialized as a JSON string
3439
:rtype: str
3540
"""
36-
return dumps(x)
41+
return dumps(x, separators=(",", ":"))
3742

3843

3944
def default_deserializer(x: str) -> Any:
@@ -85,6 +90,12 @@ class ArangoClient:
8590
None: No timeout.
8691
int: Timeout value in seconds.
8792
:type request_timeout: int | float
93+
:param request_compression: Will compress requests to the server according to
94+
the given algorithm. No compression happens by default.
95+
:type request_compression: arango.http.RequestCompression | None
96+
:param response_compression: Tells the server what compression algorithm is
97+
acceptable for the response. No compression happens by default.
98+
:type response_compression: str | None
8899
"""
89100

90101
def __init__(
@@ -97,6 +108,8 @@ def __init__(
97108
deserializer: Callable[[str], Any] = default_deserializer,
98109
verify_override: Union[bool, str, None] = None,
99110
request_timeout: Union[int, float, None] = DEFAULT_REQUEST_TIMEOUT,
111+
request_compression: Optional[RequestCompression] = None,
112+
response_compression: Optional[str] = None,
100113
) -> None:
101114
if isinstance(hosts, str):
102115
self._hosts = [host.strip("/") for host in hosts.split(",")]
@@ -133,6 +146,9 @@ def __init__(
133146
for session in self._sessions:
134147
session.verify = verify_override
135148

149+
self._request_compression = request_compression
150+
self._response_compression = response_compression
151+
136152
def __repr__(self) -> str:
137153
return f"<ArangoClient {','.join(self._hosts)}>"
138154

@@ -231,6 +247,8 @@ def db(
231247
serializer=self._serializer,
232248
deserializer=self._deserializer,
233249
superuser_token=superuser_token,
250+
request_compression=self._request_compression,
251+
response_compression=self._response_compression,
234252
)
235253
elif user_token is not None:
236254
connection = JwtConnection(
@@ -242,6 +260,8 @@ def db(
242260
serializer=self._serializer,
243261
deserializer=self._deserializer,
244262
user_token=user_token,
263+
request_compression=self._request_compression,
264+
response_compression=self._response_compression,
245265
)
246266
elif auth_method.lower() == "basic":
247267
connection = BasicConnection(
@@ -254,6 +274,8 @@ def db(
254274
http_client=self._http,
255275
serializer=self._serializer,
256276
deserializer=self._deserializer,
277+
request_compression=self._request_compression,
278+
response_compression=self._response_compression,
257279
)
258280
elif auth_method.lower() == "jwt":
259281
connection = JwtConnection(
@@ -266,6 +288,8 @@ def db(
266288
http_client=self._http,
267289
serializer=self._serializer,
268290
deserializer=self._deserializer,
291+
request_compression=self._request_compression,
292+
response_compression=self._response_compression,
269293
)
270294
else:
271295
raise ValueError(f"invalid auth_method: {auth_method}")

arango/cluster.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
ClusterServerCountError,
1212
ClusterServerEngineError,
1313
ClusterServerIDError,
14+
ClusterServerModeError,
1415
ClusterServerRoleError,
1516
ClusterServerStatisticsError,
1617
ClusterServerVersionError,
@@ -57,6 +58,27 @@ def response_handler(resp: Response) -> str:
5758

5859
return self._execute(request, response_handler)
5960

61+
def server_mode(self) -> Result[str]:
62+
"""Return the server mode.
63+
64+
In a read-only server, all write operations will fail
65+
with an error code of 1004 (ERROR_READ_ONLY). Creating or dropping
66+
databases and collections will also fail with error code 11 (ERROR_FORBIDDEN).
67+
68+
:return: Server mode. Possible values are "default" or "readonly".
69+
:rtype: str
70+
:raise arango.exceptions.ClusterServerModeError: If retrieval fails.
71+
"""
72+
request = Request(method="get", endpoint="/_admin/server/mode")
73+
74+
def response_handler(resp: Response) -> str:
75+
if resp.is_success:
76+
return str(resp.body["mode"])
77+
78+
raise ClusterServerModeError(resp, request)
79+
80+
return self._execute(request, response_handler)
81+
6082
def server_version(self, server_id: str) -> Result[Json]:
6183
"""Return the version of the given server.
6284
@@ -140,6 +162,58 @@ def response_handler(resp: Response) -> Json:
140162

141163
return self._execute(request, response_handler)
142164

165+
def server_maintenance_mode(self, server_id: str) -> Result[Json]:
166+
"""Return the maintenance status for the given server.
167+
168+
:param server_id: Server ID.
169+
:type server_id: str
170+
:return: Maintenance status for the given server.
171+
:rtype: dict
172+
:raise arango.exceptions.ClusterMaintenanceModeError: If retrieval fails.
173+
"""
174+
request = Request(
175+
method="get",
176+
endpoint=f"/_admin/cluster/maintenance/{server_id}",
177+
)
178+
179+
def response_handler(resp: Response) -> Json:
180+
if resp.is_success:
181+
result: Json = resp.body.get("result", {})
182+
return result
183+
184+
raise ClusterMaintenanceModeError(resp, request)
185+
186+
return self._execute(request, response_handler)
187+
188+
def toggle_server_maintenance_mode(
189+
self, server_id: str, mode: str, timeout: Optional[int] = None
190+
) -> Result[Json]:
191+
"""Enable or disable the maintenance mode for the given server.
192+
193+
:param server_id: Server ID.
194+
:type server_id: str
195+
:param mode: Maintenance mode. Allowed values are "normal" and "maintenance".
196+
:type mode: str
197+
:param timeout: Timeout in seconds.
198+
:type timeout: Optional[int]
199+
:return: Result of the operation.
200+
:rtype: dict
201+
:raise arango.exceptions.ClusterMaintenanceModeError: If toggle fails.
202+
"""
203+
request = Request(
204+
method="put",
205+
endpoint=f"/_admin/cluster/maintenance/{server_id}",
206+
data={"mode": mode, "timeout": timeout},
207+
)
208+
209+
def response_handler(resp: Response) -> Json:
210+
if resp.is_success:
211+
return format_body(resp.body)
212+
213+
raise ClusterMaintenanceModeError(resp, request)
214+
215+
return self._execute(request, response_handler)
216+
143217
def health(self) -> Result[Json]:
144218
"""Return the cluster health.
145219

0 commit comments

Comments
 (0)