Python SDK for the Mailnow email API - send emails programmatically with a simple, type-safe interface
Project description
Mailnow Python SDK
A simple, type-safe Python SDK for the Mailnow email API. Send emails programmatically with just a few lines of code.
Features
- 🚀 Simple, intuitive API
- 🔒 Type-safe with full type hints
- ✅ Comprehensive input validation
- 🎯 Detailed error handling
- 📝 Extensive documentation
- 🧪 Thoroughly tested
Installation
Install the SDK using pip:
pip install py-mailnow
Quick Start
from mailnow import MailnowClient
# Initialize the client with your API key
client = MailnowClient(api_key="mn_live_7e59df7ce4a14545b443837804ec9722")
# Send an email
response = client.send_email(
from_email="sender@example.com",
to_email="recipient@example.com",
subject="Hello from Mailnow!",
html="<h1>Welcome!</h1><p>This is your first email.</p>"
)
print(f"Email sent! Message ID: {response['message_id']}")
API Key Format
Your Mailnow API key must be in one of the following formats:
- Production:
mn_live_followed by your unique key (e.g.,mn_live_7e59df7ce4a14545b443837804ec9722) - Testing:
mn_test_followed by your unique key (e.g.,mn_test_abc123def456)
You can find your API key in your Mailnow dashboard.
Usage Examples
Basic Email Sending
from mailnow import MailnowClient
client = MailnowClient(api_key="mn_live_7e59df7ce4a14545b443837804ec9722")
response = client.send_email(
from_email="noreply@yourcompany.com",
to_email="customer@example.com",
subject="Welcome to Our Service",
html="<h1>Welcome!</h1><p>Thanks for signing up.</p>"
)
print(response)
# Output: {'success': True, 'message_id': 'msg_abc123', 'status': 'queued'}
With Error Handling
from mailnow import (
MailnowClient,
MailnowError,
MailnowValidationError,
MailnowAuthError,
MailnowRateLimitError,
MailnowServerError,
MailnowConnectionError
)
client = MailnowClient(api_key="mn_live_7e59df7ce4a14545b443837804ec9722")
try:
response = client.send_email(
from_email="sender@example.com",
to_email="recipient@example.com",
subject="Important Update",
html="<p>Your account has been updated.</p>"
)
print(f"✓ Email sent successfully: {response['message_id']}")
except MailnowValidationError as e:
print(f"✗ Validation error: {e}")
# Handle invalid input (missing fields, invalid email format, etc.)
except MailnowAuthError as e:
print(f"✗ Authentication error: {e}")
# Handle invalid or expired API key
except MailnowRateLimitError as e:
print(f"✗ Rate limit exceeded: {e}")
# Implement exponential backoff or retry logic
except MailnowServerError as e:
print(f"✗ Server error: {e}")
# Retry the request after a delay
except MailnowConnectionError as e:
print(f"✗ Connection error: {e}")
# Check network connectivity
except MailnowError as e:
print(f"✗ Unexpected error: {e}")
# Catch any other SDK errors
Sending HTML Emails
from mailnow import MailnowClient
client = MailnowClient(api_key="mn_live_7e59df7ce4a14545b443837804ec9722")
html_content = """
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
.header { background-color: #4CAF50; color: white; padding: 20px; }
.content { padding: 20px; }
</style>
</head>
<body>
<div class="header">
<h1>Welcome to Our Newsletter</h1>
</div>
<div class="content">
<p>Hello,</p>
<p>Thank you for subscribing to our newsletter!</p>
<p>Best regards,<br>The Team</p>
</div>
</body>
</html>
"""
response = client.send_email(
from_email="newsletter@yourcompany.com",
to_email="subscriber@example.com",
subject="Welcome to Our Newsletter",
html=html_content
)
Handling Multiple Recipients
from mailnow import MailnowClient, MailnowError
client = MailnowClient(api_key="mn_live_7e59df7ce4a14545b443837804ec9722")
recipients = [
"user1@example.com",
"user2@example.com",
"user3@example.com"
]
for recipient in recipients:
try:
response = client.send_email(
from_email="notifications@yourcompany.com",
to_email=recipient,
subject="System Notification",
html="<p>This is an automated notification.</p>"
)
print(f"✓ Sent to {recipient}: {response['message_id']}")
except MailnowError as e:
print(f"✗ Failed to send to {recipient}: {e}")
continue
Exception Types
The SDK provides detailed exception types for different error scenarios:
MailnowError
Base exception for all Mailnow SDK errors. Catch this to handle any SDK-related error.
try:
client.send_email(...)
except MailnowError as e:
print(f"SDK error: {e}")
MailnowValidationError
Raised when input validation fails. This includes:
- Missing or empty required parameters (
from_email,to_email,subject,html) - Invalid email address format
- Invalid API key format
- API returns 400 Bad Request
try:
client.send_email(
from_email="invalid-email", # Invalid format
to_email="user@example.com",
subject="Test",
html="<p>Test</p>"
)
except MailnowValidationError as e:
print(f"Validation error: {e}")
MailnowAuthError
Raised when authentication fails. This includes:
- Missing or None API key
- Empty API key
- Invalid API key format (doesn't start with
mn_live_ormn_test_) - API returns 401 Unauthorized
try:
client = MailnowClient(api_key="invalid_key")
except MailnowAuthError as e:
print(f"Authentication error: {e}")
MailnowRateLimitError
Raised when rate limit is exceeded (API returns 429 Too Many Requests). Consider implementing exponential backoff retry logic.
import time
try:
client.send_email(...)
except MailnowRateLimitError as e:
print(f"Rate limit exceeded: {e}")
time.sleep(60) # Wait before retrying
MailnowServerError
Raised when the Mailnow API experiences an internal error (5xx status codes). Consider retrying the request after a delay.
import time
max_retries = 3
for attempt in range(max_retries):
try:
response = client.send_email(...)
break
except MailnowServerError as e:
if attempt < max_retries - 1:
time.sleep(2 ** attempt) # Exponential backoff
continue
raise
MailnowConnectionError
Raised when network connection fails. This includes:
- Network connection cannot be established
- Request times out
- DNS resolution fails
- Any other network-level error
try:
client.send_email(...)
except MailnowConnectionError as e:
print(f"Connection error: {e}")
# Check network connectivity or retry
Type Hints and mypy Compatibility
The Mailnow SDK is fully type-annotated and compatible with mypy for static type checking. All public APIs include comprehensive type hints.
Running Type Checks
# Install mypy
pip install mypy
# Run type checking on your code
mypy your_script.py
Example with Type Hints
from typing import Dict, Any
from mailnow import MailnowClient
def send_welcome_email(client: MailnowClient, user_email: str) -> Dict[str, Any]:
"""Send a welcome email to a new user."""
return client.send_email(
from_email="welcome@yourcompany.com",
to_email=user_email,
subject="Welcome!",
html="<h1>Welcome to our platform!</h1>"
)
# mypy will catch type errors
client: MailnowClient = MailnowClient(api_key="mn_live_abc123")
response: Dict[str, Any] = send_welcome_email(client, "user@example.com")
API Reference
MailnowClient
Main client class for interacting with the Mailnow API.
__init__(api_key: str) -> None
Initialize the Mailnow client.
Parameters:
api_key(str): Your Mailnow API key (format:mn_live_*ormn_test_*)
Raises:
MailnowAuthError: If API key is invalid or missing
send_email(from_email: str, to_email: str, subject: str, html: str) -> Dict[str, Any]
Send an email via the Mailnow API.
Parameters:
from_email(str): Sender email address (must be valid format)to_email(str): Recipient email address (must be valid format)subject(str): Email subject line (cannot be empty)html(str): HTML content of the email (cannot be empty)
Returns:
Dict[str, Any]: Response dictionary containing:success(bool): Whether the email was successfully queuedmessage_id(str): Unique identifier for the messagestatus(str): Current status (e.g., "queued")
Raises:
MailnowValidationError: Invalid input parametersMailnowAuthError: Authentication failureMailnowRateLimitError: Rate limit exceededMailnowServerError: Server error (5xx)MailnowConnectionError: Network connection error
Requirements
- Python 3.12 or higher
- httpx >= 0.27.0
Development
Installing Development Dependencies
pip install py-mailnow[dev]
Running Tests
pytest
Running Type Checks
mypy mailnow
Code Formatting
black mailnow tests
ruff check mailnow tests
License
This project is licensed under the MIT License.
Support
- Documentation: GitHub README
- Issues: GitHub Issues
- Website: mailnow.xyz
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_mailnow-0.1.1.tar.gz.
File metadata
- Download URL: py_mailnow-0.1.1.tar.gz
- Upload date:
- Size: 77.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f529b12961222911d59eb48a9b06ff12dd22e49a6c6f4127179430dd5581022a
|
|
| MD5 |
f424b896152805fc7f9ccb7c37935061
|
|
| BLAKE2b-256 |
bbf03cd41a2415314fa895bd6c3ed20fcc9016e76207fe735eaf4f74da288cf6
|
File details
Details for the file py_mailnow-0.1.1-py3-none-any.whl.
File metadata
- Download URL: py_mailnow-0.1.1-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19fec350dea672ad56b88de9c10758c4c60c8995f679b513d356dd0c4b679797
|
|
| MD5 |
bc5347f0bb3a0efd3b6e1464ab5f23a1
|
|
| BLAKE2b-256 |
1e8f7f92ebdead5b24f5c436b56a926915e6630e4e9fd88eec71a31a030bd298
|