allow to use the JSON RPC client from async code

This commit is contained in:
adbenitez
2023-10-26 23:30:13 +02:00
parent 1b66120e7d
commit 6d2bae7b1d
2 changed files with 32 additions and 0 deletions

View File

@@ -48,3 +48,7 @@ $ python
'awesome'
>>> rpc.close()
```
## Usage from async code
See the [echobot_async.py](./examples/echobot_async.py) example.

View File

@@ -1,3 +1,4 @@
import asyncio
import json
import logging
import os
@@ -35,6 +36,10 @@ class Rpc:
self.writer_thread: Thread
self.events_thread: Thread
def get_async_rpc(self) -> "AsyncRpc":
"""Get asynchronous wrapper to use the RPC methods from async code."""
return AsyncRpc(self)
def start(self) -> None:
if sys.version_info >= (3, 11):
self.process = subprocess.Popen(
@@ -84,6 +89,13 @@ class Rpc:
def __exit__(self, _exc_type, _exc, _tb):
self.close()
async def __aenter__(self):
self.__enter__()
return AsyncRpc(self)
async def __aexit__(self, _exc_type, _exc, _tb):
self.__exit__(_exc_type, _exc, _tb)
def reader_loop(self) -> None:
try:
while True:
@@ -165,3 +177,19 @@ class Rpc:
return None
return method
class AsyncRpc:
def __init__(self, sync_rpc: Rpc) -> None:
self._sync_rpc = sync_rpc
def __getattr__(self, attr: str) -> Any:
sync_method = getattr(self._sync_rpc, attr)
if sync_method:
async def method(*args) -> Any:
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, sync_method, *args)
return method
return None