Memberful Python SDK
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
httpx2for 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)
Stopping auto-renew
set_subscription_autorenew() turns renewal off (or back on) without a refund: the subscription stays active until the end of the paid period. It returns the Subscription from Memberful's response, so check autorenew on the result rather than assuming it worked.
subscription = await client.set_subscription_autorenew(subscription_id, False)
assert subscription.autorenew is False
This is a write, so the API key needs write access. A custom application key limited to read access fails with memberful.api.MemberfulGraphQLError. Memberful returns HTTP 200 with a GraphQL errors array, and its message is on e.messages. MemberfulGraphQLError subclasses MemberfulError, which subclasses ValueError. HTTP failures and timeouts raise httpx errors after 3 attempts. The call never fails silently.
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
- API Documentation - Complete guide to using the API client with examples
- Webhook Documentation - Detailed webhook event reference and handling guide
Quick Examples
Check out the examples directory for ready-to-run code:
- Basic API Usage - Simple examples to get started
- Webhook Usage - Webhook handling patterns
- Webhook Parsing - Detailed webhook parsing examples
- FastAPI Integration - Complete FastAPI webhook server
🛠️ Core Features
API Client Capabilities
- ✅ Fetch members (individual, paginated, or all)
- ✅ Retrieve subscriptions with full plan details
- ✅ Stop or resume a subscription's auto-renew (
set_subscription_autorenew) - ✅ Automatic pagination handling
- ✅ Smart retry logic with exponential backoff (3 attempts, handles network errors)
- ✅ Configurable request timeout
- ✅ Type-safe responses with Pydantic models
- ✅ Typed errors:
MemberfulGraphQLError/MemberfulError(bothValueErrorsubclasses)
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
- ✅
UnsupportedEventErrorfor 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, andstaminafor 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:
- Check existing issues first to avoid duplicates
- Open an issue to discuss the change
- 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.updatedandtax_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.5.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| memberful-0.5.1.tar.gz | 19.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| memberful-0.5.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.1 kB
Release files / memberful-0.5.1.tar.gz
| Download URL | memberful-0.5.1.tar.gz |
|---|---|
| Size | 19.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3cc2cb8396bb457254701f1ab20fdbcc9464b13c4f44f6d29b763cbcd54a5f33
|
|
BLAKE2b-256 checksum How to use checksums |
1fb5936244ca0d6333fdd852b219d192a1c65bd0964a94f192a9de96c665f084
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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.5.1-py3-none-any.whl
| Download URL | memberful-0.5.1-py3-none-any.whl |
|---|---|
| Size | 21.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3ff9ccfd27207a745e75e9c8624fc2eb738932970815112b3dcad8a8ab3e2ce5
|
|
BLAKE2b-256 checksum How to use checksums |
75fd3218fdc6545e85adf0e236e26c7240ec795d3b1c358fd852625fa12cb5f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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}
|
Security for memberful 0.5.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.