Skip to main content

Hark! The herald of completion has arrived ... to let you know when your long-running tasks are done.

Project description

Herald of Completion

Version pypi CI Issues Donate

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 Email STMP server of the email address you want to send from
SMTP_PORT int Email STMP port of the email address you want to send from
SMTP_STARTTLS bool Email Whether your server uses STARTTLS for authentication
SMTP_USER str Email Your email username
SMTP_PASSWORD str Email Your email password

Contribution

Creating a new messenger

Creating a new messenger is straightforward and requires only 1 file:

  1. Create a new module in src/herald/messengers/
  2. Your class name should take the form <Name>Messenger and inherit the base Messenger abstract class. Example: class DiscordMessenger(Messenger): ...
  3. Your class must implement the abstract methods defined in the base Messenger class here
  4. Those methods define how your messenger sets it's secret values, and how it uses those settings to send a notification
  5. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

herald-of-completion-0.3.0.tar.gz (25.2 kB view hashes)

Uploaded Source

Built Distribution

herald_of_completion-0.3.0-py3-none-any.whl (24.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page