|
| 1 | +# prefect-email |
| 2 | + |
| 3 | +<p align="center"> |
| 4 | + <a href="https://pypi.python.org/pypi/prefect-email/" alt="PyPI version"> |
| 5 | + <img alt="PyPI" src="https://img.shields.io/pypi/v/prefect-email?color=0052FF&labelColor=090422"></a> |
| 6 | + <a href="https://pepy.tech/badge/prefect-email/" alt="Downloads"> |
| 7 | + <img src="https://img.shields.io/pypi/dm/prefect-email?color=0052FF&labelColor=090422" /></a> |
| 8 | +</p> |
| 9 | + |
| 10 | +Visit the full docs [here](https://PrefectHQ.github.io/prefect-email) to see additional examples and the API reference. |
| 11 | + |
| 12 | +`prefect-email` is a collection of prebuilt Prefect integrations that can be used to interact with email services. |
| 13 | + |
| 14 | +## Getting Started |
| 15 | + |
| 16 | +### Integrate with Prefect flows |
| 17 | + |
| 18 | +`prefect-email` makes sending emails effortless, giving you peace of mind that your emails are being sent as expected. |
| 19 | + |
| 20 | +First, install [prefect-email](#installation) and [save your email credentials to a block](#saving-credentials-to-block) to run the examples below! |
| 21 | + |
| 22 | +```python |
| 23 | +from prefect import flow |
| 24 | +from prefect_email import EmailServerCredentials, email_send_message |
| 25 | + |
| 26 | +@flow |
| 27 | +def example_email_send_message_flow(email_addresses): |
| 28 | + email_server_credentials = EmailServerCredentials.load("BLOCK-NAME-PLACEHOLDER") |
| 29 | + for email_address in email_addresses: |
| 30 | + subject = email_send_message.with_options(name=f"email {email_address}").submit( |
| 31 | + email_server_credentials=email_server_credentials, |
| 32 | + subject="Example Flow Notification using Gmail", |
| 33 | + msg="This proves email_send_message works!", |
| 34 | + email_to=email_address, |
| 35 | + ) |
| 36 | + |
| 37 | +example_email_send_message_flow(["EMAIL-ADDRESS-PLACEHOLDER"]) |
| 38 | +``` |
| 39 | + |
| 40 | +Outputs: |
| 41 | + |
| 42 | +```bash |
| 43 | +16:58:27.646 | INFO | prefect.engine - Created flow run 'busy-bat' for flow 'example-email-send-message-flow' |
| 44 | +16:58:29.225 | INFO | Flow run 'busy-bat' - Created task run 'email someone@gmail.com-0' for task 'email someone@gmail.com' |
| 45 | +16:58:29.229 | INFO | Flow run 'busy-bat' - Submitted task run 'email someone@gmail.com-0' for execution. |
| 46 | +16:58:31.523 | INFO | Task run 'email someone@gmail.com-0' - Finished in state Completed() |
| 47 | +16:58:31.713 | INFO | Flow run 'busy-bat' - Finished in state Completed('All states completed.') |
| 48 | +``` |
| 49 | + |
| 50 | +Please note, many email services, like Gmail, require an [App Password](https://support.google.com/accounts/answer/185833) to successfully send emails. If you encounter an error similar to `smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted...`, it's likely you are not using an App Password. |
| 51 | + |
| 52 | +### Capture exceptions and notify by email |
| 53 | + |
| 54 | +Perhaps you want an email notification with the details of the exception when your flow run fails. |
| 55 | + |
| 56 | +`prefect-email` can be wrapped in an `except` statement to do just that! |
| 57 | + |
| 58 | +```python |
| 59 | +from prefect import flow |
| 60 | +from prefect.context import get_run_context |
| 61 | +from prefect_email import EmailServerCredentials, email_send_message |
| 62 | + |
| 63 | +def notify_exc_by_email(exc): |
| 64 | + context = get_run_context() |
| 65 | + flow_run_name = context.flow_run.name |
| 66 | + email_server_credentials = EmailServerCredentials.load("email-server-credentials") |
| 67 | + email_send_message( |
| 68 | + email_server_credentials=email_server_credentials, |
| 69 | + subject=f"Flow run {flow_run_name!r} failed", |
| 70 | + msg=f"Flow run {flow_run_name!r} failed due to {exc}.", |
| 71 | + email_to=email_server_credentials.username, |
| 72 | + ) |
| 73 | + |
| 74 | +@flow |
| 75 | +def example_flow(): |
| 76 | + try: |
| 77 | + 1 / 0 |
| 78 | + except Exception as exc: |
| 79 | + notify_exc_by_email(exc) |
| 80 | + raise |
| 81 | + |
| 82 | +example_flow() |
| 83 | +``` |
| 84 | + |
| 85 | +## Resources |
| 86 | + |
| 87 | +For more tips on how to use tasks and flows in a Collection, check out [Using Collections](https://docs.prefect.io/collections/usage/)! |
| 88 | + |
| 89 | +### Installation |
| 90 | + |
| 91 | +Install `prefect-email` with `pip`: |
| 92 | + |
| 93 | +```bash |
| 94 | +pip install prefect-email |
| 95 | +``` |
| 96 | + |
| 97 | +Then, register to [view the block](https://docs.prefect.io/ui/blocks/) on Prefect Cloud: |
| 98 | + |
| 99 | +```bash |
| 100 | +prefect block register -m prefect_email |
| 101 | +``` |
| 102 | + |
| 103 | +Note, to use the `load` method on Blocks, you must already have a block document [saved through code](https://docs.prefect.io/concepts/blocks/#saving-blocks) or [saved through the UI](https://docs.prefect.io/ui/blocks/). |
| 104 | + |
| 105 | +Requires an installation of Python 3.8+. |
| 106 | + |
| 107 | +We recommend using a Python virtual environment manager such as pipenv, conda or virtualenv. |
| 108 | + |
| 109 | +These tasks are designed to work with Prefect 2. For more information about how to use Prefect, please refer to the [Prefect documentation](https://docs.prefect.io/). |
| 110 | + |
| 111 | +### Saving credentials to block |
| 112 | + |
| 113 | +Note, to use the `load` method on Blocks, you must already have a block document [saved through code](https://docs.prefect.io/concepts/blocks/#saving-blocks) or [saved through the UI](https://docs.prefect.io/ui/blocks/). |
| 114 | + |
| 115 | +Below is a walkthrough on saving block documents through code. |
| 116 | + |
| 117 | +Create a short script, replacing the placeholders. |
| 118 | + |
| 119 | +```python |
| 120 | +from prefect_email import EmailServerCredentials |
| 121 | + |
| 122 | +credentials = EmailServerCredentials( |
| 123 | + username="EMAIL-ADDRESS-PLACEHOLDER", |
| 124 | + password="PASSWORD-PLACEHOLDER", # must be an app password |
| 125 | +) |
| 126 | +credentials.save("BLOCK-NAME-PLACEHOLDER") |
| 127 | +``` |
| 128 | + |
| 129 | +Congrats! You can now easily load the saved block, which holds your credentials: |
| 130 | + |
| 131 | +```python |
| 132 | +from prefect_email import EmailServerCredentials |
| 133 | + |
| 134 | +EmailServerCredentials.load("BLOCK_NAME_PLACEHOLDER") |
| 135 | +``` |
| 136 | + |
| 137 | +!!! info "Registering blocks" |
| 138 | + |
| 139 | + Register blocks in this module to |
| 140 | + [view and edit them](https://docs.prefect.io/ui/blocks/) |
| 141 | + on Prefect Cloud: |
| 142 | + |
| 143 | + ```bash |
| 144 | + prefect block register -m prefect_email |
| 145 | + ``` |
0 commit comments