Updated Development_API (markdown)

master
Chris Caron 2025-06-07 16:28:37 -04:00
parent fd2cc44d82
commit 1696fc307c
1 changed files with 176 additions and 249 deletions

@ -1,313 +1,240 @@
# Table of Contents # Table of Contents
<!--ts--> <!--ts-->
* [Development API](#development-api) * [Development API](#development-api)
* [The Apprise Object](#the-apprise-object) * [The Apprise Object](#the-apprise-object)
* [`add()`](#add-add-a-new-notification-service-by-urls) * [`add()`](#add-register-notification-services)
* [`notify()`](#notify--send-notifications) * [`notify()`](#notify-send-notifications)
* [`len()`](#len-returns-number-of-notification-services-loaded) * [`async_notify()`](#async_notify-awaitable-notifications)
* [`clear()`](#clear-reset-our-apprise-object) * [`len()`](#len-count-services)
* [`details()`](#details-dynamic-view-into-available-notification-services-apprise-offers) * [`clear()`](#clear-reset-service-list)
* [`async_notify()`](#async_notify--leveraging-await-to-send-notifications) * [`details()`](#details-inspect-configuration--schemas)
* [The Apprise Asset Object](#the-appriseasset-object) * [The AppriseAsset Object](#the-appriseasset-object)
* [The Apprise Notification Object](#the-apprise-notification-object) * [The Apprise Notification Object](#the-apprise-notification-object)
* **Features**: * **Features**
* [Pickle Support](#pickleserialization-support) * [Pickle/Serialization Support](#pickleserialization-support)
<!--te--> <!--te-->
# Development API
Apprise is very easy to use as a developer. The **Apprise()** object handles everything for you, meanwhile the **AppriseAsset()** Object allows you to stray away from some default configuration to personalize the users experience (and perhaps fit your application better):
* **[[The Apprise Object|Development_API#the-apprise-object]]**
* **[[The Apprise Asset Object|Development_API#the-apprise-asset-object]]**
Some additional functionality is available via the **[[The Apprise Notification Object|Development_API#the-apprise-notification-object]]** for those who want to manage the notifications themselves.
Another useful class that can help you out with sending notifications is the **[[The LogCapture Object|Development_LogCapture]]**. It can be used to capture the events that surrounded the success (and potential failure) of the notifications being delivered so that you can work with them.
## The Apprise Object ## The Apprise Object
The Apprise() object is the heart and soul of this library. To instantiate an instance of the object, one might do the following:
### Instantiation
```python ```python
# Import this library
import apprise import apprise
# create an Apprise instance and assign it to variable `apobj`
apobj = apprise.Apprise() apobj = apprise.Apprise()
``` ```
### add(): Add a New Notification Service By URL(s) ---
Use the **add()** function to append the notification URLs we want to provide notifications for.
### `add()`: Register Notification Services
Add one or more service URLs to your notification pool:
```python ```python
# Add all of the notification services by their server url. # Single service
# A sample email notification ok = apobj.add('mailto://user:pass@example.com')
isokay = apobj.add('mailto://myemail:mypass@gmail.com')
# add() will return a True if the URL was successfully parsed and added into # Multiple services
# our notification pool. Otherwise it returns False. ok = apobj.add([
'growl://192.168.1.50',
# A sample pushbullet notification
isokay = apobj.add('pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b')
# You can additionally add URLs via a list/set/tuple:
isokay = apobj.add([
# A sample growl service
'growl://192.168.40.23',
# Our Microsoft Windows desktop
'windows://', 'windows://',
]) ])
``` ```
- **Returns**: `True` if all URLs parsed and added; `False` otherwise.
---
### `notify()`: Send Notification(s)
Send to all—or filter by tag:
```python
# Broad notification
apobj.notify(
title='Deployment Complete',
body='Version 2.1.0 has been successfully deployed!',
)
# Filtered by tag
apobj.notify(
title='Error Alert',
body='Service X failed to respond',
tag='critical'
)
```
#### Tagging #### Tagging
Tagging is a great way to add a richer experience to the notification flow.
You can associate one or more _tags_ with the notifications you choose to **add()**. Doing so grants you to flexibility to later call _on just some_ (_or all_) of the services you added. It effectively grants you the additional ability to filter notifications based on your workflow.
Here is an example: Apprise tagging allows you to group and filter notifications. Two main design patterns exist:
```python
# import our library
import apprise
# Create our object 1. **Inclusive**
apobj = apprise.Apprise() Define department- or role-based tags and notify any combination:
# Add a tag by a simple string ```python
apobj.add('json://localhost/tagA/', tag="TagA") import apprise
# Add 2 tags by string; the comma and/or space auto delimit apobj = apprise.Apprise()
# our entries (spaces and comma's are ignored):
apobj.add('json://localhost/tagAB/', tag="TagA, TagB")
# Add 2 tags using a list; this works with tuples and sets too! # 1. Register each departments notification endpoint with its tag
apobj.add('json://localhost/tagCD/', tag=["TagC", "TagD"]) apobj.add('slack://hooks.slack.com/services/FINANCE_WEBHOOK_URL', tag='finance')
``` apobj.add('slack://hooks.slack.com/services/DEVOPS_WEBHOOK_URL', tag='devops')
apobj.add('slack://hooks.slack.com/services/DEVELOPERS_WEBHOOK_URL', tag='developers')
apobj.add('slack://hooks.slack.com/services/MANAGEMENT_WEBHOOK_URL', tag='management')
### notify() : Send Notification(s) # 2. Now fire notifications to whichever groups you need:
You can now send a notification to all of the loaded notifications services by just providing it a **title** and a **body** like so:
```python
# Then notify these services any time you desire. The below would
# notify all of the services loaded into our Apprise object.
apobj.notify(
body='what a great notification service!',
title='my notification title',
)
```
Developers should know that Apprise passes everything it gets _as is_ which will work for most circumstances. However sometimes it's useful to let apprise know the data you're feeding it. This information is used to guarantee that the upstream provider can handle the content, and if it can't, it _will be modified_ so that it does. # A budget alert → finance team only
```python apobj.notify(
# Include the NotifyFormat object title='Budget Exceeded',
from apprise import NotifyFormat body='Q2 marketing spend is now 120% of planned.',
tag='finance'
)
# our body might be read from a file, it might be just input from # A CI/CD pipeline failure → devops AND developers
# our end users apobj.notify(
body=""" title='Pipeline Failed',
...a lot of content body='Build #492 on main branch failed unit tests.',
that could span multiple lines ... tag=['devops', 'developers']
""" )
# Now we can send our notification while controlling the input source # A high-level executive summary → management only
# and knowing the upstream plugins will be able to handle it apobj.notify(
apobj.notify( title='Monthly Operations Summary',
body=body, body='All systems green; revenue +8% month-over-month.',
# Possible formats are TEXT, MARDOWN, and HTML tag='management'
body_format=NotifyFormat.TEXT, )
)
```
### async_notify() : Leveraging Await to Send Notification(s) # A system-wide alert → broadcast to all teams
Under the hood, Apprise will attempt to send all of your notifications asynchronously which means it will acquire it's own event loop. If you already have one going, then you can still send your notifications using `await` like so: apobj.notify(
```python title='Service Outage',
import asyncio body='API gateway is down; investigating root cause.',
tag=['finance', 'devops', 'developers', 'management']
)
```
async my_event_loop(): 2. **Exclusive**
# assumes you declared your apobj (as identified above) Use specialized tags (e.g. `'warning-download'`, `'warning-upload'`). Apprise ignores unmatched tags silently.
# You can trigger it asynchronously now like so:
results = await apobj.async_notify(
body='what a great async friendly notification service!',
title='my notification title')
loop = asyncio.get_event_loop() ```python
loop.run_until_complete(main()) # Add services expecting specific warnings
``` apobj.add('json://localhost/download/', tag='warning-download')
apobj.add('json://localhost/upload/', tag='warning-upload')
#### Leverage Tagging # Only 'warning-upload' triggers
If you associated tags with your notification services when you called **add()** earlier, you can leverage it's full potential through the **notify()** function here. Tagging however allows you to trigger notifications only when a criteria is met. The tagging logic can be interpreted as follows: apobj.notify(
title='Upload Issue',
body='Upload failed',
tag='warning-upload'
)
| apprise.notify(tag=_match_) | Notify Services Having Tag(s): | # 'warning-parse' is ignored if no service has that tag
| -------------------------------- | ------------------------------ | apobj.notify(
| "TagA" | TagA title='Parse Problem',
| "TagA, TagB" | TagA **OR** TagB body='Parse failed',
| ['TagA', 'TagB'] | TagA **OR** TagB tag='warning-parse'
| [('TagA', 'TagC'), 'TagB'] | (TagA **AND** TagC) **OR** TagB )
| [('TagB', 'TagC')] | TagB **AND** TagC ```
Now that we've added our services and assigned them tags, this is how we can access them: General filter expressions follow:
```python
# Has TagA
apobj.notify(
body="a body", title='a title', tag="tagA")
# Has TagA OR TagB | Filter | Selected services |
apobj.notify( |-------------------------------|-----------------------------------------------|
body="a body", title='a title', tag=["tagA", "TagB"]) | `'TagA'` | Has **TagA** |
| `['TagA', 'TagB']` | **OR** between tags |
| `[('TagA','TagC'), 'TagB']` | (**AND** within tuple) **OR** others |
| `[('TagB','TagC')]` | **AND** between tags |
# Has TagA AND TagB ---
apobj.notify(
body="a body", title='a title', tag=[("tagA", "TagB")])
# Has TagA OR TagB OR (TagC AND TagD)
apobj.notify(
body="a body", title='a title', tag=["tagA", "TagB", ["TagC", "TagD"]])
# No reference to tags; alert all of the added services
apobj.notify(body="my body", title="my title")
```
#### Tagging and Categories
Another use case for tagging might be to instead interpret them as categories. A system owner could simply fill their code with clean logic like:
```python
#... stuff happening
apobj.notify(body="a body", title='a title', tag="service-message")
# ... uh oh, something went wrong
apobj.notify(body="a body", title='a title', tag="debug-message")
# ... more stuff happening
apobj.notify(body="a body", title='a title', tag="broadcast-notice")
# ...
```
The idea would be that somewhere when the Apprise Object (_apobj_) was first created, you (as a system owner) would have retrieved the user settings and only load the tags based on what they're interested in:
```python
# import our library
import apprise
# Create our object
apobj = apprise.Apprise()
# Poll our user for their setting and add them
apobj.add('mailto://myuser:theirpassword@hotmail.com', tag=[
# Services we want our user subscribed to:
"service-message",
"broadcast-notice"
])
```
**Takeaway**: In this example (above), the user would never be notified for "_debug-message_" calls. Yet the developer of this system does not need to provide any additional logic around the apprise calls other than the _tag_ that should trigger the notification. Just let _Apprise_ handle the logic of what notifications to send for you.
#### Message Types and Themes #### Message Types and Themes
By default, all notifications are sent as type **NotifyType.INFO** using the _default_ theme. The following other types are included with this theme:
By default, all notifications use `NotifyType.INFO` with the `default` theme. Available types:
| Notification Type | Text Representation | Image | | Notification Type | Text Representation | Image |
| -------------------- | ------------------- | ----- | |---------------------------|---------------------|-------|
| **NotifyType.INFO** | _info_ | [![Build Status](https://github.com/caronc/apprise/blob/master/apprise/assets/themes/default/apprise-info-72x72.png)](https://github.com/caronc/apprise/tree/master/apprise/assets/themes/default) | | `NotifyType.INFO` | `info` | ![info](https://raw.githubusercontent.com/caronc/apprise/master/apprise/assets/themes/default/apprise-info-72x72.png) |
| **NotifyType.SUCCESS** | _success_ | [![Build Status](https://github.com/caronc/apprise/blob/master/apprise/assets/themes/default/apprise-success-72x72.png)](https://github.com/caronc/apprise/tree/master/apprise/assets/themes/default) | | `NotifyType.SUCCESS` | `success` | ![success](https://raw.githubusercontent.com/caronc/apprise/master/apprise/assets/themes/default/apprise-success-72x72.png) |
| **NotifyType.WARNING** | _warning_ | [![Build Status](https://github.com/caronc/apprise/blob/master/apprise/assets/themes/default/apprise-warning-72x72.png)](https://github.com/caronc/apprise/tree/master/apprise/assets/themes/default) | | `NotifyType.WARNING` | `warning` | ![warning](https://raw.githubusercontent.com/caronc/apprise/master/apprise/assets/themes/default/apprise-warning-72x72.png) |
| **NotifyType.FAILURE** | _failure_ | [![Build Status](https://github.com/caronc/apprise/blob/master/apprise/assets/themes/default/apprise-failure-72x72.png)](https://github.com/caronc/apprise/tree/master/apprise/assets/themes/default) | | `NotifyType.FAILURE` | `failure` | ![failure](https://raw.githubusercontent.com/caronc/apprise/master/apprise/assets/themes/default/apprise-failure-72x72.png) |
Use a different type:
Should you want to send a notification using a different status, simply include it as part of your **notify()** call:
```python ```python
# Import our NotifyType
from apprise import NotifyType from apprise import NotifyType
# Then notify these services any time you desire. The below would
# notify all of the services loaded into our Apprise object as a WARNING.
apobj.notify( apobj.notify(
body='what a great notification service!', title='Disk Space Low',
title='my notification title', body='Only 5% left',
notify_type=NotifyType.WARNING, notify_type=NotifyType.WARNING,
) )
``` ```
You can alter the theme as well; this is discussed lower down using the [[the Apprise Asset Object|Development_API#the-apprise-asset-object]]. ---
### len(): Returns Number of Notification Services loaded ### `async_notify()`: Awaitable Notifications
Use inside your existing asyncio loop:
We can retrieve a list of the active and loaded notification services by using python's built in
**len()** function.
```python ```python
# len(apobj) returns the number of notifications loaded import asyncio
# the below calls this and prints it to the screen:
print("There are %d notification services loaded" % len(apobj)) async def main():
results = await apobj.async_notify(
title='Async Test',
body='This was sent asynchronously',
)
print(results)
asyncio.run(main())
``` ```
### clear(): Reset our Apprise Object
If you ever want to reset our Apprise object, and eliminate all of the services we had previously loaded into it, you can use the **clear()** function. ---
### `len()`: Count Services
```python
print(f"There are {len(apobj)} services loaded")
```
---
### `clear()`: Reset Service List
```python ```python
# clears out all of the loaded notification services associated with our
# Apprise Object.
apobj.clear() apobj.clear()
``` ```
### details(): Dynamic View Into Available Notification Services Apprise Offers
Developers who wish to be able to generate information based on this library dynamically can use the *details()** function: ---
### `details()`: Inspect Configuration & Schemas
```python ```python
# returns an object containing details about the plugin for dynamic integration. info = apobj.details()
apobj.details()
``` ```
The output will look like:
Returns a `dict` containing:
- **version** — Apprise version
- **asset** — current `AppriseAsset` settings
- **schemas** — supported services and URLs
- **details** — templates, tokens, args, kwargs
<details>
<summary>Example JSON</summary>
```json ```json
{ {
"version": "0.5.2", "version": "1.0.0",
"asset": { "asset": { /* ... */ },
"default_extension": ".png", "schemas": [ /* ... */ ],
"app_desc": "Apprise Notifications", "details": { /* ... */ }
"image_path_mask": "https://github.com/caronc/apprise/raw/master/apprise/assets/themes/{THEME}/apprise-{TYPE}-{XY}{EXTENSION}",
"app_id": "Apprise",
"theme": "default",
"image_url_logo": "https://github.com/caronc/apprise/raw/master/apprise/assets/themes/{THEME}/apprise-logo.png",
"image_url_mask": "https://github.com/caronc/apprise/raw/master/apprise/assets/themes/{THEME}/apprise-{TYPE}-{XY}{EXTENSION}"
},
"schemas": [
{
"service_name": "Boxcar",
"setup_url": "https://github.com/caronc/apprise/wiki/Notify_boxcar",
"service_url": "https://boxcar.io/",
"protocols": null,
"secure_protocols": [
"boxcar"
]
},
{
"service_name": "Discord",
"setup_url": "https://github.com/caronc/apprise/wiki/Notify_discored",
"service_url": "https://discordapp.com/",
"protocols": null,
"secure_protocols": [
"discord"
]
},
{
"service_name": "E-Mail",
"setup_url": "https://github.com/caronc/apprise/wiki/Notify_email",
"service_url": null,
"protocols": [
"mailto"
],
"secure_protocols": [
"mailtos"
]
},
"... etc, ..."
],
"details": {
"templates": {
...
},
"tokens": {
...
},
"args": {
...
},
"kwargs": {
...
},
},
} }
``` ```
The idea behind the **details()** function is that it allows developers to pass details back through their program letting their users know what notifications are supported. Thus as this library deprecates and introduces new notification services, calling front end applications (built around the **details()** function) can automatically serve this information back to their user base. </details>
More detailed information about this object can be found [[here|Development_Apprise_Details]]. ---
## The AppriseAsset Object ## The AppriseAsset Object