Skip to main content

Python client library for the Laneful API

Project description

Laneful Python Client

A Python client library for the Laneful API, providing easy email sending capabilities with support for templates, attachments, tracking, and webhooks.

Python Version License

Installation

The library supports flexible installation options:

# Default installation (sync client only)
pip install laneful

# Add async support to existing sync installation
pip install laneful[async] 

# Async-only (no sync dependencies)
pip install laneful[async-only]

# Explicit sync support (same as default)
pip install laneful[sync]

# Full support (both sync and async)
pip install laneful[all]

Quick Start

Synchronous Usage

pip install laneful  # Default installation
from laneful import LanefulClient, Email, Address

# Initialize the sync client
client = LanefulClient(
    base_url="https://custom-endpoint.send.laneful.net",
    auth_token="your-auth-token"
)

# Create an email
email = Email(
    from_address=Address(email="sender@example.com", name="Your Name"),
    to=[Address(email="recipient@example.com", name="Recipient Name")],
    subject="Hello from Laneful",
    text_content="This is a test email.",
    html_content="<h1>This is a test email.</h1>",
)

# Send the email
response = client.send_email(email)
print(f"Email sent successfully: {response.status}")

Asynchronous Usage

pip install laneful[async]  # Add async to sync
# OR
pip install laneful[async-only]  # Pure async, no sync deps
import asyncio
from laneful import AsyncLanefulClient, Email, Address

async def send_email_async():
    # Initialize the async client
    async with AsyncLanefulClient(
        base_url="https://custom-endpoint.send.laneful.net",
        auth_token="your-auth-token"
    ) as client:
        # Create an email
        email = Email(
            from_address=Address(email="sender@example.com", name="Your Name"),
            to=[Address(email="recipient@example.com", name="Recipient Name")],
            subject="Hello from Laneful (Async)",
            text_content="This is an async test email.",
            html_content="<h1>This is an async test email.</h1>",
        )
        
        # Send the email
        response = await client.send_email(email)
        print(f"Email sent successfully: {response.status}")

# Run the async function
asyncio.run(send_email_async())

Features

  • ✅ Send single or multiple emails
  • ✅ Support for plain text and HTML content
  • ✅ Email templates with dynamic data
  • ✅ File attachments
  • ✅ Email tracking (opens, clicks, unsubscribes)
  • ✅ Custom headers
  • ✅ Scheduled sending
  • ✅ Webhook handling
  • ✅ Reply-to addresses
  • ✅ Context manager support
  • ✅ Type hints and mypy support
  • ✅ Comprehensive error handling

API Reference

Creating Clients

Synchronous Client

from laneful import LanefulClient

client = LanefulClient(
    base_url="https://custom-endpoint.laneful.net",
    auth_token="your-auth-token",
    timeout=30.0,  # Optional: request timeout in seconds
    verify_ssl=True  # Optional: SSL verification
)

Asynchronous Client

from laneful import AsyncLanefulClient

# Method 1: Using async context manager (recommended)
async with AsyncLanefulClient(
    base_url="https://custom-endpoint.laneful.net",
    auth_token="your-auth-token",
    timeout=30.0,  # Optional: request timeout in seconds
    verify_ssl=True  # Optional: SSL verification
) as client:
    # Use client here
    pass

# Method 2: Manual session management
client = AsyncLanefulClient(base_url, auth_token)
try:
    # Use client here
    pass
finally:
    await client.close()

Email

from laneful import Email, Address, Attachment, TrackingSettings

email = Email(
    from_address=Address(email="sender@example.com", name="Sender"),
    to=[Address(email="recipient@example.com", name="Recipient")],
    subject="Email Subject",
    text_content="Plain text content",  # Optional
    html_content="<h1>HTML content</h1>",  # Optional
    cc=[Address(email="cc@example.com")],  # Optional
    bcc=[Address(email="bcc@example.com")],  # Optional
    reply_to=Address(email="reply@example.com"),  # Optional
    attachments=[],  # Optional: List of Attachment objects
    headers={"X-Custom": "value"},  # Optional
    template_id="template-123",  # Optional: for template emails
    template_data={"name": "John"},  # Optional: template variables
    send_time=1640995200,  # Optional: Unix timestamp for scheduling
    tracking=TrackingSettings(opens=True, clicks=True),  # Optional
    webhook_data={"user_id": "123"}  # Optional: custom webhook data
)

Sending Emails

Single Email (Sync)

response = client.send_email(email)
print(f"Status: {response.status}")
print(f"Message ID: {response.message_id}")

Single Email (Async)

response = await client.send_email(email)
print(f"Status: {response.status}")
print(f"Message ID: {response.message_id}")

Multiple Emails (Sync)

emails = [email1, email2, email3]
responses = client.send_emails(emails)

for i, response in enumerate(responses):
    print(f"Email {i+1} status: {response.status}")

Multiple Emails (Async)

emails = [email1, email2, email3]
responses = await client.send_emails(emails)

for i, response in enumerate(responses):
    print(f"Email {i+1} status: {response.status}")

Bulk Email Sending

For sending multiple emails at once, use the send_emails method:

from laneful import LanefulClient, Email, Address

client = LanefulClient("https://custom-endpoint.send.laneful.net", "your-auth-token")

emails = [
    Email(from_address=Address(email="sender@example.com"), 
          to=[Address(email="user1@example.com")], subject="Hello User 1"),
    Email(from_address=Address(email="sender@example.com"), 
          to=[Address(email="user2@example.com")], subject="Hello User 2"),
]

responses = client.send_emails(emails)

Concurrent Email Sending (Async Only)

import asyncio

async with AsyncLanefulClient(base_url, auth_token) as client:
    # Send multiple emails concurrently
    tasks = [client.send_email(email) for email in emails]
    responses = await asyncio.gather(*tasks)
    
    print(f"Sent {len(responses)} emails concurrently!")

Context Managers

# Sync context manager
with LanefulClient(base_url, auth_token) as client:
    response = client.send_email(email)
    print(f"Email sent: {response.status}")
# Client session automatically closed

# Async context manager  
async with AsyncLanefulClient(base_url, auth_token) as client:
    response = await client.send_email(email)
    print(f"Email sent: {response.status}")
# Client session automatically closed

Examples

Template Email

from laneful import Email, Address, LanefulClient

client = LanefulClient("https://custom-endpoint.send.laneful.net", "your-auth-token")

email = Email(
    from_address=Address(email="sender@example.com"),
    to=[Address(email="user@example.com")],
    subject="Welcome!",
    template_id="11",
    template_data={
        "name": "John Doe",
        "company": "Acme Corp",
        "activation_link": "https://example.com/activate?token=abc123"
    },
)

response = client.send_email(email)

Email with Attachments

import base64
from laneful import Attachment, Email, Address, LanefulClient

client = LanefulClient("https://custom-endpoint.send.laneful.net", "your-auth-token")

# Prepare attachment (base64 encoded content)
with open("document.pdf", "rb") as f:
    content = base64.b64encode(f.read()).decode()

email = Email(
    from_address=Address(email="sender@example.com"),
    to=[Address(email="user@example.com")],
    subject="Document Attached",
    text_content="Please find the document attached.",
    attachments=[
        Attachment(
            file_name="document.pdf",
            content=content,
            content_type="application/pdf",
            inline_id="123",
        )
    ],
)

response = client.send_email(email)

Scheduled Email

import time

from laneful import Email, Address, LanefulClient

client = LanefulClient("https://custom-endpoint.send.laneful.net", "your-auth-token")

# Schedule email to be sent 1 hour from now
send_time = int(time.time()) + 3600

email = Email(
    from_address=Address(email="sender@example.com"),
    to=[Address(email="user@example.com")],
    subject="Scheduled Email",
    text_content="This email was scheduled.",
    send_time=send_time,
)

response = client.send_email(email)

Email with Tracking

from laneful import TrackingSettings, Address, LanefulClient, Email

client = LanefulClient("https://custom-endpoint.send.laneful.net", "your-auth-token")

email = Email(
    from_address=Address(email="sender@example.com"),
    to=[Address(email="user@example.com")],
    subject="Tracked Email",
    html_content='<h1>Tracked Email</h1><a href="https://example.com">Click me</a>',
    tracking=TrackingSettings(
        opens=True,
        clicks=True,
        unsubscribes=True
    ),
)

# Sync
response = client.send_email(email)

AsyncIO support

import asyncio
from laneful import AsyncLanefulClient
  
async def send_emails_async(emails):
    async with AsyncLanefulClient("https://custom-endpoint.send.laneful.net", "your-auth-token") as client:
        tasks = [client.send_email(email) for email in emails]
        return await asyncio.gather(*tasks)

Webhook Handling

The library provides comprehensive webhook handling for email events:

from laneful.webhooks import WebhookHandler, WebhookEvent

webhook_payload = dict()

# Initialize webhook handler
handler = WebhookHandler(webhook_secret="your-webhook-secret")

# Register event handlers
@handler.on("email.delivered")
def handle_delivered(event: WebhookEvent):
    print(f"Email {event.message_id} delivered to {event.email}")

@handler.on("email.opened")  
def handle_opened(event: WebhookEvent):
    print(f"Email {event.message_id} opened by {event.email}")

@handler.on("email.clicked")
def handle_clicked(event: WebhookEvent):
    url = event.data.get("url")
    print(f"Link clicked: {url}")

# Process webhook payload
handler.process_webhook(webhook_payload)

Error Handling

The library provides specific exception types:

from laneful.exceptions import LanefulError, LanefulAPIError, LanefulAuthError

try:
    response = client.send_email(email)
except LanefulAuthError:
    print("Authentication failed - check your token")
except LanefulAPIError as e:
    print(f"API error: {e.message} (status: {e.status_code})")
except LanefulError as e:
    print(f"Client error: {e.message}")

Development

Running Tests

# Run tests
pytest

# Run tests with coverage
pytest --cov=laneful

# Run type checking
mypy laneful/

# Run linting
ruff check laneful/
black --check laneful/

Code Formatting

# Format code
black laneful/ tests/
isort laneful/ tests/

# Check formatting
ruff check laneful/

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Support

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

laneful-1.0.6.tar.gz (148.9 kB view details)

Uploaded Source

Built Distribution

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

laneful-1.0.6-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

Details for the file laneful-1.0.6.tar.gz.

File metadata

  • Download URL: laneful-1.0.6.tar.gz
  • Upload date:
  • Size: 148.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for laneful-1.0.6.tar.gz
Algorithm Hash digest
SHA256 0b6453ecc5efc531dea705df0fce1e1ae464c6cd7013294fdb79065f0684c5a5
MD5 09a8b40f8e1d1f651adf6b8f9cdb9509
BLAKE2b-256 cf43894dd8669f2e3fb2d177db897499218003cd6b9c7001fd8640179cc06b37

See more details on using hashes here.

Provenance

The following attestation bundles were made for laneful-1.0.6.tar.gz:

Publisher: release.yml on lanefulhq/laneful-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file laneful-1.0.6-py3-none-any.whl.

File metadata

  • Download URL: laneful-1.0.6-py3-none-any.whl
  • Upload date:
  • Size: 13.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for laneful-1.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 3fcc077650c2d6224dc52e19aa98cb47254d269bbda6f0c037e130b9a3344d02
MD5 2fdac02ac8218b1245db4d8341167a72
BLAKE2b-256 d77ac1abd2ff50b9167920ba18c325f1dbe639721ccb752fb74fa4acb1914eb8

See more details on using hashes here.

Provenance

The following attestation bundles were made for laneful-1.0.6-py3-none-any.whl:

Publisher: release.yml on lanefulhq/laneful-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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