Added web hooks section to README.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Fabio Manganiello 2024-05-25 20:11:07 +02:00
parent 0479c37d64
commit 35751da068
Signed by: blacklight
GPG Key ID: D90FBA7F76362774
2 changed files with 42 additions and 10 deletions

View File

@ -34,6 +34,7 @@
- [Websocket API](#websocket-api)
* [Events](#events)
* [Actions](#actions)
- [Web hooks](#web-hooks)
- [Entities](#entities)
- [Core Installation](#core-installation)
* [System package manager installation](#system-package-manager-installation)
@ -685,6 +686,41 @@ responses asynchronously on the same channel:
-x '{"type": "requests", "action": "procedure.foo.bar"}'
```
## Web hooks
You can use Platypush to expose your custom routines as dynamic Web hooks that
can be called by any client.
All you need is to register a listener for a
[`WebhookEvent`](https://docs.platypush.tech/platypush/events/http.hook.html#platypush.message.event.http.hook.WebhookEvent)
```python
from platypush import run, when
from platypush.events.http.hook import WebhookEvent
hook_token = "abcdefabcdef"
# Expose the hook under the /hook/at_home endpoint
@when(WebhookEvent, hook="at_home")
def at_home_webhook(event: WebhookEvent):
# Unlike the calls to /execute, custom web hooks are unauthenticated.
# If you want authentication, you'll need to implement your custom logic by
# parsing the event headers
if event.headers.get("X-Token") != hook_token:
# Tuple with <response, http-code, [response-headers]>
event.send_response(("Unauthorized", 401))
return
run('procedure.at_home')
```
Then you can invoke your custom logic over HTTP:
```bash
curl -H 'X-Token: abcdefabcdef' 'http://localhost:8008/hook/at_home'
```
## Entities
Entities are another building block of Platypush. Many integrations will store

View File

@ -57,20 +57,16 @@ class WebhookEvent(Event):
)
def send_response(self, response):
output = response.output
output = getattr(response, 'output', response)
if isinstance(output, tuple):
# A 3-sized tuple where the second element is an int and the third
# is a dict represents an HTTP response in the format `(data,
# http_code headers)`.
if (
len(output) == 3
and isinstance(output[1], int)
and isinstance(output[2], dict)
):
# A 3-sized tuple where the first element is the response, the
# second element is the HTTP code and the third is a dict with the
# response headers
if len(output) in (2, 3) and isinstance(output[1], int):
output = {
'___data___': output[0],
'___code___': output[1],
'___headers___': output[2],
'___headers___': output[2] if len(output) > 2 else {},
}
else:
# Normalize tuples to lists before serialization