Hark! The herald of completion has arrived ... to let you know when your long-running tasks are done.
Project description
Herald of Completion
Hark! The herald of completion has arrived ... to let you know when your long-running tasks are done.
Decorate your functions with messengers, who will send a notification to you when your function has finished running.
The notification can contain a message and, optionally, the traceback if your function failed.
Installation
pip install herald-of-completion
Usage
Wrap the @herald
decorator around the function you want to be notified about:
from herald.decorators import Herald
from herald.messengers import DiscordMessenger
herald = Herald(".env") # Specify location of your .env settings file
# herald is the name of your decorator
discord = DiscordMessenger() # create a new messenger
@herald(discord) # wrap decorator around the function, with the messenger you want to use
def my_function():
a = [1, 2, 3]
return a
You can send multiple messengers at the same time:
from herald.decorators import Herald
from herald.messengers import DiscordMessenger, EmailMessenger
herald = Herald(".env")
discord = DiscordMessenger()
email = EmailMessenger("recipient@email.com") # some messengers take arguments
@herald([discord, email]) # multiple messengers can be used at the same time
def my_function():
a = [1, 2, 3]
return a
Options
By default, Herald will send a basic notification message indicating whether the function finished successfully or with an error. You can pass in a custom message to use instead:
@herald(email, message="My custom message")
Passing send_result=True
to the decorator will send the return value of your function through the messenger. This also includes notifying you of any exceptions that were raised:
@herald(email, send_result=True) # defaults to True
def my_function():
a = [1, 2, 3]
return a[100] # if an exception is raised, `send_result=True` will also send the traceback
Passing send_args=True
will show the args
and kwargs
the function was called with:
@herald(email, send_args=True) # defaults to True
def my_function(var1, var2):
return ", ".join([var1, var2])
my_function("Hello", var2="world") # function call will be notified with all args and kwargs
Manual notifications
There may be times where you want to send a notification without using a decorator / tying it to a specific function.
A utility function, send_notification()
, can be used for this purpose. To use this, you'll need to construct your own TaskInfo
object (see: fields) containing the notification contents:
from herald.types import TaskInfo
from herald.utils import send_notification # import the utility
discord = DiscordMessenger()
email = EmailMessenger()
info = TaskInfo(message="custom message", ...) # create TaskInfo with contents of the message
send_notification([discord, email], info, ".env") # pass in path to your .env file, if required
For more details about usage, the full API documentation can be found here: documentation
.env settings
Some messengers require credentials and/or additional settings to work. These values are stored in a .env
file.
Pass the location of this file to the Herald
constructor, which will pass the values down to your messengers.
The .env
file should look something like this. You only need settings for the messengers you want to use:
# Discord settings
WEBHOOK_URL="https://discord.com/..."
# Email settings
SMTP_SERVER="smtp.gmail.com"
SMTP_PORT=587
SMTP_STARTTLS=True
SMTP_USER="user@gmail.com"
SMTP_PASSWORD="password"
Given the contents of this file, make sure you don't check it in to version control!
Explanation
Name | Value Type | Messenger | Description |
---|---|---|---|
WEBHOOK_URL |
str | Discord | The webhook URL for your server. Instructions here |
SMTP_SERVER |
str | STMP server of the email address you want to send from | |
SMTP_PORT |
int | STMP port of the email address you want to send from | |
SMTP_STARTTLS |
bool | Whether your server uses STARTTLS for authentication | |
SMTP_USER |
str | Your email username | |
SMTP_PASSWORD |
str | Your email password |
Contribution
Creating a new messenger
Creating a new messenger is straightforward and requires only 1 file:
- Create a new module in
src/herald/messengers/
- Your class name should take the form
<Name>Messenger
and inherit the baseMessenger
abstract class. Example:class DiscordMessenger(Messenger): ...
- Your class must implement the abstract methods defined in the base
Messenger
class here - Those methods define how your messenger sets it's secret values, and how it uses those settings to send a notification
- Finally, import your messenger in the
__init__.py
file here. This shortens the import path for users.
The notify()
method of your messenger will receive a TaskInfo dataclass object. You can use the dataclass' fields (e.g. name
, header
) to construct custom notification messages.
Note: Pull requests should be made to the develop
branch.
Tests
Unit and integration tests are located here.
Tests should be run using pytest
.
Code style
The project is formatted using the black
formatter.
Docstrings should follow the Google style (with a few tweaks to help with Sphinx generation of documentation pages). Use the docstrings throughout the codebase as a guide.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for herald-of-completion-0.3.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 695bd8b3b95bf43326c27421034d803e5ccfc020b216f4e239cb6baac1e9cbae |
|
MD5 | d98da8dcb7da3ff48691404460e181eb |
|
BLAKE2b-256 | 37ea3b25ad179c80afb6f692c5164570d08fe4b7b7325e1b66cb529060a95d89 |
Hashes for herald_of_completion-0.3.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 79fdf12d39310712c07b9adbeaaf74c4995d8170c67fc2942095f6e4e4c420dd |
|
MD5 | 94e54a225d23b7e64354da59a13f24f1 |
|
BLAKE2b-256 | 60352dfc45764128b2857c4753ac8045d6ba695cd609705e6b3388dd63127ba8 |