http
#
- class platypush.backend.http.HttpBackend(port: int = 8008, bind_address: str = '0.0.0.0', resource_dirs: Mapping[str, str] | None = None, secret_key_file: str | None = None, num_workers: int | None = None, use_werkzeug_server: bool = False, **kwargs)[source]#
Bases:
Backend
The HTTP backend is a general-purpose web server.
Example configuration:
backend.http: # Default HTTP listen port port: 8008 # External folders that will be exposed over `/resources/<name>` resource_dirs: photos: /mnt/hd/photos videos: /mnt/hd/videos music: /mnt/hd/music
You can leverage this backend:
To execute Platypush commands via HTTP calls. In order to do so:
Register a user to Platypush through the web panel (usually served on
http://host:8008/
).Generate a token for your user, either through the web panel (Settings -> Generate Token) or via API:
curl -XPOST -H 'Content-Type: application/json' -d ' { "username": "$YOUR_USER", "password": "$YOUR_PASSWORD" }' http://host:8008/auth
Execute actions through the
/execute
endpoint:curl -XPOST -H 'Content-Type: application/json' -H "Authorization: Bearer $YOUR_TOKEN" -d ' { "type": "request", "action": "tts.say", "args": { "text": "This is a test" } }' http://host:8008/execute
To interact with your system (and control plugins and backends) through the Platypush web panel, by default available on
http://host:8008/
. Any configured plugin that has an available panel plugin will be automatically added to the web panel.To create asynchronous integrations with Platypush over websockets. Two routes are available:
/ws/events
- Subscribe to this websocket to receive the events generated by the application./ws/requests
- Subscribe to this websocket to send commands to Platypush and receive the response asynchronously.
You will have to authenticate your connection to these websockets, just like the
/execute
endpoint. In both cases, you can pass the token either viaAuthorization: Bearer
, via thetoken
query string or body parameter, or leverageAuthorization: Basic
with username and password (not advised), or use a validsession_token
cookie from an authenticated web panel session.To display a fullscreen dashboard with custom widgets.
Widgets are available as Vue.js components under
platypush/backend/http/webapp/src/components/widgets
.Explore their options (some may require some plugins or backends to be configured in order to work) and create a new dashboard template under
~/.config/platypush/dashboards
- e.g.main.xml
:<Dashboard> <!-- Display the following widgets on the same row. Each row consists of 12 columns. You can specify the width of each widget either through class name (e.g. col-6 means 6 columns out of 12, e.g. half the size of the row) or inline style (e.g. `style="width: 50%"`). --> <Row> <!-- Show a calendar widget with the upcoming events. It requires the `calendar` plugin to be enabled and configured. --> <Calendar class="col-6" /> <!-- Show the current track and other playback info. It requires `music.mpd` plugin or any other music plugin enabled. --> <Music class="col-3" /> <!-- Show current date, time and weather. It requires a `weather` plugin or backend enabled --> <DateTimeWeather class="col-3" /> </Row> <!-- Display the following widgets on a second row --> <Row> <!-- Show a carousel of images from a local folder. For security reasons, the folder must be explicitly exposed as an HTTP resource through the backend `resource_dirs` attribute. --> <ImageCarousel class="col-6" img-dir="/mnt/hd/photos/carousel" /> <!-- Show the news headlines parsed from a list of RSS feed and stored locally through the `http.poll` backend --> <RssNews class="col-6" db="sqlite:////path/to/your/rss.db" /> </Row> </Dashboard>
The dashboard will be accessible under
http://host:8008/dashboard/<name>
, wherename=main
if for example you stored your template under~/.config/platypush/dashboards/main.xml
.
To expose custom endpoints that can be called as web hooks by other applications and run some custom logic. All you have to do in this case is to create a hook on a
platypush.message.event.http.hook.WebhookEvent
with the endpoint that you want to expose and store it under e.g.~/.config/platypush/scripts/hooks.py
:from platypush.context import get_plugin from platypush.event.hook import hook from platypush.message.event.http.hook import WebhookEvent hook_token = 'abcdefabcdef' # Expose the hook under the /hook/lights_toggle endpoint @hook(WebhookEvent, hook='lights_toggle') def lights_toggle(event, **context): # Do any checks on the request assert event.headers.get('X-Token') == hook_token, 'Unauthorized' # Run some actions lights = get_plugin('light.hue') lights.toggle()
Any plugin can register custom routes under
platypush/backend/http/app/routes/plugins
. Any additional route is managed as a Flask blueprint template and the .py module can expose lists of routes to the main webapp through the__routes__
object (a list of Flask blueprints).Security: Access to the endpoints requires at least one user to be registered. Access to the endpoints is regulated in the following ways (with the exception of event hooks, whose logic is up to the user):
Simple authentication - i.e. registered username and password.
JWT token provided either over as
Authorization: Bearer
header orGET
?token=<TOKEN>
parameter. A JWT token can be generated either through the web panel or over the/auth
endpoint.Global platform token, usually configured on the root of the
config.yaml
astoken: <VALUE>
. It can provided either over on theX-Token
header or as aGET
?token=<TOKEN>
parameter.Session token, generated upon login, it can be used to authenticate requests through the
Cookie
header (cookie name:session_token
).
- __init__(port: int = 8008, bind_address: str = '0.0.0.0', resource_dirs: Mapping[str, str] | None = None, secret_key_file: str | None = None, num_workers: int | None = None, use_werkzeug_server: bool = False, **kwargs)[source]#
- Parameters:
port – Listen port for the web server (default: 8008)
bind_address – Address/interface to bind to (default: 0.0.0.0, accept connection from any IP)
resource_dirs – Static resources directories that will be accessible through
/resources/<path>
. It is expressed as a map where the key is the relative path under/resources
to expose and the value is the absolute path to expose.secret_key_file – Path to the file containing the secret key that will be used by Flask (default:
~/.local/share/platypush/flask.secret.key
).num_workers – Number of worker processes to use (default:
(cpu_count * 2) + 1
).use_werkzeug_server –
Whether the backend should be served by a Werkzeug server (default:
False
). Note that using the built-in Werkzeug server instead of Tornado is very inefficient, and it doesn’t support websocket-based features either so the UI will probably be severely limited. You should only use this option if:You are running tests.
You have issues with running a full Tornado server - for example, you are running the application on a small embedded device that doesn’t support Tornado.
- notify_web_clients(event)[source]#
Notify all the connected web clients (over websocket) of a new event
- run()[source]#
Starts the backend thread. To be implemented in the derived classes if the loop method isn’t defined.
- send_message(*_, **__)[source]#
Sends a platypush.message.Message to a node. To be implemented in the derived classes. By default, if the Redis backend is configured then it will try to deliver the message to other consumers through the configured Redis main queue.
- Parameters:
msg – The message to send
queue_name – Send the message on a specific queue (default: the queue_name configured on the Redis backend)