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.
This commit is contained in:
mathieui 2021-02-14 11:36:51 +01:00
parent 8da5310ea6
commit d51c4e307d

View file

@ -1,3 +1,5 @@
from typing import Any, Optional
from asyncio import iscoroutinefunction, Future
from slixmpp.xmlstream import JID from slixmpp.xmlstream import JID
@ -44,7 +46,7 @@ class APIRegistry(object):
self.xmpp = xmpp self.xmpp = xmpp
self.settings = {} self.settings = {}
def _setup(self, ctype, op): def _setup(self, ctype: str, op: str):
"""Initialize the API callback dictionaries. """Initialize the API callback dictionaries.
:param string ctype: The name of the API to initialize. :param string ctype: The name of the API to initialize.
@ -61,17 +63,19 @@ class APIRegistry(object):
'jid': {}, 'jid': {},
'node': {}} 'node': {}}
def wrap(self, ctype): def wrap(self, ctype: str) -> APIWrapper:
"""Return a wrapper object that targets a specific API.""" """Return a wrapper object that targets a specific API."""
return APIWrapper(self, ctype) return APIWrapper(self, ctype)
def purge(self, ctype): def purge(self, ctype: str):
"""Remove all information for a given API.""" """Remove all information for a given API."""
del self.settings[ctype] del self.settings[ctype]
del self._handler_defaults[ctype] del self._handler_defaults[ctype]
del self._handlers[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. """Execute an API callback, based on specificity.
The API callback that is executed is chosen based on the combination 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 Handlers should check that the JID ``ifrom`` is authorized to perform
the desired action. the desired action.
:param string ctype: The name of the API to use. .. versionchanged:: 1.8.0
:param string op: The API operation to perform. ``run()`` always returns a future, if the handler is a coroutine
:param JID jid: Optionally provide specific JID. the future should be awaited on.
:param string node: Optionally provide specific node.
:param JID ifrom: Optionally provide the requesting JID. :param ctype: The name of the API to use.
:param tuple args: Optional positional arguments to the handler. :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) self._setup(ctype, op)
@ -130,7 +138,13 @@ class APIRegistry(object):
if handler: if handler:
try: 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: except TypeError:
# To preserve backward compatibility, drop the ifrom # To preserve backward compatibility, drop the ifrom
# parameter for existing handlers that don't understand it. # parameter for existing handlers that don't understand it.