1
0
Fork 0
platypush/platypush/message/event/http/hook.py
Fabio Manganiello c3fa3315f5
Implemented synchronization with webhook responses.
When a client triggers a `WebhookEvent` by calling a configured webhook
over `/hook/<hook_name>`, the server will now wait for the configured
`@hook` function to complete and it will return the returned response
back to the client.

This makes webhooks much more powerful, as they can be used to proxy
HTTP calls or other services, and in general return something to the
client instead of just executing actions.
2022-08-30 23:35:19 +02:00

70 lines
1.7 KiB
Python

import json
import uuid
from platypush.message.event import Event
from platypush.utils import get_redis
class WebhookEvent(Event):
"""
Event triggered when a custom webhook is called.
"""
def __init__(
self,
*argv,
hook,
method,
data=None,
args=None,
headers=None,
response=None,
**kwargs,
):
"""
:param hook: Name of the invoked web hook, from http://host:port/hook/<hook>
:type hook: str
:param method: HTTP method (in uppercase)
:type method: str
:param data: Extra data passed over POST/PUT/DELETE
:type data: str or dict/list from JSON
:param args: Extra query string arguments
:type args: dict
:param headers: Request headers
:type args: dict
:param response: Response returned by the hook.
:type args: dict | list | str
"""
# This queue is used to synchronize with the hook and wait for its completion
kwargs['response_queue'] = kwargs.get(
'response_queue', f'platypush/webhook/{str(uuid.uuid1())}'
)
super().__init__(
*argv,
hook=hook,
method=method,
data=data,
args=args or {},
headers=headers or {},
response=response,
**kwargs,
)
def send_response(self, response):
output = response.output
if isinstance(output, (dict, list)):
output = json.dumps(output)
get_redis().rpush(self.args['response_queue'], output)
def wait_response(self, timeout=None):
return get_redis().blpop(self.args['response_queue'], timeout=timeout)[1]
# vim:sw=4:ts=4:et: