Skip to main content

btx_lib_mail

CI CodeQL License: MIT Open in Codespaces PyPI PyPI - Downloads Code Style: Ruff codecov Maintainability security: bandit

Send email from Python and from the shell.

Most mail libraries are sold on a feature list, and nobody loses sleep over a feature list. What keeps you up is the one message that matters failing at the worst possible time: the 2 GB export that runs your server out of memory, the customer whose name comes through as garbled bytes, the primary relay that drops mid-send. btx_lib_mail is built for that message, not for the demo.

What you get:

  • Send a 100 GB attachment on a box with almost no free memory. The message is streamed to disk and pushed to the server one chunk at a time, so peak memory stays flat whether the file is 100 kB or 100 GB. It never holds the whole payload in RAM, because the RAM you do not have is the RAM that kills the job.
  • BDAT when the server supports it, DATA when it does not. If the far end advertises CHUNKING (RFC 3030) the message goes out in length-prefixed chunks; otherwise it falls back to a correct, dot-stuffed DATA phase. You do not pick, the library negotiates.
  • Subjects and bodies that encode correctly. Umlauts, emoji, CJK, a subject that is only a full stop: all handled by the standard library's modern email machinery, not by a regex someone wrote at 2am. No more Grüße arriving as Grüße in a customer's name.
  • No more hand-rolling smtplib. No MIME assembly, no dot-stuffing, no failover loop. One function call, or one command.
  • A command-line mailer. btx-lib-mail send ... turns any shell into a mail client, with the same streaming and the same checks.
  • Attachments checked before they leave. Path traversal, symlinks, /.ssh/, system directories, dangerous extensions and a size cap are refused by default, so you do not email your private key by accident.

The part that costs us and earns your trust is the unglamorous part: every wire path is proven end to end against a real SMTP server, including BDAT, STARTTLS with authentication, and a memory bound that a 100 GB attachment cannot breach. That confidence is the actual product. Go and try the daft thing: point it at a spare mailbox and attach something absurd.

Quickstart

Install:

pip install btx_lib_mail

Send an email from Python:

from btx_lib_mail import send

send(
    mail_from="alerts@example.com",
    mail_recipients=["oncall@example.com"],
    mail_subject="build failed",
    mail_body="See CI logs for details.",
    smtphosts=["smtp.example.com:587"],
    credentials=("mailer", "s3cr3t"),
)

Attach a huge file without running out of memory (streamed, never buffered whole):

from pathlib import Path
from btx_lib_mail import send

send(
    mail_from="backups@example.com",
    mail_recipients=["archive@example.com"],
    mail_subject="nightly dump",
    mail_body="Attached.",
    smtphosts=["smtp.example.com:587"],
    attachment_file_paths=[Path("/data/nightly-dump.tar")],  # gigabytes are fine
)

Send from the shell:

btx-lib-mail send \
  --host smtp.example.com:587 \
  --sender alerts@example.com \
  --recipient oncall@example.com \
  --subject "Ping" \
  --body "Smoke test"

Both commands (btx_lib_mail and btx-lib-mail) and python -m btx_lib_mail run the same CLI.

Use it from an AI agent (zero install)

btx_lib_mail is built to be driven by LLMs and agents, not only by people. An agent can send mail with nothing installed, straight from PyPI via uvx:

uvx btx-lib-mail send \
  --host smtp.example.com:587 \
  --sender alerts@example.com --recipient oncall@example.com \
  --subject "Ping" --body "Smoke test"

The library also ships a Claude Code skill (python-send-mail) that teaches an agent when and how to use it: install, uvx, the library API, the CLI, streaming and BDAT, and attachment security. Install it into any project:

/plugin marketplace add bitranox/btx_lib_mail
/plugin install btx_lib_mail

It is also available in the central bitranox-skills marketplace as coding-python-send-mail.

Documentation

Project docs

Download files

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

Source Distribution

btx_lib_mail-1.5.0.tar.gz (112.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

btx_lib_mail-1.5.0-py3-none-any.whl (37.4 kB view details)

Uploaded Python 3

File details

Details for the file btx_lib_mail-1.5.0.tar.gz.

File metadata

  • Download URL: btx_lib_mail-1.5.0.tar.gz
  • Upload date:
  • Size: 112.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for btx_lib_mail-1.5.0.tar.gz
Algorithm Hash digest
SHA256 2c97ab5381f9385c20af0d87ec2010735719a3ccd61de107e216a058909296c1
MD5 271a44c8ea3e6d9474826bff26e112d9
BLAKE2b-256 e83ac6a3bb949aa1f4e0eb56fccdb94dc4312a6e5175e7a7ee0fd5ac728b6507

See more details on using hashes here.

File details

Details for the file btx_lib_mail-1.5.0-py3-none-any.whl.

File metadata

  • Download URL: btx_lib_mail-1.5.0-py3-none-any.whl
  • Upload date:
  • Size: 37.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for btx_lib_mail-1.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 82e11996f1d6fd137487e82eb48205977f29a0d0a8a1f368ea75a6eea5e9caa4
MD5 ce78d5d9c3528c884933d84c154600d8
BLAKE2b-256 550c8217d9d2129737ff19d2571045f19d947ae6d6141b276a79a55411ab6791

See more details on using hashes here.

Release history Release notifications | RSS feed

1.5.2

2 files

1.5.1

2 files

This release

1.5.0 This release

2 files

1.4.0

2 files

1.3.2

2 files

1.3.1

2 files

1.3.0

2 files

1.2.1

2 files

1.2.0

2 files

1.1.0

2 files

1.0.3

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page