sendMail module

Overview

The sendMail module is a comprehensive email campaign management system that supports:

  • Bulk email sending with rate limiting and batch processing

  • Multiple email profiles (Arts Croisés, Cambristi)

  • Google Sheets integration for subscriber management

  • Google Drive integration for attachment handling

  • HTML email templates with inline image support

  • Membership management and cotisation reminders

  • SMTP and Gmail API support for sending emails

  • Flexible filtering based on subscriber attributes

The module is designed for organizations managing mailing lists, newsletters, and membership communications.

Bulk email campaign management system for organizations.

Provides functionality for sending email campaigns to subscribers via SMTP or Gmail API, with support for: - Google Sheets and CSV subscriber databases - HTML email templates with inline image support - Rate limiting and batch processing - Google Drive integration for attachments - Markdown to HTML conversion - Flexible filtering based on subscriber attributes - Email profiles with IMAP/SMTP configuration

Main usage:

python src/sendMail.py –profile <profile_name> -s “Subject” [files…]

Key classes:

Dict2Class: Convert dictionaries to objects

Key functions:

build_email: Build MIME email message send_mail: Send email via SMTP send_gmail: Send email via Gmail API filter: Filter subscriber rows based on criteria generate_mailing: Generate and send campaign emails

sendMail.get_default_config_path()[source]

Get default configuration file path based on OS home directory.

Returns:

Path to sendMail.yml in user’s .config directory,

e.g., ~/.config/sendMail.yml

Return type:

str

sendMail.init_log(log_file: str | None = None) Logger[source]

Initialize logging configuration.

Sets up logging with default format, level, and optional file handler.

Parameters:

log_file – Path to log file. If None, logs to console only (default: None)

Returns:

Configured Logger instance

sendMail.open_google_db_members_sheet(sa: str, sheet_id: str) Any[source]

Open Google Sheet and return spreadsheet object.

Parameters:
  • sa – Service account entry name in secret vault

  • sheet_id – Google Sheet ID entry name in secret vault

Returns:

gspread Spreadsheet object for reading/writing data

sendMail.read_all_sheet(wb: Any, sheet_name: str = '') list[list[Any]][source]

Read all values from a Google Sheet.

Parameters:
  • wb – gspread Spreadsheet object

  • sheet_name – Sheet name to read. If empty, reads first sheet

Returns:

List of lists containing all sheet values (array of arrays)

sendMail.get_google_sheets_schema(sa: str, sheet_id: str) list[str][source]

Extract field names (header row) from Google Sheet for validation.

Parameters:
  • sa – Service account entry name in secret vault

  • sheet_id – Google Sheet ID entry name in secret vault

Returns:

List of field names from first row of Google Sheet, or empty list on error

class sendMail.Dict2Class(my_dict: dict[str, Any])[source]

Bases: object

Convert dictionary to object with lowercase attribute names.

Allows dict-like configs to be accessed as objects (obj.key instead of dict[‘key’]). All keys are converted to lowercase attribute names.

Parameters:

my_dict – Dictionary to convert to object

Example

config = Dict2Class({‘Name’: ‘John’, ‘Email’: ‘j@example.com’}) config.name # ‘John’ config.email # ‘j@example.com

__init__(my_dict: dict[str, Any]) None[source]
sendMail.guess_type(filepath: str) str | None[source]

Detect MIME type of a file by content or extension.

Tries magic-based detection first (file content), falls back to extension-based guessing if magic not available.

Parameters:

filepath – Path to file to identify

Returns:

MIME type string (e.g., ‘image/png’) or None if detection fails

sendMail.file_to_base64(filepath: str) str[source]

Encode file contents as base64 string.

Handles both local files and HTTP URLs.

Parameters:

filepath – Local file path or HTTP URL

Returns:

Base64 encoded file content as string, or empty string on error

sendMail.make_html_images_inline(in_filepath: str, out_filepath: str | None = None) str[source]

Takes an HTML file and writes a new version with inline Base64 encoded images. :param in_filepath: Input file path (HTML) :type in_filepath: str :param out_filepath: Output file path (HTML) - if None, return the data :type out_filepath: str :returns the html data with inline images

sendMail.prepare_html_for_cid(in_filepath)[source]

Prepare HTML content for embedding inline images as Content-ID (CID) references.

This function processes an HTML file, reads its content, identifies the <img> tags, and replaces their src attributes with Content-ID (CID) references, allowing the images to be embedded inline in emails. It handles local image paths and excludes external or base64-encoded images. A mapping of the local image paths and the generated CIDs is returned.

Parameters:

in_filepath (str) – The file path to the HTML file to be processed.

Returns:

A tuple containing the modified HTML content as a string and a list of tuples, where each tuple includes the local image file path and its associated CID.

Return type:

tuple[str, list[tuple[str, str]]]

sendMail.get_subscriber_reader(param)[source]

Returns a reader object and file handle for retrieving subscriber data based on the given parameter. The function retrieves the data either from a Google Sheets document or a local CSV file, depending on the configuration in the parameter. If the database file is not found, it logs the error and returns None, None.

Parameters:

param (object) – The configuration object containing details for data retrieval (e.g., Google Sheets credentials or CSV/XLS database path).

Returns:

A tuple consisting of a data reader object (either for Google Sheets or CSV) and a file handle. If the database is not found, it returns (None, None).

Return type:

tuple(iterator | None, file | None)

sendMail.get_indices(header: list[Any]) dict[str, int][source]

Create a dictionary that maps each header element to its corresponding index in the list of headers.

Parameters:

header – List of header values (strings or other types from CSV/sheets).

Returns:

Dictionary where keys are string representations of header elements and values are their corresponding indices.

sendMail.get_smtp_connection(param: Any) SMTP | None[source]

Open SMTP connection with TLS.

Creates connection to SMTP server, upgrades to TLS, and authenticates with provided credentials.

Parameters:

param – Configuration object with smtp_host, smtp_port, username, password

Returns:

SMTP connection object, or None if connection failed

Raises:

SystemExit – On authentication failure (logs critical error)

sendMail.get_gmail_service(param)[source]

Fetches and returns the Gmail service object by authenticating through OAuth2. If valid credentials are not found locally, the function retrieves them via authorized secrets or user authentication interaction.

Parameters:

param (object) – An object containing the following attributes: - token_file: A path to the file holding the user’s token information. - scopes: A list of OAuth2 scopes required by the Gmail API. - token_id: Identifier for fetching the token via secret management. - credentials_id: Identifier for fetching OAuth2 client credentials via secret management. - SCOPES: A list of OAuth2 scopes required for the authentication process.

Returns:

A Google API client service object for accessing the Gmail API.

Return type:

googleapiclient.discovery.Resource

sendMail.save_to_sent(param: Any, msg: MIMEMultipart) None[source]

Store message in IMAP Sent folder.

Saves sent email to Sent folder for archival. Retries up to 3 times on failure with 10-second delays.

Parameters:
  • param – Configuration object with imap_host, imap_port, username, password, sent_folder, verbose

  • msg – Email message (MIMEMultipart) to store

sendMail.prepare_html_and_get_images(in_filepath, max_width=800)[source]

Processes an HTML file to embed inline images and resize them for optimized usage.

Parameters:
  • in_filepath (str) – The path to the input HTML file.

  • max_width (int, optional) – The maximum allowable width for images. Images wider than this will be resized. Defaults to 800.

Returns:

A tuple containing the modified HTML content as a string, a list of inline image metadata dictionaries with optimized file paths and their corresponding CID references, and the path to the temporary directory used for storing the optimized images.

Return type:

tuple[str, list[dict[str, str]], str]

sendMail.format_message(template: str, row: list[Any], header: list[str]) str[source]

Format message by replacing ${field} placeholders with row values.

Substitutes template placeholders with subscriber data. Placeholders use syntax ${column_name} which maps to header column names.

Parameters:
  • template – Template string with ${field_name} placeholders

  • row – List of subscriber values (one per column)

  • header – List of column/field names (indices match row)

Returns:

Formatted message with values substituted, or original template on error

sendMail.process_attachments(args, config, folder='input')[source]

Processes attachments by either verifying file paths provided in the arguments or downloading files from a Google Drive folder and cleaning up the local folder. Returns processed file paths, the Google Drive service connection, and metadata about the downloaded files.

Parameters:
  • args (Namespace) – Command-line arguments containing file paths or other configurations.

  • config (dict) – Configuration dictionary containing keys like ‘SA’ for service account and ‘mailing_folder’ for desired Google Drive folder ID.

  • folder (str) – Optional path to the local folder used for downloading files. Defaults to “input”.

Returns:

A tuple containing the list of processed file paths, the Google Drive service connection object (or None if unused), and metadata about files fetched from Google Drive.

Return type:

tuple[list[str], Union[Resource, None], list[dict]]

sendMail.md2html(file_path, styles=None, embed_styles=False)[source]

Converts a Markdown file to an HTML file with optional styling.

The function reads a Markdown file, converts its content to an HTML document using the Markdown library, and writes the resulting HTML to a new file. Default and optional CSS styles can be embedded in or linked from the resulting HTML document.

Parameters:
  • file_path (str) – The file path of the Markdown file to be converted.

  • styles (str, optional) – Optional path to a CSS file for custom styling. Defaults to None.

  • embed_styles (bool) – Specifies whether to embed styles directly into the HTML. If True and a valid styles path is provided, the CSS content will be embedded as inline styles. Defaults to False.

Returns:

The file path of the created HTML file, or None if the process fails (e.g., if the Markdown file does not exist).

Return type:

str or None

sendMail.build_email(param: Any, subject: str = '', to: str = '', cc: str = '', bcc: str | None = None, message: str = '', images: str | list[str] | None = None, attachments: str | list[str] | None = None) tuple[MIMEMultipart, list[str]][source]

Build MIME email message with attachments and inline images.

Constructs multipart email with headers, body, inline images, and attachments. Supports HTML/text bodies, inline CID images, and file attachments.

Parameters:
  • param – Configuration object with sender details

  • subject – Email subject line

  • to – Comma-separated To addresses

  • cc – Comma-separated CC addresses

  • bcc – Comma-separated BCC addresses

  • message – HTML or text email body

  • images – File path(s) of inline images (str or list)

  • attachments – File path(s) of attachments (str or list)

Returns:

Tuple of (MIME message object, list of recipient addresses)

sendMail.generate_mailing(param)[source]

Generates and sends emails to a list of subscribers based on provided parameters and subscriber information.

This function reads a list of recipients from a CSV file and sends them emails in batched groups. The function supports various profiles for filtering recipients, skipping initial records, and processing up to a certain index. It respects constraints like maximum recipients per email, maximum emails sent per hour, and pauses between batches. The email messages can include custom formatting, attachments, and can be sent using different email delivery methods based on the profile.

If an error occurs during execution, the function logs the error and attempts to finish gracefully.

Parameters:

param (Any) – An object containing configuration attributes required to generate, filter, and send emails. The attributes include limits, filters, email parameters, and operational flags.

Returns:

A string “OK” if email generation and sending complete successfully, or “Error” if an error occurs.

Return type:

str

sendMail.filter(filter: dict[str, str], row: list[Any], indices: dict[str, int]) bool[source]

Filter row: return True if should be EXCLUDED, False if INCLUDED.

Applies filter conditions to subscriber row. All filter conditions must match for row to be included (AND logic).

Supported operations: is, is not, gt, lt, ge, le, in, not in, is empty, is not empty, contains, does not contain, starts with, ends with, matches, does not match, and their aliases (e.g., “greater than”, “one of”).

Parameters:
  • filter – Dict of {field_name: “operator value”} (e.g., {“status”: “is active”})

  • row – List of subscriber field values

  • indices – Dict mapping field names to column indices

Returns:

True if row should be filtered OUT (excluded), False if INCLUDED

sendMail.send_gmail(service, message=None)[source]

Sends an email message using the Gmail API.

This function encodes the message in Base64 and uses the provided Gmail service to send the email. It handles errors and logs any failures.

Parameters:
  • service (googleapiclient.discovery.Resource) – An authorized Gmail API service instance.

  • message (MIMEMultipart or MIMEText) – The email message as a MIME object.

Returns:

The sent message resource if successful, None otherwise.

Return type:

dict or None

sendMail.send_mail(param: Any = None, message: Any = None, recipients: Any = None) bool[source]

Send an email message to specified recipients using SMTP.

This function attempts to send an email message to the specified list of recipients using an SMTP connection. It retries sending the email up to two times in case of a failure. Logging and other functionalities depend on the settings provided in the param object. The email is saved to the sent records if it is successfully sent.

Parameters:
  • param – Configuration object that determines the behavior of the email-sending process

  • message – The email message to be sent with “From” field populated

  • recipients – List of recipient email addresses

Returns:

Boolean indicating whether the email was successfully sent

sendMail.get_newsletter_name(files, args)[source]

Parses given files and updates newsletter-related attributes in the provided arguments.

The function analyses filenames and their extensions to infer newsletter-related details such as subject, newsletter name, and message body. It modifies the attributes of the provided args object accordingly.

Parameters:
  • files (list[str]) – List of file paths to analyze

  • args (Any) – Arguments object that holds properties like subject, newsletter_name, and message

Returns:

Updated arguments object with inferred newsletter details

Return type:

Any

sendMail.process_profile(args)[source]

Processes the user profile to configure and send a mailing task with attachments. The function integrates configurations, manages secrets, processes attachments, and dynamically generates and sends the mailing.

Parameters:

args – The argparse.Namespace object containing the configurations and command-line arguments required for the mailing process.

Returns:

A string indicating the success or failure of the process. Returns “OK” if the mailing was successfully sent in normal mode, “OK_TEST” if it was successfully sent in test mode, and “Error” otherwise.

sendMail.check_mandatory_param(param: Any) bool[source]

Validates that all mandatory parameters are present and correctly configured.

This function ensures that required parameters for mailing operations are set and valid before proceeding with the mailing process. It checks for:

  • Common Parameters: subject, sender, sendername, message.

  • Data Source: either a CSV database path or (Google Service Account and Sheet ID).

  • Mailing Method:
    • SMTP/IMAP mode: smtp_host, smtp_port, imap_host, imap_port, username, password, sent_folder.

    • Gmail mode: token_file, scopes, credentials_id.

Parameters:

param (Dict2Class) – An object containing configuration parameters.

Returns:

True if all mandatory parameters are present, False otherwise.

Return type:

bool

sendMail.setup_argparse()[source]

Sets up and parses command-line arguments for a mailing utility.

This function configures an argument parser with various command-line options to customize email sending behavior. The options include mail subject, body, attachments, database indices, test mode, verbosity, and other configurations for controlling email sending and processing.

Returns:

Parsed arguments from the command line

Return type:

argparse.Namespace

Options:
  • -cfg, –config: Path to the configuration file (default: User Home folder).

  • -s, –subject: Subject of the mail (default: None).

  • -m, –message: Text message of the mail (default: an empty string).

  • file: A list of files to attach to the mail (default: []).

  • -t, –test: Test mode flag; sends only to a tester group (default: False).

  • -v, –verbose: Flag to increase output verbosity (default: False).

  • -x, –doNotSend: Flag to disable mail sending (default: False).

  • -db, –database: Database path (default: None).

  • -f, –from_index: Starting index in the database (default: None).

  • -to, –to_index: Stopping index in the database (default: None).

  • -w, –wait: Waiting time in minutes before restarting mail sending (default: None).

  • –selected: Flag to send only selected mail (default: False).

  • –body: Specifies the email body (default: None).

  • -mh, –max-mails-per-hour: Maximum emails to send per hour (default: 1000).

  • -na, –max_addr_per_mail: Maximum number of addresses per mail (default: 50).

  • -p, –pause: Pause duration in seconds between operations (default: 3).

  • –md2html: Flag to convert input Markdown file to embedded HTML (default: False).

  • –keep-html: Flag to keep the generated HTML file (default: False).

  • –profile: Specifies the mail profile to use (default: None).

sendMail.main()[source]

Changes the current working directory to the directory of the executing file, parses command-line arguments, and loads configuration settings from a YAML file. Based on the specified profile in the arguments, it processes the respective profile logic.

Returns:

None

Classes

Dict2Class

class sendMail.Dict2Class(my_dict: dict[str, Any])[source]

Bases: object

Convert dictionary to object with lowercase attribute names.

Allows dict-like configs to be accessed as objects (obj.key instead of dict[‘key’]). All keys are converted to lowercase attribute names.

Parameters:

my_dict – Dictionary to convert to object

Example

config = Dict2Class({‘Name’: ‘John’, ‘Email’: ‘j@example.com’}) config.name # ‘John’ config.email # ‘j@example.com

__init__(my_dict: dict[str, Any]) None[source]

Functions

Logging & Initialization

sendMail.init_log(log_file: str | None = None) Logger[source]

Initialize logging configuration.

Sets up logging with default format, level, and optional file handler.

Parameters:

log_file – Path to log file. If None, logs to console only (default: None)

Returns:

Configured Logger instance

Google Sheets Functions

sendMail.open_google_db_members_sheet(sa: str, sheet_id: str) Any[source]

Open Google Sheet and return spreadsheet object.

Parameters:
  • sa – Service account entry name in secret vault

  • sheet_id – Google Sheet ID entry name in secret vault

Returns:

gspread Spreadsheet object for reading/writing data

sendMail.read_all_sheet(wb: Any, sheet_name: str = '') list[list[Any]][source]

Read all values from a Google Sheet.

Parameters:
  • wb – gspread Spreadsheet object

  • sheet_name – Sheet name to read. If empty, reads first sheet

Returns:

List of lists containing all sheet values (array of arrays)

File Utilities

sendMail.guess_type(filepath: str) str | None[source]

Detect MIME type of a file by content or extension.

Tries magic-based detection first (file content), falls back to extension-based guessing if magic not available.

Parameters:

filepath – Path to file to identify

Returns:

MIME type string (e.g., ‘image/png’) or None if detection fails

sendMail.file_to_base64(filepath: str) str[source]

Encode file contents as base64 string.

Handles both local files and HTTP URLs.

Parameters:

filepath – Local file path or HTTP URL

Returns:

Base64 encoded file content as string, or empty string on error

HTML Processing

sendMail.prepare_html_for_cid(in_filepath)[source]

Prepare HTML content for embedding inline images as Content-ID (CID) references.

This function processes an HTML file, reads its content, identifies the <img> tags, and replaces their src attributes with Content-ID (CID) references, allowing the images to be embedded inline in emails. It handles local image paths and excludes external or base64-encoded images. A mapping of the local image paths and the generated CIDs is returned.

Parameters:

in_filepath (str) – The file path to the HTML file to be processed.

Returns:

A tuple containing the modified HTML content as a string and a list of tuples, where each tuple includes the local image file path and its associated CID.

Return type:

tuple[str, list[tuple[str, str]]]

sendMail.prepare_html_and_get_images(in_filepath, max_width=800)[source]

Processes an HTML file to embed inline images and resize them for optimized usage.

Parameters:
  • in_filepath (str) – The path to the input HTML file.

  • max_width (int, optional) – The maximum allowable width for images. Images wider than this will be resized. Defaults to 800.

Returns:

A tuple containing the modified HTML content as a string, a list of inline image metadata dictionaries with optimized file paths and their corresponding CID references, and the path to the temporary directory used for storing the optimized images.

Return type:

tuple[str, list[dict[str, str]], str]

sendMail.md2html(file_path, styles=None, embed_styles=False)[source]

Converts a Markdown file to an HTML file with optional styling.

The function reads a Markdown file, converts its content to an HTML document using the Markdown library, and writes the resulting HTML to a new file. Default and optional CSS styles can be embedded in or linked from the resulting HTML document.

Parameters:
  • file_path (str) – The file path of the Markdown file to be converted.

  • styles (str, optional) – Optional path to a CSS file for custom styling. Defaults to None.

  • embed_styles (bool) – Specifies whether to embed styles directly into the HTML. If True and a valid styles path is provided, the CSS content will be embedded as inline styles. Defaults to False.

Returns:

The file path of the created HTML file, or None if the process fails (e.g., if the Markdown file does not exist).

Return type:

str or None

Email Building & Sending

sendMail.build_email(param: Any, subject: str = '', to: str = '', cc: str = '', bcc: str | None = None, message: str = '', images: str | list[str] | None = None, attachments: str | list[str] | None = None) tuple[MIMEMultipart, list[str]][source]

Build MIME email message with attachments and inline images.

Constructs multipart email with headers, body, inline images, and attachments. Supports HTML/text bodies, inline CID images, and file attachments.

Parameters:
  • param – Configuration object with sender details

  • subject – Email subject line

  • to – Comma-separated To addresses

  • cc – Comma-separated CC addresses

  • bcc – Comma-separated BCC addresses

  • message – HTML or text email body

  • images – File path(s) of inline images (str or list)

  • attachments – File path(s) of attachments (str or list)

Returns:

Tuple of (MIME message object, list of recipient addresses)

sendMail.send_mail(param: Any = None, message: Any = None, recipients: Any = None) bool[source]

Send an email message to specified recipients using SMTP.

This function attempts to send an email message to the specified list of recipients using an SMTP connection. It retries sending the email up to two times in case of a failure. Logging and other functionalities depend on the settings provided in the param object. The email is saved to the sent records if it is successfully sent.

Parameters:
  • param – Configuration object that determines the behavior of the email-sending process

  • message – The email message to be sent with “From” field populated

  • recipients – List of recipient email addresses

Returns:

Boolean indicating whether the email was successfully sent

sendMail.send_gmail(service, message=None)[source]

Sends an email message using the Gmail API.

This function encodes the message in Base64 and uses the provided Gmail service to send the email. It handles errors and logs any failures.

Parameters:
  • service (googleapiclient.discovery.Resource) – An authorized Gmail API service instance.

  • message (MIMEMultipart or MIMEText) – The email message as a MIME object.

Returns:

The sent message resource if successful, None otherwise.

Return type:

dict or None

sendMail.get_gmail_service(param)[source]

Fetches and returns the Gmail service object by authenticating through OAuth2. If valid credentials are not found locally, the function retrieves them via authorized secrets or user authentication interaction.

Parameters:

param (object) – An object containing the following attributes: - token_file: A path to the file holding the user’s token information. - scopes: A list of OAuth2 scopes required by the Gmail API. - token_id: Identifier for fetching the token via secret management. - credentials_id: Identifier for fetching OAuth2 client credentials via secret management. - SCOPES: A list of OAuth2 scopes required for the authentication process.

Returns:

A Google API client service object for accessing the Gmail API.

Return type:

googleapiclient.discovery.Resource

Message Processing

sendMail.generate_mailing(param)[source]

Generates and sends emails to a list of subscribers based on provided parameters and subscriber information.

This function reads a list of recipients from a CSV file and sends them emails in batched groups. The function supports various profiles for filtering recipients, skipping initial records, and processing up to a certain index. It respects constraints like maximum recipients per email, maximum emails sent per hour, and pauses between batches. The email messages can include custom formatting, attachments, and can be sent using different email delivery methods based on the profile.

If an error occurs during execution, the function logs the error and attempts to finish gracefully.

Parameters:

param (Any) – An object containing configuration attributes required to generate, filter, and send emails. The attributes include limits, filters, email parameters, and operational flags.

Returns:

A string “OK” if email generation and sending complete successfully, or “Error” if an error occurs.

Return type:

str

sendMail.process_attachments(args, config, folder='input')[source]

Processes attachments by either verifying file paths provided in the arguments or downloading files from a Google Drive folder and cleaning up the local folder. Returns processed file paths, the Google Drive service connection, and metadata about the downloaded files.

Parameters:
  • args (Namespace) – Command-line arguments containing file paths or other configurations.

  • config (dict) – Configuration dictionary containing keys like ‘SA’ for service account and ‘mailing_folder’ for desired Google Drive folder ID.

  • folder (str) – Optional path to the local folder used for downloading files. Defaults to “input”.

Returns:

A tuple containing the list of processed file paths, the Google Drive service connection object (or None if unused), and metadata about files fetched from Google Drive.

Return type:

tuple[list[str], Union[Resource, None], list[dict]]

SMTP & IMAP

sendMail.get_smtp_connection(param: Any) SMTP | None[source]

Open SMTP connection with TLS.

Creates connection to SMTP server, upgrades to TLS, and authenticates with provided credentials.

Parameters:

param – Configuration object with smtp_host, smtp_port, username, password

Returns:

SMTP connection object, or None if connection failed

Raises:

SystemExit – On authentication failure (logs critical error)

sendMail.save_to_sent(param: Any, msg: MIMEMultipart) None[source]

Store message in IMAP Sent folder.

Saves sent email to Sent folder for archival. Retries up to 3 times on failure with 10-second delays.

Parameters:
  • param – Configuration object with imap_host, imap_port, username, password, sent_folder, verbose

  • msg – Email message (MIMEMultipart) to store

Configuration & Validation

sendMail.check_mandatory_param(param: Any) bool[source]

Validates that all mandatory parameters are present and correctly configured.

This function ensures that required parameters for mailing operations are set and valid before proceeding with the mailing process. It checks for:

  • Common Parameters: subject, sender, sendername, message.

  • Data Source: either a CSV database path or (Google Service Account and Sheet ID).

  • Mailing Method:
    • SMTP/IMAP mode: smtp_host, smtp_port, imap_host, imap_port, username, password, sent_folder.

    • Gmail mode: token_file, scopes, credentials_id.

Parameters:

param (Dict2Class) – An object containing configuration parameters.

Returns:

True if all mandatory parameters are present, False otherwise.

Return type:

bool

Filtering & Data Processing

sendMail.get_subscriber_reader(param)[source]

Returns a reader object and file handle for retrieving subscriber data based on the given parameter. The function retrieves the data either from a Google Sheets document or a local CSV file, depending on the configuration in the parameter. If the database file is not found, it logs the error and returns None, None.

Parameters:

param (object) – The configuration object containing details for data retrieval (e.g., Google Sheets credentials or CSV/XLS database path).

Returns:

A tuple consisting of a data reader object (either for Google Sheets or CSV) and a file handle. If the database is not found, it returns (None, None).

Return type:

tuple(iterator | None, file | None)

sendMail.get_indices(header: list[Any]) dict[str, int][source]

Create a dictionary that maps each header element to its corresponding index in the list of headers.

Parameters:

header – List of header values (strings or other types from CSV/sheets).

Returns:

Dictionary where keys are string representations of header elements and values are their corresponding indices.

sendMail.format_message(template: str, row: list[Any], header: list[str]) str[source]

Format message by replacing ${field} placeholders with row values.

Substitutes template placeholders with subscriber data. Placeholders use syntax ${column_name} which maps to header column names.

Parameters:
  • template – Template string with ${field_name} placeholders

  • row – List of subscriber values (one per column)

  • header – List of column/field names (indices match row)

Returns:

Formatted message with values substituted, or original template on error

sendMail.filter(filter: dict[str, str], row: list[Any], indices: dict[str, int]) bool[source]

Filter row: return True if should be EXCLUDED, False if INCLUDED.

Applies filter conditions to subscriber row. All filter conditions must match for row to be included (AND logic).

Supported operations: is, is not, gt, lt, ge, le, in, not in, is empty, is not empty, contains, does not contain, starts with, ends with, matches, does not match, and their aliases (e.g., “greater than”, “one of”).

Parameters:
  • filter – Dict of {field_name: “operator value”} (e.g., {“status”: “is active”})

  • row – List of subscriber field values

  • indices – Dict mapping field names to column indices

Returns:

True if row should be filtered OUT (excluded), False if INCLUDED

Profile Processing

sendMail.process_profile(args)[source]

Processes the user profile to configure and send a mailing task with attachments. The function integrates configurations, manages secrets, processes attachments, and dynamically generates and sends the mailing.

Parameters:

args – The argparse.Namespace object containing the configurations and command-line arguments required for the mailing process.

Returns:

A string indicating the success or failure of the process. Returns “OK” if the mailing was successfully sent in normal mode, “OK_TEST” if it was successfully sent in test mode, and “Error” otherwise.

Command-line Interface

sendMail.setup_argparse()[source]

Sets up and parses command-line arguments for a mailing utility.

This function configures an argument parser with various command-line options to customize email sending behavior. The options include mail subject, body, attachments, database indices, test mode, verbosity, and other configurations for controlling email sending and processing.

Returns:

Parsed arguments from the command line

Return type:

argparse.Namespace

Options:
  • -cfg, –config: Path to the configuration file (default: User Home folder).

  • -s, –subject: Subject of the mail (default: None).

  • -m, –message: Text message of the mail (default: an empty string).

  • file: A list of files to attach to the mail (default: []).

  • -t, –test: Test mode flag; sends only to a tester group (default: False).

  • -v, –verbose: Flag to increase output verbosity (default: False).

  • -x, –doNotSend: Flag to disable mail sending (default: False).

  • -db, –database: Database path (default: None).

  • -f, –from_index: Starting index in the database (default: None).

  • -to, –to_index: Stopping index in the database (default: None).

  • -w, –wait: Waiting time in minutes before restarting mail sending (default: None).

  • –selected: Flag to send only selected mail (default: False).

  • –body: Specifies the email body (default: None).

  • -mh, –max-mails-per-hour: Maximum emails to send per hour (default: 1000).

  • -na, –max_addr_per_mail: Maximum number of addresses per mail (default: 50).

  • -p, –pause: Pause duration in seconds between operations (default: 3).

  • –md2html: Flag to convert input Markdown file to embedded HTML (default: False).

  • –keep-html: Flag to keep the generated HTML file (default: False).

  • –profile: Specifies the mail profile to use (default: None).

sendMail.main()[source]

Changes the current working directory to the directory of the executing file, parses command-line arguments, and loads configuration settings from a YAML file. Based on the specified profile in the arguments, it processes the respective profile logic.

Returns:

None

Command-Line Arguments

The sendMail module can be invoked from the command line with the following arguments:

Basic Options

Argument

Type

Description

--profile

string

Required. Mail profile to use (artscroises or cambristi)

-s, --subject

string

Subject of the email

-m, --message

string

Text message body of the email

file

list

Files to attach to the email (positional argument, can specify multiple files)

Test & Debug Options

Argument

Type

Description

-t, --test

flag

Test mode - send only to the tester group

-v, --verbose

flag

Increase output verbosity

-x, --doNotSend

flag

Do not send any mail (dry run)

Database Options

Argument

Type

Description

-db, --database

string

Path to CSV database file (alternative to Google Sheets)

-f, --from_index

integer

Starting index in the database

-to, --to_index

integer

Stopping index in the database

--selected

flag

Only send to selected recipients

Rate Limiting & Batch Options

Argument

Type

Description

-mh, --max-mails-per-hour

integer

Maximum emails to send per hour (default: 1000)

-na, --max_addr_per_mail

integer

Maximum number of addresses per mail (default: 50)

-p, --pause

integer

Pause duration in seconds between operations (default: 3)

-w, --wait

integer

Wait x minutes before starting to send mail

Other Options

Argument

Type

Description

--body

string

Specifies the email body content

--check_spam

flag

Perform spam detection checks

Usage Examples

Example 1: Basic Newsletter with Attachments

Send a newsletter to all active members with a PDF attachment:

python src/sendMail.py --profile artscroises \
    -s "Newsletter January 2026" \
    newsletter.pdf logo.png

Example 2: Test Mode with Custom Message

Test email sending with a custom message to the test group only:

python src/sendMail.py --profile artscroises \
    -s "Test Newsletter" \
    -m "This is a test message" \
    -t \
    -v \
    newsletter.pdf

Example 3: HTML Email with Rate Limiting

Send HTML email with controlled rate limiting:

python src/sendMail.py --profile cambristi \
    -s "Event Announcement" \
    -mh 500 \
    -na 25 \
    -p 5 \
    email_template.html

Example 4: Partial Database Processing

Process only records 100 to 200 from the database:

python src/sendMail.py --profile artscroises \
    -s "Newsletter" \
    -f 100 \
    -to 200 \
    newsletter.pdf

Example 5: Dry Run (No Sending)

Preview what would be sent without actually sending emails:

python src/sendMail.py --profile artscroises \
    -s "Newsletter Test" \
    -x \
    -v \
    newsletter.pdf

Example 6: Selected Recipients Only

Send only to recipients marked as “selected” in the database:

python src/sendMail.py --profile artscroises \
    -s "Special Announcement" \
    --selected \
    announcement.pdf

Example 7: Using CSV Database

Use a local CSV file instead of Google Sheets:

python src/sendMail.py --profile artscroises \
    -s "Newsletter" \
    -db subscribers.csv \
    newsletter.pdf

Example 8: Delayed Send with Wait Time

Wait 30 minutes before starting the mail campaign:

python src/sendMail.py --profile artscroises \
    -s "Scheduled Newsletter" \
    -w 30 \
    newsletter.pdf

Configuration

The module requires a config.yml file with profile-specific settings:

artscroises:
  MAILCONFIG: "ArtsCroisesMailConfig"
  SA: "artscroisesServiceAccount"
  sheetid: "artscroisesmembersdb"
  mailing_folder: "folder_id_from_google_drive"
  smtp_host: "smtp.example.com"
  smtp_port: 587
  imap_host: "imap.example.com"
  imap_port: 993
  max_mails_per_hour: 1000
  max_addr_per_mail: 50
  pause: 3

cambristi:
  MAILCONFIG: "CambristiMailConfig"
  # Similar configuration...

Secrets (credentials, API keys) should be stored securely using the getSecrets module.