Skip to main content

replyowl

Email reply body generator for HTML and text in Python

License PyPI Python CI Coverage Renovate GitHub stars

replyowl

replyowl creates email bodies with quoted messages. Provide the original message and your reply message, and replyowl will combine them into a new message. The returned content can be used as the text and/or HTML body content of a new email. HTML-to-text conversion is performed with html2text.

Installation

pip install replyowl

Usage

from replyowl import ReplyOwl

owl = ReplyOwl()
text, html = owl.compose_reply(
    content="<i>New</i> reply <b>content</b>",
    quote_attribution="You wrote:",
    quote_text="Original message text",
    quote_html="<b>Original</b> message text",
)

print(text)
# _New_ reply **content**
#
# ----
#
# You wrote:
#
# > Original message text

print(html)  # (output formatted for readability)
# <!DOCTYPE html>
# <html>
#   <head>
#     <title></title>
#   </head>
#   <body>
#     <i>New</i> reply <b>content</b>
#     <div>You wrote:<br />
#     </div>
#     <blockquote style="margin-left: 0.8ex; padding-left: 2ex;
#                        border-left: 2px solid #aaa; border-radius: 8px;" type="cite">
#       <b>Original</b> message text
#     </blockquote>
#   </body>
# </html>

Links in HTML are preserved when creating plain text email bodies:

from replyowl import ReplyOwl

owl = ReplyOwl()
text, html = owl.compose_reply(
    content=(
        'Check <a href="https://example.com/">this</a> out<br />'
        'Or this: <a href="https://example.net/">https://example.net/</a>'
    ),
    quote_attribution="You wrote:",
    quote_text="Send me a URL",
    quote_html="Send me a <i>URL</i>",
)

print(text)
# Check this (https://example.com/) out
# Or this: https://example.net/
#
# ----
#
# You wrote:
#
# > Send me a URL

If the quoted HTML content contains a <body> tag, that is preserved:

from replyowl import ReplyOwl

owl = ReplyOwl()
text, html = owl.compose_reply(
    content="Hello there",
    quote_attribution="You wrote:",
    quote_text="Hi",
    quote_html='<html><body class="sender_body"><b>Hi</b></body></html>',
)

print(html)  # (output formatted for readability)
# <html>
#   <body class="sender_body">
#     Hello there
#     <div>
#     You wrote:<br/>
#     </div>
#     <blockquote style="margin-left: 0.8ex; padding-left: 2ex;
#                        border-left: 2px solid #aaa; border-radius: 8px;" type="cite">
#       <b>Hi</b>
#     </blockquote>
#   </body>
# </html>

A custom value can be provided for the <blockquote>'s style tag:

from replyowl import ReplyOwl

owl = ReplyOwl(blockquote_style="font-weight: bold;")
text, html = owl.compose_reply(
    text, html = owl.compose_reply(
        content="Your quote is in bold",
        quote_attribution="You wrote:",
        quote_text="I'm going to be in bold when you reply",
        quote_html="I'm going to be in bold when you reply",
    )
)

print(html)  # (output formatted for readability)
# <html>
#   <body class="sender_body">
#     Your quote is in bold
#     <div>
#     You wrote:<br/>
#     </div>
#     <blockquote style="font-weight: bold;" type="cite"
#       I'm going to be in bold when you reply
#     </blockquote>
#   </body>
# </html>

License

Copyright (C) 2022 Stephen Kent and contributors

Licensed under the GNU Lesser General Public License v3.0 or later (LGPL-3.0-or-later).

Project template

This project is based on and maintained with copier-project.

Metadata

Release files for replyowl 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for replyowl 0.3.1
File Size Uploaded Provenance Actions
replyowl-0.3.1.tar.gz 25.6 kB With provenance Details for replyowl-0.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for replyowl 0.3.1
File Interpreter ABI Platform Actions
replyowl-0.3.1-py3-none-any.whl Python 3 none any Details for replyowl-0.3.1-py3-none-any.whl

Total release size: 45.1 kB

Release files / replyowl-0.3.1.tar.gz

Download URL replyowl-0.3.1.tar.gz
Size 25.6 kB
Tags Source
SHA-256 checksum
How to use checksums
69353221eb729f8e56318828fc6ea67f3494768c473b18e13f8ead533f28c509
BLAKE2b-256 checksum
How to use checksums
12787f1a5a5bf05a498e8cc9ad1ac2ee4c2daa4e5deae8fb4eccb64c4c898190
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

Release files / replyowl-0.3.1-py3-none-any.whl

Download URL replyowl-0.3.1-py3-none-any.whl
Size 19.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bdc8c0f5c81384d6203e187515ca1acae56881b55d2961e7d9a11dbb28e937a9
BLAKE2b-256 checksum
How to use checksums
cb3f5f1f5f3747de406d7e2e28f2f4ce4cdecead5f4015c6dc7595f0532c7b15
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

Security for replyowl 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for replyowl-0.3.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page