### Generate Sample Input Files Source: https://context7.com/awdeorio/mailmerge/llms.txt Use the --sample flag to create example template, database, and configuration files to get started with mailmerge. ```bash # Generate sample input files to get started mailmerge --sample # Output: # Created sample template email "mailmerge_template.txt" # Created sample database "mailmerge_database.csv" # Created sample config file "mailmerge_server.conf" ``` -------------------------------- ### Setup Development Environment Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Installs the project in editable mode with development and testing dependencies. Ensure you are in a virtual environment. ```bash python3 -m venv env source env/bin/activate pip install --editable .[dev,test] ``` -------------------------------- ### Install Development Environment Source: https://github.com/awdeorio/mailmerge/blob/develop/CONTRIBUTING.md Set up a Python virtual environment and install the project in editable mode with development and test dependencies. ```console $ python3 -m venv env $ source env/bin/activate $ pip install --editable .[dev,test] ``` -------------------------------- ### SMTP Server Configuration Examples Source: https://context7.com/awdeorio/mailmerge/llms.txt INI-format configuration file examples for specifying SMTP server connection parameters. Supports various security protocols and rate limiting. ```ini # Gmail with SSL/TLS (port 465) [smtp_server] host = smtp.gmail.com port = 465 security = SSL/TLS username = you@gmail.com ratelimit = 0 ``` ```ini # University SMTP with STARTTLS [smtp_server] host = smtp.mail.umich.edu port = 587 security = STARTTLS username = yourusername ratelimit = 60 ``` ```ini # Microsoft 365 with XOAUTH (bearer token entered at prompt) [smtp_server] host = smtp.office365.com port = 587 security = XOAUTH username = you@company.com ``` ```ini # Plain login (no TLS) [smtp_server] host = internal-smtp.corp.net port = 25 security = PLAIN username = mailbot ratelimit = 30 ``` ```ini # Open relay (no authentication, no security) [smtp_server] host = localhost port = 25 ratelimit = 0 ``` -------------------------------- ### Install mailmerge on Fedora Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md Installs the mailmerge tool on Fedora systems using the system's package manager. ```console sudo dnf install python3-mailmerge ``` -------------------------------- ### Install mailmerge using pipx Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md Installs the mailmerge tool globally using pipx and ensures the executable is in the system's PATH. ```console pipx install mailmerge pipx ensurepath ``` -------------------------------- ### Configure SMTP server settings Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md Example configuration for the SMTP server settings, including host, port, security, and username. Defaults are provided for Gmail. ```ini [smtp_server] host = smtp.gmail.com port = 465 security = SSL/TLS username = YOUR_USERNAME_HERE ``` -------------------------------- ### Create a mailmerge template email Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md Example of a plain text email template using Jinja2 syntax for personalization. Requires TO, SUBJECT, and FROM headers. ```plaintext TO: {{email}} SUBJECT: Testing mailmerge FROM: My Self BCC: myself@mydomain.com Hi, {{name}}, Your number is {{number}}. ``` -------------------------------- ### Verify Mailmerge Entry Point Source: https://github.com/awdeorio/mailmerge/blob/develop/CONTRIBUTING.md Check the location of the installed `mailmerge` entry point script within the virtual environment. ```console $ which mailmerge /Users/awdeorio/src/mailmerge/env/bin/mailmerge ``` -------------------------------- ### Create a mailmerge database CSV Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md Example CSV file for mailmerge data. The first line must be a header matching template parameters. ```csv email,name,number myself@mydomain.com,"Myself",17 bob@bobdomain.com,"Bob",42 ``` -------------------------------- ### Style Checking with Pycodestyle Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Checks Python code for compliance with the PEP 8 style guide. Ensures consistent code formatting. ```bash pycodestyle mailmerge tests setup.py ``` -------------------------------- ### Mailmerge Jinja2 Template Example Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md This template demonstrates advanced Jinja2 features for personalized emails. It includes conditional logic based on student grades to tailor the message content. ```jinja2 TO: {{email}} SUBJECT: EECS 280 Mid-semester Progress Report FROM: My Self REPLY-TO: My Reply Self BCC: myself@mydomain.com Dear {{name}}, This email contains our record of your grades EECS 280, as well as an estimated letter grade. Project 1: {{p1}} Project 2: {{p2}} Project 3: {{p3}} Midterm exam: {{midterm}} At this time, your estimated letter grade is {{grade}}. {% if grade == "C-" -%} I am concerned that if the current trend in your scores continues, you will be on the border of the pass/fail line. I have a few suggestions for the rest of the semester. First, it is absolutely imperative that you turn in all assignments. Attend lecture and discussion sections. Get started early on the programming assignments and ask for help. Finally, plan a strategy to help you prepare well for the final exam. The good news is that we have completed about half of the course grade, so there is an opportunity to fix this problem. The other professors and I are happy to discuss strategies together during office hours. {% elif grade in ["D+", "D", "D-", "E", "F"] -%} I am writing because I am concerned about your grade in EECS 280. My concern is that if the current trend in your scores continues, you will not pass the course. If you plan to continue in the course, I urge you to see your instructor in office hours to discuss a plan for the remainder of the semester. Otherwise, if you plan to drop the course, please see your academic advisor. {% endif -%} ``` -------------------------------- ### Resume Sending and Limit Messages Source: https://context7.com/awdeorio/mailmerge/llms.txt Use the --resume flag to start sending from a specific message offset and the --limit flag to cap the total number of messages sent. ```bash # Resume from message 5 (skip first 4) and send up to 10 total mailmerge --no-dry-run --resume 5 --limit 10 ``` -------------------------------- ### Send All Emails with Mailmerge Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md Execute this command to send all emails in your list without any limits. This is typically used after verifying your setup with a single email. ```console $ mailmerge --no-dry-run --no-limit >>> message 1 TO: myself@mydomain.com SUBJECT: Testing mailmerge FROM: My Self MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Date: Thu, 19 Dec 2019 19:51:01 -0000 Hi, Myself, Your number is 17. >>> sent message 1 >>> message 2 TO: bob@bobdomain.com SUBJECT: Testing mailmerge FROM: My Self MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Date: Thu, 19 Dec 2019 19:51:01 -0000 Hi, Bob, Your number is 42. >>> sent message 2 ``` -------------------------------- ### Send a Single Email with Mailmerge Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md Use this command to send only one email. It's useful for testing your setup before sending to a larger list. Ensure your SMTP configuration is correct. ```console $ mailmerge --no-dry-run >>> message 1 TO: myself@mydomain.com SUBJECT: Testing mailmerge FROM: My Self MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Date: Thu, 19 Dec 2019 19:50:24 -0000 Hi, Myself, Your number is 17. >>> sent message 1 >>> Limit was 1 message. To remove the limit, use the --no-limit option. ``` -------------------------------- ### Mailmerge HTML Only Email Template Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md This template demonstrates how to format an email using only HTML. Set the 'Content-Type' header to 'text/html' and start the message body with ''. ```html TO: {{email}} SUBJECT: Testing mailmerge FROM: My Self BCC: myself@mydomain.com Content-Type: text/html

Hi, {{name}},

Your number is {{number}}.

Sent by mailmerge

``` -------------------------------- ### Mailmerge CSV Database Example Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md This CSV file serves as the data source for mailmerge. It includes columns for email, name, and various grade components, which are used to personalize emails via templates. ```csv email,name,p1,p2,p3,midterm,grade myself@mydomain.com,"My Self",100,100,100,100,A+ borderline@fixme.com,"Borderline Name",50,50,50,50,C- failing@fixme.com,"Failing Name",0,0,0,0,F ``` -------------------------------- ### Use Custom File Paths Source: https://context7.com/awdeorio/mailmerge/llms.txt Specify custom paths for the template, database, and configuration files using their respective flags. ```bash # Use custom file paths mailmerge \ --template my_template.txt \ --database my_contacts.csv \ --config my_server.conf \ --no-dry-run --no-limit ``` -------------------------------- ### Check MANIFEST.in with check-manifest Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Ensures that the MANIFEST.in file correctly specifies all necessary files for source distribution. Crucial for packaging. ```bash check-manifest ``` -------------------------------- ### Create Sample Mailmerge Files Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Generates sample input files (template, CSV, config) for testing and demonstration purposes. ```bash mailmerge --sample ``` -------------------------------- ### Check Manifest Source: https://github.com/awdeorio/mailmerge/blob/develop/CONTRIBUTING.md Ensure that the package manifest is correctly configured. ```console $ check-manifest ``` -------------------------------- ### Programmatic Mail Merge Loop Source: https://context7.com/awdeorio/mailmerge/llms.txt Sets up template, database, and configuration files, then iterates through the database to render and send emails using TemplateMessage and SendmailClient. Includes error handling for MailmergeError. ```python from pathlib import Path import textwrap from mailmerge import TemplateMessage, SendmailClient, MailmergeError from mailmerge.__main__ import read_csv_database # ---- Setup files ---- template_path = Path("/tmp/template.txt") database_path = Path("/tmp/database.csv") config_path = Path("/tmp/server.conf") template_path.write_text(textwrap.dedent(""" TO: {{email}} SUBJECT: Hi {{name}} FROM: sender@example.com Dear {{name}}, your code is {{code}}. """)) database_path.write_text(textwrap.dedent(""" email,name,code alice@example.com,Alice,ALPHA1 bob@example.com,Bob,BETA2 """, encoding="utf-8")) config_path.write_text(textwrap.dedent(""" [smtp_server] host = smtp.example.com port = 465 security = SSL/TLS username = sender@example.com ratelimit = 0 """)) # ---- Mail merge loop ---- tmpl = TemplateMessage(template_path) client = SendmailClient(config_path, dry_run=True) # set dry_run=False to send for i, row in enumerate(read_csv_database(database_path), start=1): try: sender, recipients, message = tmpl.render(row) client.sendmail(sender, recipients, message) print(f"[{i}] Sent to {recipients}") except MailmergeError as e: print(f"[{i}] Error: {e}") # [1] Sent to ['alice@example.com'] # [2] Sent to ['bob@example.com'] ``` -------------------------------- ### Run Tests with Coverage Report Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Executes all tests and generates a coverage report, highlighting missing lines. Helps identify areas needing more test coverage. ```bash pytest --cov ./mailmerge --cov-report term-missing ``` -------------------------------- ### Test Code Style Source: https://github.com/awdeorio/mailmerge/blob/develop/CONTRIBUTING.md Check code style compliance using pycodestyle and pydocstyle, and perform static analysis with pylint. ```console $ pycodestyle mailmerge tests setup.py $ pydocstyle mailmerge tests setup.py $ pylint mailmerge tests setup.py ``` -------------------------------- ### Raw MIME Output Format Source: https://context7.com/awdeorio/mailmerge/llms.txt For raw MIME output, use the --output-format raw flag. ```bash # Raw MIME output mailmerge --output-format raw ``` -------------------------------- ### Load and Render Email Template Source: https://context7.com/awdeorio/mailmerge/llms.txt Loads a Jinja2 email template from disk and renders it against a context dictionary. The render method returns sender, recipients, and a fully constructed email message. ```python from pathlib import Path import textwrap from mailmerge import TemplateMessage, MailmergeError # Write a template file template_path = Path("mailmerge_template.txt") template_path.write_text(textwrap.dedent(""" TO: {{email}} SUBJECT: Hello, {{name}} FROM: sender@example.com BCC: archive@example.com Hi {{name}}, Your score is {{score}}. """)) # Load the template tmpl = TemplateMessage(template_path) # Render with a context dict (one CSV row) try: sender, recipients, message = tmpl.render({ "email": "alice@example.com", "name": "Alice", "score": 95, }) except MailmergeError as e: print(f"Template error: {e}") raise print(f"From: {sender}") # From: sender@example.com print(f"Recipients: {recipients}") # Recipients: ['alice@example.com'] # Note: BCC is in recipients list but stripped from message headers print(f"Subject: {message['subject']}") # Subject: Hello, Alice print(message.get_payload()) # Hi Alice, # # Your score is 95. ``` -------------------------------- ### Run Tox for Clean Environment Tests Source: https://github.com/awdeorio/mailmerge/blob/develop/CONTRIBUTING.md Execute linters and tests within a clean, temporary virtual environment using tox. ```console $ tox ``` -------------------------------- ### Email Template with File Attachments Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md A template demonstrating how to attach multiple files to an email using the ATTACHMENT header. Jinja can be used to dynamically set attachment filenames. ```text TO: {{email}} SUBJECT: Testing mailmerge FROM: My Self BCC: myself@mydomain.com ATTACHMENT: file1.docx ATTACHMENT: ../file2.pdf ATTACHMENT: /z/shared/{{name}}_submission.txt Hi, {{name}}, This email contains three attachments. Pro-tip: Use Jinja to customize the attachments based on your database! ``` -------------------------------- ### Run All Linters and Tests with Tox Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Executes all defined linters and tests in a clean, isolated environment. Provides a reliable way to check code quality and test compatibility. ```bash tox ``` -------------------------------- ### Send Email using SendmailClient Source: https://context7.com/awdeorio/mailmerge/llms.txt Configures an SMTP client and sends email messages. Supports dry runs and enforces rate limiting based on configuration. Will prompt for password interactively for real sends. ```python import email import textwrap from pathlib import Path from mailmerge import SendmailClient, MailmergeError # Write a config file config_path = Path("mailmerge_server.conf") config_path.write_text(textwrap.dedent(""" [smtp_server] host = smtp.gmail.com port = 465 security = SSL/TLS username = you@gmail.com ratelimit = 30 """)) # Build a message object message = email.message_from_string(textwrap.dedent(""" TO: alice@example.com SUBJECT: Hello Alice FROM: you@gmail.com Hi Alice, this is a test. """)) # Dry run (default) — no network call, no password prompt client = SendmailClient(config_path, dry_run=True) client.sendmail( sender="you@gmail.com", recipients=["alice@example.com"], message=message, ) # No output; no email sent # Real send — will prompt for password interactively client_real = SendmailClient(config_path, dry_run=False) try: client_real.sendmail( sender="you@gmail.com", recipients=["alice@example.com"], message=message, ) print("Email sent successfully") except MailmergeError as e: print(f"Send failed: {e}") ``` -------------------------------- ### Template with Attachments and Inline Images Source: https://context7.com/awdeorio/mailmerge/llms.txt This template demonstrates how to include file attachments and inline images in emails. Specify ATTACHMENT headers for files and use `` tags for inline images, referencing them by filename. ```jinja2 # Template with file attachments and inline images TO: {{email}} SUBJECT: Your report is attached FROM: reports@company.com ATTACHMENT: reports/{{name}}_report.pdf ATTACHMENT: logo.png Content-Type: text/html Logo

Hi {{name}}, please find your report attached.

``` -------------------------------- ### Measure Test Coverage Source: https://github.com/awdeorio/mailmerge/blob/develop/CONTRIBUTING.md Run unit tests and report on the code coverage, highlighting missing lines. ```console $ pytest --cov ./mailmerge --cov-report term-missing ``` -------------------------------- ### Display Mailmerge Help Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Shows the help message for the mailmerge command-line tool, listing available options and their usage. ```bash mailmerge --help ``` -------------------------------- ### Plain Text Output Format Source: https://context7.com/awdeorio/mailmerge/llms.txt To receive output without ANSI color codes, use the --output-format text flag. ```bash # Plain text output (no ANSI color codes) mailmerge --output-format text ``` -------------------------------- ### Run Unit Tests Source: https://github.com/awdeorio/mailmerge/blob/develop/CONTRIBUTING.md Execute all unit tests for the project using pytest. ```console $ pytest ``` -------------------------------- ### Send First Email Source: https://context7.com/awdeorio/mailmerge/llms.txt To send the first email, disable the dry-run mode using the --no-dry-run flag. ```bash # Send only the first real email mailmerge --no-dry-run ``` -------------------------------- ### Dry Run All Messages Source: https://context7.com/awdeorio/mailmerge/llms.txt To preview all messages without sending, use the --no-limit flag in conjunction with the default dry-run mode. ```bash # Dry run all messages (no limit) mailmerge --no-limit ``` -------------------------------- ### Run All Tests with Pytest Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Executes all tests in the project using pytest. This is the primary command for verifying code correctness. ```bash pytest ``` -------------------------------- ### Static Analysis with Pylint Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Performs static analysis to find programming errors, enforce coding standards, and refactor code. Catches potential issues before runtime. ```bash pylint mailmerge tests setup.py ``` -------------------------------- ### Basic Email Template Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md A standard email template using Jinja for personalization. Supports both plain text and HTML content within a multipart message. ```text TO: {{email}} SUBJECT: Testing mailmerge FROM: My Self BCC: myself@mydomain.com MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="boundary" This is a MIME-encoded message. If you are seeing this, your mail reader is old. --boundary Content-Type: text/plain; charset=us-ascii Hi, {{name}}, Your number is {{number}}. Sent by mailmerge https://github.com/awdeorio/mailmerge --boundary Content-Type: text/html; charset=us-ascii

Hi, {{name}},

Your number is {{number}}.

Sent by mailmerge

``` -------------------------------- ### Plain Text Jinja2 Template Source: https://context7.com/awdeorio/mailmerge/llms.txt A basic email template using Jinja2 syntax for variable substitution and conditional logic. Requires TO, SUBJECT, and FROM headers. ```jinja2 # Plain text template with Jinja2 variables TO: {{email}} SUBJECT: EECS 280 Progress Report FROM: Instructor BCC: instructor@umich.edu REPLY-TO: help@umich.edu Dear {{name}}, Your current grade is {{grade}}. {% if grade in ["D+", "D", "D-", "E", "F"] %} Please visit office hours to discuss a recovery plan. {% elif grade == "C-" %} You are near the pass/fail boundary — please reach out. {% endif %} Best, Instructor ``` -------------------------------- ### Mailmerge Project File Structure Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Overview of the mailmerge project's directory and file organization. This structure helps in understanding the placement of source code, tests, and configuration files. ```tree mailmerge/ ├── mailmerge/ │ ├── __init__.py # Public API exports │ ├── __main__.py # CLI implementation │ ├── template_message.py # Template rendering and message construction │ ├── sendmail_client.py # SMTP client │ └── exceptions.py # Custom exceptions ├── tests/ │ ├── test_main.py # CLI tests │ ├── test_template_message.py # Template rendering tests │ ├── test_sendmail_client.py # SMTP client tests │ ├── test_ratelimit.py # Rate limiting tests │ └── testdata/ # Test fixtures ├── pyproject.toml # Project metadata and dependencies └── tox.ini # Multi-environment testing config ``` -------------------------------- ### Send All Emails Source: https://context7.com/awdeorio/mailmerge/llms.txt To send all emails, disable dry-run mode with --no-dry-run and remove any message limits with --no-limit. ```bash # Send all real emails mailmerge --no-dry-run --no-limit ``` -------------------------------- ### Send First Mailmerge Message Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Sends the first mail merge message for real, bypassing the dry-run mode. Use with caution. ```bash mailmerge --no-dry-run ``` -------------------------------- ### Standard CSV Database Source: https://context7.com/awdeorio/mailmerge/llms.txt A comma-separated values file where each row represents an email recipient and column headers correspond to Jinja2 template variables. ```csv # Standard comma-separated database email,name,grade,number myself@mydomain.com,"Myself",A+,17 bob@bobdomain.com,"Bob",B,42 alice@example.com,"Alice",C-,99 ``` -------------------------------- ### Dry Run Mailmerge (All Messages) Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Performs a dry run for all messages in the database, processing and displaying each one without sending. Useful for comprehensive verification. ```bash mailmerge --no-limit ``` -------------------------------- ### Docstring Checking with Pydocstyle Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Verifies that docstrings adhere to PEP 257 conventions. Important for maintainable and understandable code. ```bash pydocstyle mailmerge tests setup.py ``` -------------------------------- ### Dry Run Verification of Attachments Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md Console output showing a dry run of mailmerge, verifying attachment files and confirming that no messages were actually sent. Use --no-dry-run to send. ```console $ mailmerge >>> message 1 TO: myself@mydomain.com SUBJECT: Testing mailmerge FROM: My Self Hi, Myself, This email contains three attachments. Pro-tip: Use Jinja to customize the attachments based on your database! >>> attached /Users/awdeorio/Documents/test/file1.docx >>> attached /Users/awdeorio/Documents/file2.pdf >>> attached /z/shared/Myself_submission.txt >>> sent message 1 >>> This was a dry run. To send messages, use the --no-dry-run option. ``` -------------------------------- ### Tab-Delimited CSV Database with Unicode Source: https://context7.com/awdeorio/mailmerge/llms.txt Supports tab-delimited files and correctly handles Unicode characters. Files with a UTF-8 BOM are also processed automatically. ```csv # Tab-delimited with Unicode characters (auto-detected, UTF-8-sig BOM safe) email name month josé@example.com José García March ``` -------------------------------- ### Handle MailmergeRateLimitError Source: https://context7.com/awdeorio/mailmerge/llms.txt Shows how to check if MailmergeRateLimitError is a subclass of MailmergeError, indicating it's a specific type of mailmerge-related error. ```python from mailmerge import MailmergeError # MailmergeRateLimitError — raised by SendmailClient.sendmail() during real sends # when ratelimit > 0 and the last send was too recent print(issubclass(MailmergeRateLimitError, MailmergeError)) # True ``` -------------------------------- ### Dry Run First Message Source: https://context7.com/awdeorio/mailmerge/llms.txt By default, mailmerge performs a dry run, previewing the first rendered message without sending. Use --no-dry-run to send emails. ```bash # Dry run: preview the first rendered message (default behavior) mailmerge # >>> message 1 # TO: myself@mydomain.com # SUBJECT: Testing mailmerge # FROM: My Self # ... # >>> This was a dry run. To send messages, use the --no-dry-run option. ``` -------------------------------- ### Markdown Template for HTML Conversion Source: https://context7.com/awdeorio/mailmerge/llms.txt A Markdown template that mailmerge automatically converts to HTML for email bodies. Supports basic Markdown syntax and Jinja2 variables. ```markdown # Markdown template — auto-converted to HTML + plain text multipart TO: {{email}} SUBJECT: Newsletter - {{month}} FROM: news@example.com CONTENT-TYPE: text/markdown # Hello, {{name}}! Here are this month's highlights: - **Feature A** is now live - Bug fixes in *Module B* - [Read more](https://example.com) ``` -------------------------------- ### Send All Mailmerge Messages Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Sends all mail merge messages for real, bypassing the dry-run mode and processing all entries in the database. Use with extreme caution. ```bash mailmerge --no-dry-run --no-limit ``` -------------------------------- ### Markdown Email with Inline Image Attachment Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md A markdown email template that includes an inline image. The image must be declared as an ATTACHMENT and then referenced using markdown image syntax. ```markdown TO: {{email}} SUBJECT: Testing mailmerge FROM: My Self BCC: myself@mydomain.com ATTACHMENT: image.jpg CONTENT-TYPE: text/markdown Hi, {{name}}, ![image alt-description](image.jpg) ``` -------------------------------- ### Dry Run Mailmerge (First Message) Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Performs a dry run of the mail merge process, processing and displaying the first message without actually sending it. Useful for verifying template rendering and recipient selection. ```bash mailmerge ``` -------------------------------- ### Run Specific Test Function with Pytest Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Executes a single test function within a specified test file. Ideal for isolating and fixing a particular test case. ```bash pytest tests/test_template_message.py::test_simple ``` -------------------------------- ### HTML Email Template Source: https://context7.com/awdeorio/mailmerge/llms.txt An HTML email template that uses Jinja2 variables for personalization. Ensure the Content-Type header is set to text/html. ```jinja2 # HTML email template TO: {{email}} SUBJECT: Welcome to the team, {{name}}! FROM: HR Content-Type: text/html

Hi, {{name}},

Your start date is {{start_date}}.

See you soon!

``` -------------------------------- ### Catch Missing Attachment Error Source: https://context7.com/awdeorio/mailmerge/llms.txt Demonstrates how to catch a MailmergeError when an attachment specified in the template is not found. This is useful for validating template integrity before sending. ```python from pathlib import Path import textwrap from mailmerge import TemplateMessage, MailmergeError template_path = Path("/tmp/template.txt") text = textwrap.dedent(""" TO: test@example.com SUBJECT: Test FROM: from@example.com ATTACHMENT: nonexistent_file.pdf Body text. """) template_path.write_text(text) tmpl = TemplateMessage(template_path) try: tmpl.render({}) except MailmergeError as e: print(f"Attachment error: {e}") ``` -------------------------------- ### Run Specific Test File with Pytest Source: https://github.com/awdeorio/mailmerge/blob/develop/CLAUDE.md Executes tests only within a specified test file. Useful for focused debugging. ```bash pytest tests/test_template_message.py ``` -------------------------------- ### HTML Email with Inline Image Attachments Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md An HTML email template that includes inline images. Images must be declared as ATTACHMENTs before being referenced in the HTML body using src attributes. ```html TO: {{email}} SUBJECT: Testing mailmerge FROM: My Self BCC: myself@mydomain.com Content-Type: text/html ATTACHMENT: image.jpg ATTACHMENT: second/image.jpg

Hi, {{name}},

Sample image The second image: second

Sent by mailmerge

``` -------------------------------- ### Read CSV with UTF-8 BOM Source: https://context7.com/awdeorio/mailmerge/llms.txt Reads a CSV file that includes a UTF-8 BOM, demonstrating that the BOM is handled transparently and does not appear in field names. ```python from pathlib import Path # UTF-8 BOM file (Excel export) — handled automatically csv_bom_path = Path("excel_export.csv") csv_bom_path.write_bytes( b"\xef\xbb\xbf" # UTF-8 BOM + b"email,name\nalice@example.com,Alice\n" ) for row in read_csv_database(csv_bom_path): print(row["email"]) # alice@example.com (no BOM in field name) ``` -------------------------------- ### Catch Mailmerge Errors Source: https://context7.com/awdeorio/mailmerge/llms.txt Demonstrates catching MailmergeError for template rendering issues, such as undefined variables. MailmergeRateLimitError is a subclass for rate limiting failures. ```python from mailmerge import MailmergeError, MailmergeRateLimitError from mailmerge import TemplateMessage, SendmailClient from pathlib import Path import textwrap # Catching a template rendering error (undefined variable) template_path = Path("bad_template.txt") template_path.write_text(textwrap.dedent(""" TO: {{email}} SUBJECT: Test FROM: from@example.com Hello {{undefined_variable}} """)) tmpl = TemplateMessage(template_path) try: tmpl.render({"email": "test@example.com"}) # missing 'undefined_variable' except MailmergeError as e: print(f"Caught MailmergeError: {e}") # Caught MailmergeError: bad_template.txt: 'undefined_variable' is undefined ``` -------------------------------- ### Read Comma-Delimited CSV Database Source: https://context7.com/awdeorio/mailmerge/llms.txt Reads a comma-delimited CSV file row by row, printing each row as a dictionary. Handles UTF-8 BOM automatically. ```python from pathlib import Path import textwrap from mailmerge.__main__ import read_csv_database # Comma-delimited CSV csv_path = Path("contacts.csv") csv_path.write_text(textwrap.dedent(""" email,name,score alice@example.com,"Alice Smith",95 bob@example.com,"Bob Jones",87 """ ), encoding="utf-8") for row in read_csv_database(csv_path): print(dict(row)) # {'email': 'alice@example.com', 'name': 'Alice Smith', 'score': '95'} # {'email': 'bob@example.com', 'name': 'Bob Jones', 'score': '87'} ``` -------------------------------- ### Read Semicolon-Delimited CSV Source: https://context7.com/awdeorio/mailmerge/llms.txt Reads a semicolon-delimited CSV file, showing that the delimiter is auto-detected and the specified field can be accessed. ```python from pathlib import Path from mailmerge.__main__ import read_csv_database # Semicolon-delimited — auto-detected csv_semi = Path("european.csv") csv_semi.write_text("email;name\nalice@example.com;Alice\n") for row in read_csv_database(csv_semi): print(row["name"]) # Alice ``` -------------------------------- ### Markdown Formatted Email Template Source: https://github.com/awdeorio/mailmerge/blob/develop/README.md An email template that uses markdown formatting. Mailmerge converts markdown to HTML, sending both plain text and HTML versions. ```text TO: {{email}} SUBJECT: Testing mailmerge FROM: My Self BCC: myself@mydomain.com CONTENT-TYPE: text/markdown You can add: - Emphasis, aka italics, with *asterisks*. - Strong emphasis, aka bold, with **asterisks**. - Combined emphasis with **asterisks and _underscores_**. - Unordered lists like this one. - Ordered lists with numbers: 1. Item 1 2. Item 2 - Preformatted text with `backticks`. - How about some [hyperlinks](http://bit.ly/eecs485-wn19-p6)? # This is a heading. ## And another heading. Here's an image not attached with the email: ![python logo not attached](http://pluspng.com/img-png/python-logo-png-open-2000.png) ``` -------------------------------- ### Semicolon-Delimited CSV Database Source: https://context7.com/awdeorio/mailmerge/llms.txt Mailmerge automatically detects and parses semicolon-delimited CSV files. This format is useful when commas are part of the data. ```csv # Semicolon-delimited (auto-detected) email;name;start_date alice@corp.com;Alice;2024-03-01 bob@corp.com;Bob;2024-04-15 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.