Installation
Installation on EWC image Ubuntu 18.04.4 ECMWF built
Prepare the python3 environment needed
user@local sudo apt update user@local sudo apt install build-essential user@local sudo apt-get install python3-dev user@local sudo apt-get install python3-pip user@local sudo pip3 install setuptools user@local sudo pip3 install wheel
Install Aviso
user@local sudo pip3 install -e git+https://git.ecmwf.int/scm/lex/aviso.git@master#egg=aviso
Quick Start
Aviso can be used as a Python API or as Command-Line Interface (CLI) application. Here a few steps to quickly get a working configuration listening to notifications.
Create a configuration file in the default location /etc/aviso/config.yaml with the following settings:
username: <user_email> listeners: - event: dissemination request: destination: <user_destination> stream: enfo step: [1,2,3] triggers: - type: echo
The first line is required for a correct authentication, the username is the email associated to the user's ECMWF account. This can be checked by logging at https://api.ecmwf.int/v1/key/.
This file is a basic example of a
dissemination
event listener.request
describes for which dissemination events the user wants to execute the triggers. It is made by a set of fields. Users have to specify only the fields that they wants to use as filters.destination
is a mandatory field and it is associated to one or more destinations which are linked to the user's ECMWF account. Only the notifications complying with all the fields defined will execute the trigger. The trigger in this example isecho
. This will simply print out the notification to the console output.Save the ECMWF key as a file in /etc/aviso/key. The key can be obtained by logging at https://api.ecmwf.int/v1/key/ .
Launch the aviso application
user@local aviso listen
Once in execution this command will create a process waiting for notifications. Users can terminate the application by typing
CTRL+C
Note that the configuration file is read only at start time, therefore every time users make changes to it needs to restart the listening process.
Note that before starting to listen for new notifications, the application checks what was the last notification received and it will then return immediately all the notifications that have been missed since. It will then start listening for new ones. The first ever time the application runs however no previous notification will be returned.
Testing my listener
Aviso provides the capability of submitting test notifications. This functionality can be used to test the listener configuration.
Launch the aviso application in test mode. This allows to connect to a local file-based notification server, part of the aviso application, that is able to simulate the notification server behaviour.
user@local aviso listen --test
The console should display a
Test Mode
message.Send a test notification. From another terminal run the
notify
command. Here an example, matching the example configuration presented above:user@local aviso notify event=dissemination,class=od,date=20190810,destination=<user_destination>,domain=g,expver=1,step=1,stream=enfo,time=0,location=xxxx --test
Note the list of parameters required, the order is not important, but the command requires all of them. The
destination
has to match the one of the listener configuration.After a few seconds, the console output should display the notification, as the trigger is set to
echo
.
Define my listener
Aviso configuration file allows the definition of multiple listeners, each listener is compose or a event
type, a request
block and a triggers
block.
Event
Aviso offers notifications for the following types of events:
- The
dissemination
event is submitted by the product generation. The related listener configuration must define thedestination
field. Note that a notification received by adissemination
listener will contain the fieldlocation
containing the URL to the product notified. The
mars
event is designed for real-time data from the model output. The related listener configuration does not have thedestination
field and has no mandatory fields. Moreover the notification received by this listeners will not contain thelocation
field because the users will be able to access to it by the conventional MARS API.
Request
The table below shows the full list of fields accepted in request
block.
Field | Type | Event | Optional/Mandatory |
---|---|---|---|
destination | String, uppercase | dissemination | Mandatory |
class | Enum | All | Optional |
stream | Enum | All | Optional |
domain | Enum | All | Optional |
expver | Integer | All | Optional |
date | Date (e.g. 20190810 ) | All | Optional |
time | Values (0, 6, 12, 18) | All | Optional |
step | Integer | All | Optional |
Triggers
The triggers
block accepts a sequence of triggers. Each trigger will result in an independent process executed every time a notification is received. This sections shows the type of triggers currently available.
Echo
This is the simplest trigger as it prints the notification to the console output. It does not accept any extra parameters.
triggers: - type: echo
Log
This trigger logs the event to the log file specified. Please note that it will fail if the directory does not exist.
triggers: - type: log path: testLog.log
Command
This trigger allows the user to define a shell command.
triggers: - type: command working_dir: $HOME/aviso/examples command: ./script.sh --date ${request.date} -s ${request.stream} environment: STEP: ${request.step} TIME: "The time is ${request.time}"
command
is the command that will be executed for each notification received. This is a mandatory field.environment
is a user defined list of local variables that will be passed to the command shell. This is an optional field.working_dir
defines the working directory that will be set before executing the command. This is an optional field.
Moreover, the system performs a parameter substitution for every sequence of the patterns ${name}
in the command
and environment
fields. Each sequence is substituted with the value associated to the corresponding key found in the notification received.
A notification is a dictionary whose keys can be used in the parameter substitution mechanism described above. Here an example of a notification:
{ "event": "dissemination", "request": { "class": "od", "date": "20191112", "destination": "FOO", "domain": "g", "expver": "0001", "step": "001", "stream": "enfo", "time": "18" }, "location": "https://xxx.ecmwf.int/xxx/xxx.xx" }
The full notification can be passed in the command by using the keyword ${json}
that will translate the structure in a JSON inline string. Finally, the trigger can save the notification to a JSON file whose file name can be retrieved using the keyword ${jsonpath}
.
Using Aviso as a Python API
Aviso can be used as a Python API. This is intended for user that wants to integrate Aviso in a bigger workflow written in Python or that simply have their trigger defined as a Python function. Below an example of a python script that defines a function to be executed once a notification is received, creates a listener that references to this function trigger and finally passes it to aviso to execute.
The listening will happen in a background thread defined as daemon therefore it is responsibility of the user to keep the main thread alive.
Please note that the user configuration has not been defined in this example, the system will automatically read the configuration file defined above.
from pyaviso import NotificationManager
# define function to be called
def do_something(notification):
# do something with the notification
...
# define the trigger
trigger = {"type": "function", "function": do_something}
# create a event listener request that uses that trigger
request = {"destination": "FOO", "stream": "enfo", "date": 20190810, "time": 0}
listener = {"event": "dissemination", "request": request, "triggers": [trigger]}
listeners = {"listeners": [listener]}
# run it
aviso = NotificationManager()
aviso.listen(listeners=listeners)
# wait ...