Skip to main content

Official Python SDK for MailBlock email service

Project description

MailBlock Python SDK

Python Version Version License

Official Python SDK for the MailBlock email service. Send emails with confidence using a clean, Pythonic interface with comprehensive error handling, logging, and validation.

๐Ÿš€ Features

  • Fluent Builder Pattern - Intuitive, chainable API for email construction
  • Comprehensive Error Handling - Detailed error messages with helpful suggestions
  • Async/Await Support - Both synchronous and asynchronous email sending
  • Email Scheduling - Schedule emails for future delivery
  • Robust Validation - Client-side validation with detailed feedback
  • Advanced Logging - Built-in debugging and request tracking
  • Type Hints - Full type safety with mypy support
  • Context Manager - Proper resource management
  • Retry Mechanism - Automatic retry with exponential backoff

MailBlock Python SDK

Python Version Version License

Official Python SDK for the MailBlock email service. Send emails with confidence using a clean, Pythonic interface with comprehensive error handling, logging, and validation.

๐Ÿš€ Features

  • Fluent Builder Pattern - Intuitive, chainable API for email construction
  • Comprehensive Error Handling - Detailed error messages with helpful suggestions
  • Async/Await Support - Both synchronous and asynchronous email sending
  • Email Scheduling - Schedule emails for future delivery
  • Robust Validation - Client-side validation with detailed feedback
  • Advanced Logging - Built-in debugging and request tracking
  • Type Hints - Full type safety with mypy support
  • Context Manager - Proper resource management
  • Retry Mechanism - Automatic retry with exponential backoff

๐Ÿ“ฆ Installation

# Install from PyPI
pip install mailblock

# For async support
pip install mailblock[async]

# For development
pip install mailblock[dev]

๐Ÿ”ง Quick Start

from mailblock import MailBlock

# Initialize client
client = MailBlock("your-api-key")

# Send a simple email
response = client.email() \
    .to("recipient@example.com") \
    .from_email("sender@example.com") \
    .subject("Hello from MailBlock!") \
    .text("This is a test email from the MailBlock Python SDK.") \
    .send_sync()

if response.success:
    print(f"Email sent! ID: {response.data['id']}")
else:
    print(f"Error: {response.error}")

๐Ÿ“š Documentation

Client Initialization

from mailblock import MailBlock

# Basic initialization
client = MailBlock("your-api-key")

# With custom configuration
client = MailBlock(
    api_key="your-api-key",
    base_url="https://api.mailblock.com",  # Custom API endpoint
    timeout=30,                            # Request timeout in seconds
    max_retries=3,                        # Maximum retry attempts
    retry_delay=1.0,                      # Base retry delay in seconds
    debug=True                            # Enable debug logging
)

Basic Email Sending

Synchronous

# Simple text email
response = client.email() \
    .to("recipient@example.com") \
    .from_email("sender@example.com") \
    .subject("Hello World") \
    .text("This is a plain text email.") \
    .send_sync()

# HTML email with fallback text
response = client.email() \
    .to("user@example.com") \
    .from_email("noreply@yourapp.com") \
    .subject("Welcome!") \
    .text("Welcome to our service!") \
    .html("<h1>Welcome!</h1><p>Thanks for joining us.</p>") \
    .send_sync()

Asynchronous

import asyncio

async def send_email():
    response = await client.email() \
        .to("recipient@example.com") \
        .from_email("sender@example.com") \
        .subject("Async Email") \
        .text("This email was sent asynchronously!") \
        .send()
    return response

# Run async function
response = asyncio.run(send_email())

Email Scheduling

from datetime import datetime, timedelta

# Schedule for 1 hour from now
send_time = datetime.now() + timedelta(hours=1)

response = client.email() \
    .to("recipient@example.com") \
    .from_email("scheduler@example.com") \
    .subject("Scheduled Email") \
    .text("This email was scheduled for delivery.") \
    .schedule_at(send_time) \
    .send_sync()

# Schedule with date string
response = client.email() \
    .to("recipient@example.com") \
    .from_email("scheduler@example.com") \
    .subject("Scheduled Email") \
    .text("Scheduled via date string.") \
    .schedule_at("2024-12-25T10:00:00") \
    .send_sync()

Error Handling

from mailblock import ValidationError, AuthenticationError, RateLimitError

try:
    response = client.email() \
        .to("invalid-email") \
        .from_email("sender@example.com") \
        .subject("Test") \
        .text("Test content") \
        .send_sync()

except ValidationError as e:
    print(f"Validation error: {e}")
    print(f"Suggestion: {e.suggestion}")

except AuthenticationError as e:
    print(f"Authentication failed: {e}")
    print(f"Request ID: {e.request_id}")

except RateLimitError as e:
    print(f"Rate limited: {e}")
    print(f"Suggestion: {e.suggestion}")

except Exception as e:
    print(f"Unexpected error: {e}")

Advanced Usage

Bulk Email Sending

import asyncio

async def send_bulk_emails():
    recipients = [
        "user1@example.com",
        "user2@example.com",
        "user3@example.com"
    ]

    # Send emails concurrently
    tasks = []
    for recipient in recipients:
        task = client.email() \
            .to(recipient) \
            .from_email("bulk@example.com") \
            .subject("Bulk Email") \
            .text(f"Personal email for {recipient}") \
            .send()
        tasks.append(task)

    responses = await asyncio.gather(*tasks, return_exceptions=True)

    for i, response in enumerate(responses):
        if isinstance(response, Exception):
            print(f"Email {i+1} failed: {response}")
        elif response.success:
            print(f"Email {i+1} sent successfully")
        else:
            print(f"Email {i+1} failed: {response.error}")

asyncio.run(send_bulk_emails())

Custom Logger

import logging

# Set up custom logger
logger = logging.getLogger("my_app.mailblock")
logger.setLevel(logging.DEBUG)

handler = logging.FileHandler("email.log")
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

# Use custom logger
client = MailBlock("your-api-key", debug=True, logger=logger)

Context Manager

# Ensures proper cleanup of resources
with MailBlock("your-api-key") as client:
    response = client.email() \
        .to("recipient@example.com") \
        .from_email("sender@example.com") \
        .subject("Context Manager Test") \
        .text("This uses proper resource management.") \
        .send_sync()

Direct Email Data

from mailblock import EmailData

# Create email data directly
email_data = EmailData(
    to="recipient@example.com",
    from_email="sender@example.com",
    subject="Direct Send",
    text="Sent without builder pattern",
    html="<p>Sent <strong>without</strong> builder pattern</p>"
)

# Send directly
response = client.send_email_sync(email_data)

๐Ÿ” API Response

All send methods return an APIResponse object with the following structure:

class APIResponse:
    success: bool                    # Whether the request succeeded
    request_id: str                 # Unique request identifier
    timestamp: datetime             # When the request was made
    duration: int                   # Request duration in milliseconds

    # On success
    data: Dict[str, Any]           # Response data (includes email ID)
    message: str                   # Success message

    # On error
    error: str                     # Error message
    error_type: str               # Error category
    suggestion: str               # Helpful suggestion
    status_code: int              # HTTP status code
    endpoint: str                 # API endpoint used

Success Response Example

if response.success:
    print(f"Email ID: {response.data['id']}")
    print(f"Status: {response.data['status']}")
    print(f"Duration: {response.duration}ms")
    print(f"Request ID: {response.request_id}")

Error Response Example

if not response.success:
    print(f"Error: {response.error}")
    print(f"Type: {response.error_type}")
    print(f"Suggestion: {response.suggestion}")
    print(f"Status Code: {response.status_code}")
    print(f"Request ID: {response.request_id}")

๐Ÿ›ก๏ธ Exception Hierarchy

MailBlockError                    # Base exception
โ”œโ”€โ”€ ValidationError              # Client-side validation errors
โ”œโ”€โ”€ AuthenticationError          # Invalid API key (401)
โ”œโ”€โ”€ AuthorizationError           # Insufficient permissions (403)
โ”œโ”€โ”€ RateLimitError              # Rate limiting (429)
โ”œโ”€โ”€ ServerError                 # Server errors (5xx)
โ”œโ”€โ”€ NetworkError                # Connection issues
โ””โ”€โ”€ TimeoutError                # Request timeouts

โš™๏ธ Configuration Options

Parameter Type Default Description
api_key str Required Your MailBlock API key
base_url str https://sdk-backend-production-20e1.up.railway.app API base URL
timeout int 30 Request timeout in seconds
max_retries int 3 Maximum retry attempts
retry_delay float 1.0 Base retry delay in seconds
debug bool False Enable debug logging
logger Logger None Custom logger instance

๐Ÿงช Testing

# Install development dependencies
pip install -e .[dev]

# Run tests
pytest

# Run tests with coverage
pytest --cov=mailblock

# Run specific test file
pytest tests/test_client.py

# Run with verbose output
pytest -v

๐Ÿ—๏ธ Development

# Clone repository
git clone https://github.com/5ysc4ll/mailblock-python.git
cd mailblock-python

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install in development mode
pip install -e .[dev]

# Run linting
flake8 mailblock tests
black mailblock tests
isort mailblock tests

# Type checking
mypy mailblock

๐Ÿ“‹ Examples

Check out the examples/ directory for comprehensive usage examples:

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Run the test suite (pytest)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ› Issues & Support

๐Ÿ”— Links

๐Ÿ“Š Changelog

v1.0.0 (Initial Release)

  • โœจ Fluent builder pattern for email construction
  • ๐Ÿ”„ Both sync and async email sending
  • โฐ Email scheduling support
  • ๐Ÿ›ก๏ธ Comprehensive error handling and validation
  • ๐Ÿ“ Advanced logging and debugging
  • ๐Ÿ” Automatic retry with exponential backoff
  • ๐Ÿ“š Complete type hints and mypy support
  • โœ… Comprehensive test suite
  • ๐Ÿ“– Full documentation and examples

Built with โค๏ธ by the MailBlock Team

Project details


Download files

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

Source Distribution

mailblock-1.0.1.tar.gz (20.1 kB view details)

Uploaded Source

Built Distribution

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

mailblock-1.0.1-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file mailblock-1.0.1.tar.gz.

File metadata

  • Download URL: mailblock-1.0.1.tar.gz
  • Upload date:
  • Size: 20.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.4

File hashes

Hashes for mailblock-1.0.1.tar.gz
Algorithm Hash digest
SHA256 26fad2f4669523f2aef2a627ef0e0cf970abd1d870e3fa58ca13cb5edac5b3bc
MD5 266326ef9e022b54b5637ebacf4cbbbc
BLAKE2b-256 7d62c2d1e3261794c846537eb61a77d5511db068d8987e565a74df5585274bba

See more details on using hashes here.

File details

Details for the file mailblock-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: mailblock-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 18.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.4

File hashes

Hashes for mailblock-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 63968b06a93f2923568d2c0b157ad29295f0c7722808e70aad0e2ad0e55a2106
MD5 3b781bdb8507ce10d0165284cf481ed9
BLAKE2b-256 fbd4390147a6578bb052972136282f7595f6a8fc8ddcecc791448fc4c8c7cad9

See more details on using hashes here.

Supported by

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