Skip to content

Advanced Usage

If you are running inside an asyncio event loop, you can use async_notify() to send notifications without blocking.

import asyncio
import apprise
async def main():
apobj = apprise.Apprise()
apobj.add('mailto://user:pass@example.com')
# Await the notification delivery -- like notify(), this returns an
# AppriseResult, so capture it if you care whether delivery succeeded
result = await apobj.async_notify(
title='Async Test',
body='This was sent asynchronously',
)
if not result:
print("Delivery failed:", result.status.name)
asyncio.run(main())

See Notification Results for everything result can tell you (per-service detail, timing, captured logs, and more).

Apprise objects can be serialized (pickled). This allows you to configure an Apprise object once, save it to disk (or a database), and reload it later with all services configured.

import apprise
import pickle
# 1. Setup
apobj = apprise.Apprise()
apobj.add("json://localhost")
# 2. Serialize
serialized_data = pickle.dumps(apobj)
# ... later in your code ...
# 3. Restore
restored_obj = pickle.loads(serialized_data)
restored_obj.notify("I am back!")

Low-Level: The Apprise Notification Object

Section titled “Low-Level: The Apprise Notification Object”

When you call Apprise.notify(), it handles tagging, configuration, and logging for you. If you need to bypass this and interact directly with a specific notification object:

import apprise
# Instantiate a single notification object directly
# (Bypassing the Apprise() manager)
obj = apprise.Apprise.instantiate('glib://')
# Send raw content
obj.send(
body="Raw message",
title="Raw title"
)

Apprise raises AppriseImproperlyConfigured when a library call receives missing, invalid, or conflicting settings. Catch it when your application needs to report a configuration problem:

from apprise import AppriseAsset
from apprise.exception import AppriseImproperlyConfigured
try:
asset = AppriseAsset(service_timeout=-1)
except AppriseImproperlyConfigured as error:
print(f"Invalid Apprise settings: {error}")

Existing handlers for TypeError, ValueError, or AttributeError continue to work. New code should catch AppriseImproperlyConfigured so configuration problems are easier to identify.

All Apprise-specific exceptions inherit from AppriseException, which provides one catch-all when your application does not need to distinguish the cause. Disk failures reported as AppriseDiskIOError can also be caught as OSError. Plugin-specific failures based on ApprisePluginException can be handled together when their individual details are not needed.

notify() and async_notify() report these problems in their return value instead of raising exceptions.

A service that fails before preparing its message gets its own FAILURE entry, just like one that fails while sending. Other services still run, escalation continues, and optional services remain optional. A call with mixed outcomes reports PARTIAL.

If Apprise cannot use the message, the whole call reports FAILURE with no service entries and sends nothing. An invalid timeout= value is the only case these methods still raise for.

Apprise sends every notification over requests, which honours the standard HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables automatically. No Apprise-specific configuration is required. Set the variable before your process starts (or export it in the environment Apprise runs under) and every outbound request routes through the proxy:

Terminal window
export HTTPS_PROXY="http://127.0.0.1:3128"
export HTTP_PROXY="http://127.0.0.1:3128"
python3 my_script.py

If you only want Apprise to proxy (and not the rest of your application), scope the variable to the subprocess or environment that runs Apprise rather than exporting it globally. Set it inline for a single command, for example, or in a systemd unit’s Environment= directive for a long-running service.

NO_PROXY is also honoured, letting you exempt specific hosts:

Terminal window
export HTTPS_PROXY="http://127.0.0.1:3128"
export NO_PROXY="localhost,127.0.0.1,internal.example.com"
Questions or Feedback?

Documentation

Notice a typo or an error?

Technical Issues

Having trouble with the code? Open an issue on GitHub:

Made with love from Canada