http

class platypush.backend.http.HttpBackend(port=8008, websocket_port=8009, bind_address='0.0.0.0', disable_websocket=False, resource_dirs=None, ssl_cert=None, ssl_key=None, ssl_cafile=None, ssl_capath=None, maps=None, run_externally=False, uwsgi_args=None, **kwargs)[source]

The HTTP backend is a general-purpose web server.

Example configuration:

backend.http:
    # Default HTTP listen port
    port: 8008
    # Default websocket port
    websocket_port: 8009
    # 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 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>, where name=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 or GET ?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 as token: <VALUE>. It can provided either over on the X-Token header or as a GET ?token=<TOKEN> parameter.

  • Session token, generated upon login, it can be used to authenticate requests through the Cookie header (cookie name: session_token).

Requires:

  • flask (pip install flask)

  • bcrypt (pip install bcrypt)

  • magic (pip install python-magic), optional, for MIME type

    support if you want to enable media streaming

  • uwsgi (pip install uwsgi plus uwsgi server installed on your

    system if required) - optional but recommended. By default the Platypush web server will run in a process spawned on the fly by the HTTP backend. However, being a Flask app, it will serve clients in a single thread and won’t support many features of a full-blown web server.

Base command to run the web server over uwsgi:

uwsgi --http :8008 --module platypush.backend.http.uwsgi --master --processes 4 --threads 4

Bear in mind that the main webapp is defined in platypush.backend.http.app:application and the WSGI startup script is stored under platypush/backend/http/uwsgi.py.

__init__(port=8008, websocket_port=8009, bind_address='0.0.0.0', disable_websocket=False, resource_dirs=None, ssl_cert=None, ssl_key=None, ssl_cafile=None, ssl_capath=None, maps=None, run_externally=False, uwsgi_args=None, **kwargs)[source]
Parameters
  • port (int) – Listen port for the web server (default: 8008)

  • websocket_port (int) – Listen port for the websocket server (default: 8009)

  • bind_address (str) – Address/interface to bind to (default: 0.0.0.0, accept connection from any IP)

  • disable_websocket (bool) – Disable the websocket interface (default: False)

  • ssl_cert (str) – Set it to the path of your certificate file if you want to enable HTTPS (default: None)

  • ssl_key (str) – Set it to the path of your key file if you want to enable HTTPS (default: None)

  • ssl_cafile (str) – Set it to the path of your certificate authority file if you want to enable HTTPS (default: None)

  • ssl_capath (str) – Set it to the path of your certificate authority directory if you want to enable HTTPS (default: None)

  • resource_dirs (dict[str, str]) – 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.

  • run_externally (bool) – If set, then the HTTP backend will not directly spawn the web server. Set this option if you plan to run the webapp in a separate web server (recommended), like uwsgi or uwsgi+nginx.

  • uwsgi_args (list[str]) –

    If run_externally is set and you would like the HTTP backend to directly spawn and control the uWSGI application server instance, then pass the list of uWSGI arguments through this parameter. Some examples include:

    # Start uWSGI instance listening on HTTP port 8008 with 4
    # processes
    ['--plugin', 'python', '--http-socket', ':8008', '--master', '--processes', '4']
    
    # Start uWSGI instance listening on uWSGI socket on port 3031.
    # You can then use another full-blown web server, like nginx
    # or Apache, to communicate with the uWSGI instance
    ['--plugin', 'python', '--socket', '127.0.0.1:3031', '--master', '--processes', '4']
    

notify_web_clients(event)[source]

Notify all the connected web clients (over websocket) of a new event

on_stop()[source]

On backend stop

run()[source]

Starts the backend thread. To be implemented in the derived classes if the loop method isn’t defined.

send_message(msg, **kwargs)[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)

websocket()[source]

Websocket main server