Skip to content

Commit 5b84719

Browse files
authored
Introducing Database class (#18)
1 parent f180e7a commit 5b84719

File tree

6 files changed

+115
-11
lines changed

6 files changed

+115
-11
lines changed

arangoasync/client.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
JwtConnection,
1212
JwtSuperuserConnection,
1313
)
14-
from arangoasync.database import Database
14+
from arangoasync.database import StandardDatabase
1515
from arangoasync.http import DefaultHTTPClient, HTTPClient
1616
from arangoasync.resolver import HostResolver, get_resolver
1717
from arangoasync.version import __version__
@@ -124,7 +124,7 @@ async def db(
124124
token: Optional[JwtToken] = None,
125125
verify: bool = False,
126126
compression: Optional[CompressionManager] = None,
127-
) -> Database:
127+
) -> StandardDatabase:
128128
"""Connects to a database and returns and API wrapper.
129129
130130
Args:
@@ -147,7 +147,7 @@ async def db(
147147
client-level compression settings.
148148
149149
Returns:
150-
Database: Database API wrapper.
150+
StandardDatabase: Database API wrapper.
151151
152152
Raises:
153153
ValueError: If the authentication is invalid.
@@ -198,4 +198,4 @@ async def db(
198198
if verify:
199199
await connection.ping()
200200

201-
return Database(connection)
201+
return StandardDatabase(connection)

arangoasync/database.py

+47-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,59 @@
11
__all__ = [
22
"Database",
3+
"StandardDatabase",
34
]
45

5-
from arangoasync.connection import BaseConnection
6+
import json
7+
from typing import Any
8+
9+
from arangoasync.connection import Connection
10+
from arangoasync.exceptions import ServerStatusError
11+
from arangoasync.executor import ApiExecutor, DefaultApiExecutor
12+
from arangoasync.request import Method, Request
13+
from arangoasync.response import Response
614

715

816
class Database:
917
"""Database API."""
1018

11-
def __init__(self, connection: BaseConnection) -> None:
12-
self._conn = connection
19+
def __init__(self, executor: ApiExecutor) -> None:
20+
self._executor = executor
1321

1422
@property
15-
def conn(self) -> BaseConnection:
23+
def connection(self) -> Connection:
1624
"""Return the HTTP connection."""
17-
return self._conn
25+
return self._executor.connection
26+
27+
@property
28+
def name(self) -> str:
29+
"""Return the name of the current database."""
30+
return self.connection.db_name
31+
32+
# TODO - user real return type
33+
async def status(self) -> Any:
34+
"""Query the server status.
35+
36+
Returns:
37+
Json: Server status.
38+
39+
Raises:
40+
ServerSatusError: If retrieval fails.
41+
"""
42+
request = Request(method=Method.GET, endpoint="/_admin/status")
43+
44+
# TODO
45+
# - introduce specific return type for response_handler
46+
# - introduce specific serializer and deserializer
47+
def response_handler(resp: Response) -> Any:
48+
if not resp.is_success:
49+
raise ServerStatusError(resp, request)
50+
return json.loads(resp.raw_body)
51+
52+
return await self._executor.execute(request, response_handler)
53+
54+
55+
class StandardDatabase(Database):
56+
"""Standard database API wrapper."""
57+
58+
def __init__(self, connection: Connection) -> None:
59+
super().__init__(DefaultApiExecutor(connection))

arangoasync/exceptions.py

+4
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,7 @@ class JWTRefreshError(ArangoClientError):
8686

8787
class ServerConnectionError(ArangoServerError):
8888
"""Failed to connect to ArangoDB server."""
89+
90+
91+
class ServerStatusError(ArangoServerError):
92+
"""Failed to retrieve server status."""

arangoasync/executor.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from typing import Callable, TypeVar
2+
3+
from arangoasync.connection import Connection
4+
from arangoasync.request import Request
5+
from arangoasync.response import Response
6+
7+
T = TypeVar("T")
8+
9+
10+
class DefaultApiExecutor:
11+
"""Default API executor.
12+
13+
Responsible for executing requests and handling responses.
14+
15+
Args:
16+
connection: HTTP connection.
17+
"""
18+
19+
def __init__(self, connection: Connection) -> None:
20+
self._conn = connection
21+
22+
@property
23+
def connection(self) -> Connection:
24+
return self._conn
25+
26+
@property
27+
def context(self) -> str:
28+
return "default"
29+
30+
async def execute(
31+
self, request: Request, response_handler: Callable[[Response], T]
32+
) -> T:
33+
"""Execute the request and handle the response.
34+
35+
Args:
36+
request: HTTP request.
37+
response_handler: HTTP response handler.
38+
"""
39+
response = await self._conn.send_request(request)
40+
return response_handler(response)
41+
42+
43+
ApiExecutor = DefaultApiExecutor

tests/test_client.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def mock_method(*args, **kwargs):
5555

5656

5757
@pytest.mark.asyncio
58-
async def test_client_bad_auth_method(url, sys_db_name, root, password):
58+
async def test_client_bad_auth_method(url, sys_db_name):
5959
async with ArangoClient(hosts=url) as client:
6060
with pytest.raises(ValueError):
6161
await client.db(sys_db_name, auth_method="invalid")
@@ -89,7 +89,7 @@ async def test_client_jwt_auth(url, sys_db_name, root, password):
8989
# successful authentication with auth only
9090
async with ArangoClient(hosts=url) as client:
9191
db = await client.db(sys_db_name, auth_method="jwt", auth=auth, verify=True)
92-
token = db.conn.token
92+
token = db.connection.token
9393

9494
# successful authentication with token only
9595
async with ArangoClient(hosts=url) as client:

tests/test_database.py

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import pytest
2+
3+
from arangoasync.auth import Auth
4+
from arangoasync.client import ArangoClient
5+
6+
7+
@pytest.mark.asyncio
8+
async def test_client_basic_auth(url, sys_db_name, root, password):
9+
auth = Auth(username=root, password=password)
10+
11+
# TODO create a test database and user
12+
async with ArangoClient(hosts=url) as client:
13+
db = await client.db(sys_db_name, auth_method="basic", auth=auth, verify=True)
14+
status = await db.status()
15+
assert status["server"] == "arango"

0 commit comments

Comments
 (0)