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:
parent
8da5310ea6
commit
d51c4e307d
1 changed files with 25 additions and 11 deletions
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue