How to use the Python Launcher
Introduction
When deploying ParaViewWeb for multiple users, you will need a launcher module that will start a new visualization process for each user that requests one. This task can be achieved by our Python based launcher described below.
Because the Python launcher is included in ParaViewWeb and requires no extra software to get up and running, it is the recommended approach to launching ParaViewWeb visualization sessions. This document covers how to configure the Python launcher for use with a front end, including specific details on getting it working with Apache.
Role of the launcher
The launcher has several specific tasks, all with the common goal of allowing clients to request visualization sessions and then interact with them. The launcher needs to respond to requests for new sessions by:
- starting a new process for the user
- generating a unique key for that session
- communicating that unique key back to both the client and the front end so that the front end knows how to forward subsequent session requests to the correct visualization process
Configuration of the launcher
The launcher provides a great deal of flexibility, which can be leveraged by customizing its configuration file. In this guide, as in the Apache as a front end guide, we assume you are using Apache as the front end, and we also assume the directory you have chosen for the mapping file is <MAPPING-FILE-DIR>
. The following is an example configuration file:
launcher.config
{ |
In order to run the Python launcher service, you will need to execute the following command line.
$ pip install wslink |
It is important to take special note a few of the details:
The
apps
section gives the command lines required to start any of the visualization processes the launcher will be capable of starting. We recommend always providing the-dr
argument topvpython
so that it never tries to load any saved preferences it might find.The
configuration
section gives several important values:sessionURL
gives the url needed to communicate with the visualization processes. In the case of the Apache front end, Apache will recognize this url and re-write it so that Apache websocket forwarding can send the packets to the correct running process on the back end. ThissessionURL
value needs to match what is expected by the Apache RewriteRule (given in the Apache virtual host configuration). See the Apache as a front end guide for details.proxy_file
gives the location of the mapping file that the launcher and front end will use to communicate about which session ids get mapped to which port. The location of this file must concur with the Apache RewriteMap value (given in the Apache virtual host configuration).
sessionData
is designed to allow you to specify that certain arbitrary key/value pairs should be included in the data returned to the client upon successful creation of the session. In the example launcher config file above, we have added a key calledupdir
with a value of/Home
to thesessionData
segment. This will cause the launcher to perform normal substitutions on the on the value (in this case, none are needed as the value is simply/Home
), and then include"updir": "/Home"
in the response when sessions are successfully created for clients.- Note, however, that in the
configuration
section of the launcher config file, thefields
key denotes a list of keys that will be used as a filter when deciding which data should be returned by the server in response to the client’s JSON payload. In other words, if you want a key/value pair returned to the client when the session has been successfully started, make sure to include the key name of this desired pair in thefields
list of theconfiguration
section. In the example launcher config above, therefore, we have added the keyupdir
to thefields
filter list so that the"updir":"/Home"
key pair will actually be returned to the client, instead of filtered out.
- Note, however, that in the
resources
is a list of host/port-range combinations that the launcher will keep track of and assign to incoming client requests. The launcher will take the hosts and associated port ranges for each host and create a master list of available “resources” it can assign to clients. For example ifresources
are given as follows:
"resources" : [ { "host" : "host1.example.com", "port_range" : [9001, 9003] }, |
then the launcher will build the following list of “resources”:
[ |
When a request comes in from a client, then the launcher will choose the first available resource, and use it to fulfill the request. The host and port the launcher chooses will be available as ${host}
and ${port}
in both the sessionURL
configuration variable, as well as in any of the application
command lines. When the process associated to the client request eventually ends, the [host, port] combination will again become available for future requests. Until such time, that particular [host, port] combination, or “resource”, is considered by the launcher to be unavailable.
Optional Upload Server
The launcher can now start an optional file upload server to handle multipart POST requests on the same server and port as the launcher itself, as in the launcher config file example, above. By specifying the upload_dir
property in the configuration
section of the launcher config file, you can tell the launcher to start the file upload server in such a way that uploaded files will get written in the path given by the value of the upload_dir
property. In order to use the upload server, you would then issue a POST request with a multipart file attachment to the url http://launcher-host:launcher-port/upload
, replacing launcher-host
and launcher-port
with the correct values.
Python launcher as a front end
It is worth mentioning briefly that the Python launcher can also be used as a front end. Specifying a path for the content
key of the configuration
section of the laucher config json will cause the Python launcher to serve static content from listed directory. The Python launcher can not, however, do websocket forwarding/tunnelling, so in this situation, clients would need direct access to the host/port combinations where the visualization processes are running. Then, the sessionURL
would take this form:
"sessionURL" : "ws://${host}:${port}/ws", |
rather than this one:
"sessionURL": "ws://YOUR_HOST_NAME_TO_REPLACE/proxy?sessionId=${id}&path=ws", |