mirror of https://github.com/caronc/apprise
Updated Development_API (markdown)
parent
fd2cc44d82
commit
1696fc307c
|
@ -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 department’s 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_ | [](https://github.com/caronc/apprise/tree/master/apprise/assets/themes/default) |
|
| `NotifyType.INFO` | `info` |  |
|
||||||
| **NotifyType.SUCCESS** | _success_ | [](https://github.com/caronc/apprise/tree/master/apprise/assets/themes/default) |
|
| `NotifyType.SUCCESS` | `success` |  |
|
||||||
| **NotifyType.WARNING** | _warning_ | [](https://github.com/caronc/apprise/tree/master/apprise/assets/themes/default) |
|
| `NotifyType.WARNING` | `warning` |  |
|
||||||
| **NotifyType.FAILURE** | _failure_ | [](https://github.com/caronc/apprise/tree/master/apprise/assets/themes/default) |
|
| `NotifyType.FAILURE` | `failure` |  |
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue