Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quickstart

The fastest path from nothing to a working notification. Pick the surface you have, follow the four steps, and you are done.

1. Get the binary

pip install pyaviso
aviso --version

The Python package bundles the aviso command-line tool, so pip is all you need. If you prefer a Rust-native install, cargo install aviso-cli gives you the same command. The full install guide is at Install.

2. Point at a server

Tell aviso where the server is and how to authenticate. The simplest way is environment variables:

export AVISO_BASE_URL=https://aviso.example
export AVISO_TOKEN=your-bearer-token

Or pass them on the command line each time, with --base-url and --token.

If you would rather keep them in a file, see CLI configuration.

3. Discover notification types

First, see which notification types the server offers:

aviso schema list

For a server configured with just the example mars type, the terminal output is:

1 schema(s) registered (status: success)
- mars

This lists registered notification types, not stored notifications or data files. Pick a type from your server’s list and inspect its schema to see which identifiers you can filter on:

aviso schema get mars

Example output from a server with a minimal mars schema:

{
  "event_type": "mars",
  "schema": {
    "identifier": {
      "class": {
        "description": "MARS class.",
        "required": true,
        "type": "EnumHandler",
        "values": [
          "od",
          "rd"
        ]
      }
    },
    "payload": {
      "required": false
    }
  },
  "status": "success"
}

Here, class is required in the listener’s filter. EnumHandler means its value must come from the listed values, od or rd. We will choose od below. The payload is optional for notifications of this type.

This JSON describes the schema already registered on the server; it is command output, not a configuration file to install. Your server may offer other types or require more identifiers. Use its schema to choose the event type and supply all required identifiers in the examples below.

4. Listen for something

For the example schema above, listen for mars notifications with class=od:

aviso listen --event mars --identifiers '{"class":"od"}'

Press Ctrl+C to stop.

Every matching notification prints to your terminal as JSON. When you redirect the output to a file or pipe it into another tool, the format changes to one compact JSON object per line so you can chain it with jq:

aviso listen --event mars --identifiers '{"class":"od"}' | jq -r '.payload'

That is it. You have a working listener.

What just happened

  • aviso connected to the server and opened a long-lived stream.
  • It asked for mars events with class=od.
  • It echoed each match to your terminal.
  • It remembered the last notification it printed in ~/.config/aviso/state.json, so the next run starts after that point.

Re-running the same command resumes from where you left off. A notification can still be redelivered after a crash or failed checkpoint, so production triggers should be safe to run more than once. To start fresh next time, add --no-state-store.

Calling aviso from Python

The same listener as step 4, through the native Python API. The pip install pyaviso from step 1 already gave you the pyaviso package, and pyaviso.Env() reads the same environment variables you exported in step 2:

"""Listen for mars notifications and print each one as it arrives."""

import os
import pyaviso

client = pyaviso.AvisoClient(base_url=os.environ["AVISO_BASE_URL"], auth=pyaviso.Env())

for notification in client.listen("mars", filter={"class": "od"}):
    print(f"seq={notification.sequence} payload={notification.payload}")

Notifications arrive as typed objects with sequence, identifier, and payload fields, so there is no JSON to re-parse. Publishing, resuming across restarts, async, and error handling are covered in the Python section, starting with its quickstart.

Calling aviso from a Rust program

use std::collections::BTreeMap;
use aviso::{
    watch::{Trigger, WatchRequest},
    AvisoClient,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = AvisoClient::builder()
        .base_url("https://aviso.example")
        .build()?;

    let mut filter = BTreeMap::new();
    filter.insert("class".to_string(), serde_json::json!("od"));

    let req = WatchRequest::watch("mars")
        .with_filter(filter)
        .with_triggers(vec![Trigger::echo()]);

    let mut stream = client.watch(req)?;
    while let Some(notification) = stream.recv().await {
        let n = notification?;
        println!("seq {}: {}", n.sequence, n.payload);
    }
    Ok(())
}

The filter must include any identifier the event type’s schema marks required: true (run aviso schema get <TYPE> to see which).

The full library walkthrough is in the library guide.

Next