Skip to content

Commit 0577dfe

Browse files
committed
object oriented API
1 parent 4e197e0 commit 0577dfe

File tree

5 files changed

+156
-88
lines changed

5 files changed

+156
-88
lines changed

deltachat-rpc-client/src/deltachat_rpc_client/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from .deltachat import Deltachat, start_rpc_server, new_online_account
1+
from .rpc import Rpc, start_rpc_server, new_online_account
2+
from .deltachat import Deltachat
3+
from .account import Account
24

35

46
async def main():
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from typing import Optional
2+
3+
4+
class Account:
5+
def __init__(self, rpc, id):
6+
self.id = id
7+
self.rpc = rpc
8+
9+
async def remove(self) -> None:
10+
await self.rpc.remove_account(self.id)
11+
12+
async def start_io(self) -> None:
13+
await self.rpc.start_io(self.id)
14+
15+
async def stop_io(self) -> None:
16+
await self.rpc.stop_io(self.id)
17+
18+
async def get_info(self):
19+
await self.rpc.get_info(self.id)
20+
21+
async def get_file_size(self):
22+
await self.rpc.get_account_file_size(self.id)
23+
24+
async def is_configured(self) -> bool:
25+
await self.rpc.is_configured(self.id)
26+
27+
async def set_config(key: str, value: Optional[str]):
28+
await self.rpc.set_config(self.id, key, value)
29+
30+
async def get_config(key: str) -> Optional[str]:
31+
await self.rpc.get_config(self.id, key)
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,25 @@
1-
import asyncio
2-
import aiohttp
3-
import json
4-
import logging
5-
import os
6-
7-
8-
class JsonRpcError(Exception):
9-
pass
1+
from .account import Account
102

113

124
class Deltachat:
13-
def __init__(self, process):
14-
self.process = process
15-
self.event_queue = asyncio.Queue()
16-
self.id = 0
17-
self.reader_task = asyncio.create_task(self.reader_loop())
18-
19-
# Map from request ID to `asyncio.Future` returning the response.
20-
self.request_events = {}
21-
22-
async def reader_loop(self):
23-
while True:
24-
line = await self.process.stdout.readline()
25-
response = json.loads(line)
26-
if "id" in response:
27-
fut = self.request_events.pop(response["id"])
28-
fut.set_result(response)
29-
else:
30-
if response["method"] == "event":
31-
# An event notification.
32-
await self.event_queue.put(response["params"]["event"])
33-
34-
async def get_next_event(self):
35-
"""Returns next event."""
36-
return await self.event_queue.get()
37-
38-
def __getattr__(self, attr):
39-
async def method(*args, **kwargs):
40-
self.id += 1
41-
request_id = self.id
42-
43-
params = args
44-
if kwargs:
45-
assert not args
46-
params = kwargs
47-
48-
request = {
49-
"jsonrpc": "2.0",
50-
"method": attr,
51-
"params": params,
52-
"id": self.id,
53-
}
54-
data = (json.dumps(request) + "\n").encode()
55-
self.process.stdin.write(data)
56-
event = asyncio.Event()
57-
loop = asyncio.get_running_loop()
58-
fut = loop.create_future()
59-
self.request_events[request_id] = fut
60-
response = await fut
61-
if "error" in response:
62-
raise JsonRpcError(response["error"])
63-
if "result" in response:
64-
return response["result"]
5+
"""
6+
Delta Chat account manager.
7+
This is the root of the object oriented API.
8+
"""
659

66-
return method
10+
def __init__(self, rpc):
11+
self.rpc = rpc
6712

13+
async def add_account(self):
14+
account_id = await self.rpc.add_account()
15+
return Account(self.rpc, account_id)
6816

69-
async def start_rpc_server():
70-
proc = await asyncio.create_subprocess_exec(
71-
"deltachat-rpc-server",
72-
stdin=asyncio.subprocess.PIPE,
73-
stdout=asyncio.subprocess.PIPE,
74-
)
75-
deltachat = Deltachat(proc)
76-
return deltachat
17+
async def get_all_accounts(self):
18+
account_ids = await self.rpc.get_all_account_ids()
19+
return [Account(rpc, account_id) for account_id in account_ids]
7720

21+
async def start_io(self) -> None:
22+
await self.rpc.start_io_for_all_accounts()
7823

79-
async def new_online_account():
80-
url = os.getenv("DCC_NEW_TMP_EMAIL")
81-
async with aiohttp.ClientSession() as session:
82-
async with session.post(url) as response:
83-
return json.loads(await response.text())
24+
async def stop_io(self) -> None:
25+
await self.rpc.stop_io_for_all_accounts()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import asyncio
2+
import aiohttp
3+
import json
4+
import logging
5+
import os
6+
7+
8+
class JsonRpcError(Exception):
9+
pass
10+
11+
12+
class Rpc:
13+
def __init__(self, process):
14+
self.process = process
15+
self.event_queue = asyncio.Queue()
16+
self.id = 0
17+
self.reader_task = asyncio.create_task(self.reader_loop())
18+
19+
# Map from request ID to `asyncio.Future` returning the response.
20+
self.request_events = {}
21+
22+
async def reader_loop(self):
23+
while True:
24+
line = await self.process.stdout.readline()
25+
response = json.loads(line)
26+
if "id" in response:
27+
fut = self.request_events.pop(response["id"])
28+
fut.set_result(response)
29+
else:
30+
if response["method"] == "event":
31+
# An event notification.
32+
await self.event_queue.put(response["params"]["event"])
33+
34+
async def get_next_event(self):
35+
"""Returns next event."""
36+
return await self.event_queue.get()
37+
38+
def __getattr__(self, attr):
39+
async def method(*args, **kwargs):
40+
self.id += 1
41+
request_id = self.id
42+
43+
params = args
44+
if kwargs:
45+
assert not args
46+
params = kwargs
47+
48+
request = {
49+
"jsonrpc": "2.0",
50+
"method": attr,
51+
"params": params,
52+
"id": self.id,
53+
}
54+
data = (json.dumps(request) + "\n").encode()
55+
self.process.stdin.write(data)
56+
event = asyncio.Event()
57+
loop = asyncio.get_running_loop()
58+
fut = loop.create_future()
59+
self.request_events[request_id] = fut
60+
response = await fut
61+
if "error" in response:
62+
raise JsonRpcError(response["error"])
63+
if "result" in response:
64+
return response["result"]
65+
66+
return method
67+
68+
69+
async def start_rpc_server():
70+
proc = await asyncio.create_subprocess_exec(
71+
"deltachat-rpc-server",
72+
stdin=asyncio.subprocess.PIPE,
73+
stdout=asyncio.subprocess.PIPE,
74+
)
75+
rpc = Rpc(proc)
76+
return rpc
77+
78+
79+
async def new_online_account():
80+
url = os.getenv("DCC_NEW_TMP_EMAIL")
81+
async with aiohttp.ClientSession() as session:
82+
async with session.post(url) as response:
83+
return json.loads(await response.text())

deltachat-rpc-client/tests/test_something.py

+22-12
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,45 @@
22
import pytest_asyncio
33

44
import deltachat_rpc_client
5+
from deltachat_rpc_client import Deltachat
56

67

78
@pytest_asyncio.fixture
8-
async def rpc_server():
9+
async def rpc():
910
return await deltachat_rpc_client.start_rpc_server()
1011

1112

1213
@pytest.mark.asyncio
13-
async def test_system_info(rpc_server):
14-
system_info = await rpc_server.get_system_info()
14+
async def test_system_info(rpc):
15+
system_info = await rpc.get_system_info()
1516
assert "arch" in system_info
1617
assert "deltachat_core_version" in system_info
1718

1819

1920
@pytest.mark.asyncio
20-
async def test_email_address_validity(rpc_server):
21+
async def test_email_address_validity(rpc):
2122
valid_addresses = [
2223
2324
"36aa165ae3406424e0c61af17700f397cad3fe8ab83d682d0bddf3338a5dd52e@yggmail@yggmail",
2425
]
2526
invalid_addresses = ["email@", "example.com", "emai221"]
2627

2728
for addr in valid_addresses:
28-
assert await rpc_server.check_email_validity(addr)
29+
assert await rpc.check_email_validity(addr)
2930
for addr in invalid_addresses:
30-
assert not await rpc_server.check_email_validity(addr)
31+
assert not await rpc.check_email_validity(addr)
3132

3233
@pytest.mark.asyncio
33-
async def test_online_account(rpc_server):
34+
async def test_online_account(rpc):
3435
account_json = await deltachat_rpc_client.new_online_account()
3536

36-
account_id = await rpc_server.add_account()
37-
await rpc_server.set_config(account_id, "addr", account_json["email"])
38-
await rpc_server.set_config(account_id, "mail_pw", account_json["password"])
37+
account_id = await rpc.add_account()
38+
await rpc.set_config(account_id, "addr", account_json["email"])
39+
await rpc.set_config(account_id, "mail_pw", account_json["password"])
3940

40-
await rpc_server.configure(account_id)
41+
await rpc.configure(account_id)
4142
while True:
42-
event = await rpc_server.get_next_event()
43+
event = await rpc.get_next_event()
4344
if event["type"] == "ConfigureProgress":
4445
# Progress 0 indicates error.
4546
assert event["progress"] != 0
@@ -50,3 +51,12 @@ async def test_online_account(rpc_server):
5051
else:
5152
print(event)
5253
print("Successful configuration")
54+
55+
56+
@pytest.mark.asyncio
57+
async def test_online_account(rpc):
58+
deltachat = Deltachat(rpc)
59+
account = await deltachat.add_account()
60+
assert not await account.is_configured()
61+
info = await account.get_info()
62+
print(info)

0 commit comments

Comments
 (0)