summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormathieui <mathieui@mathieui.net>2021-02-14 11:36:51 +0100
committermathieui <mathieui@mathieui.net>2021-02-26 00:08:56 +0100
commitd51c4e307d79cad2eaf42ce52c4f17454475f44d (patch)
tree108f6e7f6b2f87a88e3af11cd078407639411890
parent8da5310ea61d40c3d31dc16f08846f4741c0c4f8 (diff)
downloadslixmpp-d51c4e307d79cad2eaf42ce52c4f17454475f44d.tar.gz
slixmpp-d51c4e307d79cad2eaf42ce52c4f17454475f44d.tar.bz2
slixmpp-d51c4e307d79cad2eaf42ce52c4f17454475f44d.tar.xz
slixmpp-d51c4e307d79cad2eaf42ce52c4f17454475f44d.zip
api: make run() always return a Future
plugins must be modified to make use of this, but this keeps synchronous code synchrouns while allowing coroutine in api, which makes sense.
-rw-r--r--slixmpp/api.py36
1 files changed, 25 insertions, 11 deletions
diff --git a/slixmpp/api.py b/slixmpp/api.py
index f09e0365..7a68ec4c 100644
--- a/slixmpp/api.py
+++ b/slixmpp/api.py
@@ -1,3 +1,5 @@
+from typing import Any, Optional
+from asyncio import iscoroutinefunction, Future
from slixmpp.xmlstream import JID
@@ -44,7 +46,7 @@ class APIRegistry(object):
self.xmpp = xmpp
self.settings = {}
- def _setup(self, ctype, op):
+ def _setup(self, ctype: str, op: str):
"""Initialize the API callback dictionaries.
:param string ctype: The name of the API to initialize.
@@ -61,17 +63,19 @@ class APIRegistry(object):
'jid': {},
'node': {}}
- def wrap(self, ctype):
+ def wrap(self, ctype: str) -> APIWrapper:
"""Return a wrapper object that targets a specific API."""
return APIWrapper(self, ctype)
- def purge(self, ctype):
+ def purge(self, ctype: str):
"""Remove all information for a given API."""
del self.settings[ctype]
del self._handler_defaults[ctype]
del self._handlers[ctype]
- def run(self, ctype, op, jid=None, node=None, ifrom=None, args=None):
+ def run(self, ctype: str, op: str, jid: Optional[JID] = None,
+ node: Optional[str] = None, ifrom: Optional[JID] = None,
+ args: Any = None) -> Future:
"""Execute an API callback, based on specificity.
The API callback that is executed is chosen based on the combination
@@ -90,12 +94,16 @@ class APIRegistry(object):
Handlers should check that the JID ``ifrom`` is authorized to perform
the desired action.
- :param string ctype: The name of the API to use.
- :param string op: The API operation to perform.
- :param JID jid: Optionally provide specific JID.
- :param string node: Optionally provide specific node.
- :param JID ifrom: Optionally provide the requesting JID.
- :param tuple args: Optional positional arguments to the handler.
+ .. versionchanged:: 1.8.0
+ ``run()`` always returns a future, if the handler is a coroutine
+ the future should be awaited on.
+
+ :param ctype: The name of the API to use.
+ :param op: The API operation to perform.
+ :param jid: Optionally provide specific JID.
+ :param node: Optionally provide specific node.
+ :param ifrom: Optionally provide the requesting JID.
+ :param args: Optional arguments to the handler.
"""
self._setup(ctype, op)
@@ -130,7 +138,13 @@ class APIRegistry(object):
if handler:
try:
- return handler(jid, node, ifrom, args)
+ if iscoroutinefunction(handler):
+ return self.xmpp.wrap(handler(jid, node, ifrom, args))
+ else:
+ future = Future()
+ result = handler(jid, node, ifrom, args)
+ future.set_result(result)
+ return future
except TypeError:
# To preserve backward compatibility, drop the ifrom
# parameter for existing handlers that don't understand it.