Skip to main content

Memberful Python SDK

Python 3.10+ License: MIT Pydantic v2

A modern, type-safe Python SDK for integrating with Memberful's API and webhooks. Built with Pydantic models for comprehensive type hints and runtime validation.

✨ Key Features

  • 🔒 Type Safety: Full Pydantic model coverage for all API responses and webhook events
  • 🚀 Async First: Built on httpx2 for high-performance async operations
  • ⚡ GraphQL Powered: Efficient data fetching with Memberful's GraphQL API
  • 🔄 Resilient: Smart retry logic with exponential backoff handles network hiccups and rate limits automatically
  • 📝 Auto-Complete Heaven: Comprehensive type hints mean your IDE knows exactly what's available
  • 🎯 Zero Guesswork: No more digging through API docs to figure out response formats
  • 🪝 Webhook Support: Parse and validate webhook events with confidence
  • 📚 Rich Documentation: Detailed examples and comprehensive API documentation
  • 🧪 Tested: Test suite covering webhook parsing and the API data models
  • 🐍 Modern Python: Supports Python 3.10+ with all the latest features

📦 Installation

uv pip install memberful

Or with uv project management:

uv add memberful

🚀 Quick Start

API Client

import memberful.api

# Initialize the client with your API key and your Memberful account's URL
async with memberful.api.MemberfulClient(
    api_key="YOUR_API_KEY",
    base_url="https://youraccount.memberful.com",
) as client:
    # Get all members with full type safety
    members = await client.get_all_members()
    
    for member in members:
        print(f"{member.full_name} - {member.email}")
        
        # Your IDE provides auto-complete for all attributes!
        if member.subscriptions:
            active_subs = [s for s in member.subscriptions if s.active]
            print(f"  Active subscriptions: {len(active_subs)}")

    # Large account? Stream page by page instead of loading everyone at once.
    # Memberful's API is cursor-based: iter_members() follows the cursors for you.
    async for page in client.iter_members(per_page=100):
        for member in page.members:
            ...

    # Or page manually: pass the previous page's end_cursor as `after`.
    page = await client.get_members(per_page=100)
    if page.has_next_page:
        page = await client.get_members(per_page=100, after=page.end_cursor)

Webhook Handling

import memberful.webhooks
import json

def handle_webhook(request_body: str, signature_header: str, webhook_secret: str):
    # Verify the webhook signature
    if not memberful.webhooks.validate_signature(
        payload=request_body,
        signature=signature_header,
        secret_key=webhook_secret
    ):
        raise ValueError("Invalid webhook signature")
    
    # Parse the event with full type safety
    try:
        event = memberful.webhooks.parse_payload(json.loads(request_body))
    except memberful.webhooks.UnsupportedEventError:
        # Event types this package doesn't model (e.g. custom_fields.updated).
        # Acknowledge with a 2xx anyway: Memberful retries failures and eventually
        # deletes endpoints that keep failing.
        return
    
    # Handle different event types with isinstance checks
    match event:
        case memberful.webhooks.MemberSignupEvent():
            print(f"New member: {event.member.email}")
        case memberful.webhooks.SubscriptionCreatedEvent():
            print(f"New subscription for: {event.subscription.member.email}")
        case _:
            print(f"Received {event.event} event")

📖 Documentation

Comprehensive Guides

Quick Examples

Check out the examples directory for ready-to-run code:

🛠️ Core Features

API Client Capabilities

  • ✅ Fetch members (individual, paginated, or all)
  • ✅ Retrieve subscriptions with full plan details
  • ✅ Automatic pagination handling
  • ✅ Smart retry logic with exponential backoff (3 attempts, handles network errors)
  • ✅ Configurable request timeout
  • ✅ Type-safe responses with Pydantic models
  • ✅ Comprehensive error handling

Webhook Features

  • ✅ Type-safe parsing of all webhook event types
  • ✅ HMAC signature verification with validate_signature()
  • ✅ Support for 20 Memberful webhook events:
    • Member events: signup, updated, deleted
    • Subscription events: created, updated, activated, deactivated, deleted, renewed, reactivated
    • Order events: purchased, refunded, completed, suspended
    • Plan events: created, updated, deleted
    • Download events: created, updated, deleted
  • ✅ Pydantic models for each event type
  • ✅ UnsupportedEventError for events not modeled here (custom_fields.updated, tax_id.updated), so you can acknowledge and ignore them

🏗️ Architecture

This SDK is built with modern Python best practices:

  • GraphQL API - leverages Memberful's GraphQL endpoint for efficient data fetching
  • Async/await for efficient I/O operations
  • Pydantic v2 for fast data validation and serialization
  • Type hints throughout for better IDE support
  • Minimal dependencies - just httpx2, pydantic, and stamina for resilient retries

🧪 Testing

The SDK includes a comprehensive test suite. Run tests with:

# Install dev dependencies
uv pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=memberful

🤝 Contributing

We love contributions! If you've found a bug or have a feature request:

  1. Check existing issues first to avoid duplicates
  2. Open an issue to discuss the change
  3. Submit a PR with your improvements

Development Setup

# Clone the repo
git clone https://github.com/mikeckennedy/memberful.git
cd memberful

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

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

# Run tests
pytest

# Format code
ruff format

# Run linter
ruff check

# Type check
uvx ty check

📊 Project Status

This SDK is under active development and currently supports:

  • ✅ Member operations (read)
  • ✅ Subscription operations (read)
  • ✅ All documented webhook event types except custom_fields.updated and tax_id.updated
  • ✅ Signature verification
  • ⏳ Member operations (create/update) - coming soon
  • ✅ GraphQL API integration with automatic retries

📄 License

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

🙏 Acknowledgments

  • Built with ❤️ for the Memberful community
  • Inspired by modern Python SDK design patterns
  • Special thanks to all contributors

📬 Support


Ready to integrate Memberful into your Python application? Get started now!

Metadata

Release files for memberful 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for memberful 0.4.0
File Size Uploaded
memberful-0.4.0.tar.gz 17.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for memberful 0.4.0
File Interpreter ABI Platform
memberful-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 37.9 kB

Release files / memberful-0.4.0.tar.gz

Download URL memberful-0.4.0.tar.gz
Size 17.8 kB
Tags Source
SHA-256 checksum
How to use checksums
64c493ab6f349e5e1e02b8a15ba38f7db102a21ddf3d560e696f0a4da9b00a81
BLAKE2b-256 checksum
How to use checksums
14f81c0158df75a8aa04cb03c47973ad449d7199bd0af466082a3cdc47f14111
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / memberful-0.4.0-py3-none-any.whl

Download URL memberful-0.4.0-py3-none-any.whl
Size 20.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
509db65b67ce451f8006e09643f9099c2ff833665b95a55d429a72238f98748d
BLAKE2b-256 checksum
How to use checksums
e6f506bd1abc6d8a18ea76074cf40384907fbf15030508fe481ed24728924637
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.5.0

2 release files

This release

0.4.0 This release

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page