memberful 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- memberful-0.1.0/.gitignore +170 -0
- memberful-0.1.0/LICENSE +21 -0
- memberful-0.1.0/PKG-INFO +273 -0
- memberful-0.1.0/README.md +216 -0
- memberful-0.1.0/pyproject.toml +105 -0
- memberful-0.1.0/src/memberful/__init__.py +17 -0
- memberful-0.1.0/src/memberful/api/__init__.py +663 -0
- memberful-0.1.0/src/memberful/api/models.py +227 -0
- memberful-0.1.0/src/memberful/webhooks/__init__.py +182 -0
- memberful-0.1.0/src/memberful/webhooks/models.py +338 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# poetry
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
102
|
+
#poetry.lock
|
|
103
|
+
|
|
104
|
+
# pdm
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
106
|
+
#pdm.lock
|
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
108
|
+
# in version control.
|
|
109
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
110
|
+
.pdm.toml
|
|
111
|
+
|
|
112
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
113
|
+
__pypackages__/
|
|
114
|
+
|
|
115
|
+
# Celery stuff
|
|
116
|
+
celerybeat-schedule
|
|
117
|
+
celerybeat.pid
|
|
118
|
+
|
|
119
|
+
# SageMath parsed files
|
|
120
|
+
*.sage.py
|
|
121
|
+
|
|
122
|
+
# Environments
|
|
123
|
+
.env
|
|
124
|
+
.venv
|
|
125
|
+
env/
|
|
126
|
+
venv/
|
|
127
|
+
ENV/
|
|
128
|
+
env.bak/
|
|
129
|
+
venv.bak/
|
|
130
|
+
|
|
131
|
+
# Spyder project settings
|
|
132
|
+
.spyderproject
|
|
133
|
+
.spyproject
|
|
134
|
+
|
|
135
|
+
# Rope project settings
|
|
136
|
+
.ropeproject
|
|
137
|
+
|
|
138
|
+
# mkdocs documentation
|
|
139
|
+
/site
|
|
140
|
+
|
|
141
|
+
# mypy
|
|
142
|
+
.mypy_cache/
|
|
143
|
+
.dmypy.json
|
|
144
|
+
dmypy.json
|
|
145
|
+
|
|
146
|
+
# Pyre type checker
|
|
147
|
+
.pyre/
|
|
148
|
+
|
|
149
|
+
# pytype static type analyzer
|
|
150
|
+
.pytype/
|
|
151
|
+
|
|
152
|
+
# Cython debug symbols
|
|
153
|
+
cython_debug/
|
|
154
|
+
|
|
155
|
+
# PyCharm
|
|
156
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
157
|
+
# be added to the global gitignore or merged into this project gitignore. For a PyCharm
|
|
158
|
+
# project, it is not recommended to check the .idea/ directory into version control.
|
|
159
|
+
.idea/
|
|
160
|
+
.vscode/
|
|
161
|
+
|
|
162
|
+
# OS generated files
|
|
163
|
+
.DS_Store
|
|
164
|
+
.DS_Store?
|
|
165
|
+
._*
|
|
166
|
+
.Spotlight-V100
|
|
167
|
+
.Trashes
|
|
168
|
+
ehthumbs.db
|
|
169
|
+
Thumbs.db
|
|
170
|
+
settings.json
|
memberful-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Michael Kennedy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
memberful-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memberful
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Memberful service Python client for webhooks and API
|
|
5
|
+
Project-URL: Homepage, https://github.com/mikeckennedy/memberful
|
|
6
|
+
Project-URL: Repository, https://github.com/mikeckennedy/memberful.git
|
|
7
|
+
Project-URL: Issues, https://github.com/mikeckennedy/memberful/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/mikeckennedy/memberful/blob/main/CHANGELOG.md
|
|
9
|
+
Author: Michael Kennedy
|
|
10
|
+
Maintainer: Michael Kennedy
|
|
11
|
+
License: MIT License
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2025 Michael Kennedy
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Keywords: api,memberful,membership,subscription,webhooks
|
|
34
|
+
Classifier: Development Status :: 3 - Alpha
|
|
35
|
+
Classifier: Intended Audience :: Developers
|
|
36
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
37
|
+
Classifier: Operating System :: OS Independent
|
|
38
|
+
Classifier: Programming Language :: Python :: 3
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
43
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
44
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
45
|
+
Requires-Python: >=3.10
|
|
46
|
+
Requires-Dist: httpx>=0.25.0
|
|
47
|
+
Requires-Dist: pydantic>=2.0.0
|
|
48
|
+
Requires-Dist: stamina>=24.0.0
|
|
49
|
+
Provides-Extra: dev
|
|
50
|
+
Requires-Dist: mypy>=1.7.0; extra == 'dev'
|
|
51
|
+
Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
|
|
52
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
53
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
54
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
55
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
56
|
+
Description-Content-Type: text/markdown
|
|
57
|
+
|
|
58
|
+
# Memberful Python SDK
|
|
59
|
+
|
|
60
|
+
[](https://www.python.org/downloads/)
|
|
61
|
+
[](https://opensource.org/licenses/MIT)
|
|
62
|
+
[](https://docs.pydantic.dev/)
|
|
63
|
+
|
|
64
|
+
A modern, type-safe Python SDK for integrating with [Memberful](https://memberful.com)'s API and webhooks. Built with Pydantic models for comprehensive type hints and runtime validation.
|
|
65
|
+
|
|
66
|
+
## โจ Key Features
|
|
67
|
+
|
|
68
|
+
- **๐ Type Safety**: Full Pydantic model coverage for all API responses and webhook events
|
|
69
|
+
- **๐ Async First**: Built on `httpx` for high-performance async operations
|
|
70
|
+
- **โก GraphQL Powered**: Efficient data fetching with Memberful's GraphQL API
|
|
71
|
+
- **๐ Resilient**: Smart retry logic with exponential backoff handles network hiccups and rate limits automatically
|
|
72
|
+
- **๐ Auto-Complete Heaven**: Comprehensive type hints mean your IDE knows exactly what's available
|
|
73
|
+
- **๐ฏ Zero Guesswork**: No more digging through API docs to figure out response formats
|
|
74
|
+
- **๐ช Webhook Support**: Parse and validate webhook events with confidence
|
|
75
|
+
- **๐ Rich Documentation**: Detailed examples and comprehensive API documentation
|
|
76
|
+
- **๐งช Battle-Tested**: Extensive test suite ensures reliability
|
|
77
|
+
- **๐ Modern Python**: Supports Python 3.10+ with all the latest features
|
|
78
|
+
|
|
79
|
+
## ๐ฆ Installation
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv pip install memberful
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Or with uv project management:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
uv add memberful
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## ๐ Quick Start
|
|
92
|
+
|
|
93
|
+
### API Client
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from memberful.api import MemberfulClient
|
|
97
|
+
|
|
98
|
+
# Initialize the client
|
|
99
|
+
async with MemberfulClient(api_key="YOUR_API_KEY") as client:
|
|
100
|
+
# Get all members with full type safety
|
|
101
|
+
members = await client.get_all_members()
|
|
102
|
+
|
|
103
|
+
for member in members:
|
|
104
|
+
print(f"{member.full_name} - {member.email}")
|
|
105
|
+
|
|
106
|
+
# Your IDE provides auto-complete for all attributes!
|
|
107
|
+
if member.subscriptions:
|
|
108
|
+
active_subs = [s for s in member.subscriptions if s.active]
|
|
109
|
+
print(f" Active subscriptions: {len(active_subs)}")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Webhook Handling
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from memberful.webhooks import (
|
|
116
|
+
parse_payload,
|
|
117
|
+
validate_signature,
|
|
118
|
+
MemberSignupEvent,
|
|
119
|
+
SubscriptionCreatedEvent
|
|
120
|
+
)
|
|
121
|
+
import json
|
|
122
|
+
|
|
123
|
+
def handle_webhook(request_body: str, signature_header: str, webhook_secret: str):
|
|
124
|
+
# Verify the webhook signature
|
|
125
|
+
if not validate_signature(
|
|
126
|
+
payload=request_body,
|
|
127
|
+
signature=signature_header,
|
|
128
|
+
secret_key=webhook_secret
|
|
129
|
+
):
|
|
130
|
+
raise ValueError("Invalid webhook signature")
|
|
131
|
+
|
|
132
|
+
# Parse the event with full type safety
|
|
133
|
+
event = parse_payload(json.loads(request_body))
|
|
134
|
+
|
|
135
|
+
# Handle different event types with isinstance checks
|
|
136
|
+
match event:
|
|
137
|
+
case MemberSignupEvent():
|
|
138
|
+
print(f"New member: {event.member.email}")
|
|
139
|
+
case SubscriptionCreatedEvent():
|
|
140
|
+
print(f"New subscription for: {event.member.email}")
|
|
141
|
+
case _:
|
|
142
|
+
print(f"Received {event.event} event")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## ๐ Documentation
|
|
146
|
+
|
|
147
|
+
### Comprehensive Guides
|
|
148
|
+
|
|
149
|
+
- **[API Documentation](reference/api.md)** - Complete guide to using the API client with examples
|
|
150
|
+
- **[Webhook Documentation](reference/webhooks.md)** - Detailed webhook event reference and handling guide
|
|
151
|
+
|
|
152
|
+
### Quick Examples
|
|
153
|
+
|
|
154
|
+
Check out the [examples directory](examples/) for ready-to-run code:
|
|
155
|
+
- [Basic API Usage](examples/basic_api_usage.py) - Simple examples to get started
|
|
156
|
+
- [Webhook Usage](examples/basic_webhook_usage.py) - Webhook handling patterns
|
|
157
|
+
- [Webhook Parsing](examples/webhook_parsing.py) - Detailed webhook parsing examples
|
|
158
|
+
- [FastAPI Integration](examples/fastapi_webhook_example/) - Complete FastAPI webhook server
|
|
159
|
+
|
|
160
|
+
## ๐ ๏ธ Core Features
|
|
161
|
+
|
|
162
|
+
### API Client Capabilities
|
|
163
|
+
|
|
164
|
+
- โ
Fetch members (individual, paginated, or all)
|
|
165
|
+
- โ
Retrieve subscriptions with full plan details
|
|
166
|
+
- โ
Automatic pagination handling
|
|
167
|
+
- โ
**Smart retry logic** with exponential backoff (3 attempts, handles network errors)
|
|
168
|
+
- โ
Configurable timeouts and retries
|
|
169
|
+
- โ
Type-safe responses with Pydantic models
|
|
170
|
+
- โ
Comprehensive error handling
|
|
171
|
+
|
|
172
|
+
### Webhook Features
|
|
173
|
+
|
|
174
|
+
- โ
Type-safe parsing of all webhook event types
|
|
175
|
+
- โ
Automatic signature verification
|
|
176
|
+
- โ
Support for all 16 Memberful webhook events:
|
|
177
|
+
- **Member events**: signup, updated, deleted
|
|
178
|
+
- **Subscription events**: created, updated, activated, deleted, renewed
|
|
179
|
+
- **Order events**: completed, suspended
|
|
180
|
+
- **Plan events**: created, updated, deleted
|
|
181
|
+
- **Download events**: created, updated, deleted
|
|
182
|
+
- โ
Pydantic models for each event type
|
|
183
|
+
- โ
Helper functions for event handling
|
|
184
|
+
|
|
185
|
+
## ๐๏ธ Architecture
|
|
186
|
+
|
|
187
|
+
This SDK is built with modern Python best practices:
|
|
188
|
+
|
|
189
|
+
- **GraphQL API** - leverages Memberful's GraphQL endpoint for efficient data fetching
|
|
190
|
+
- **Async/await** for efficient I/O operations
|
|
191
|
+
- **Pydantic v2** for fast data validation and serialization
|
|
192
|
+
- **Type hints** throughout for better IDE support
|
|
193
|
+
- **Minimal dependencies** - just `httpx`, `pydantic`, and `stamina` for resilient retries
|
|
194
|
+
- **100% test coverage** for reliability
|
|
195
|
+
|
|
196
|
+
## ๐งช Testing
|
|
197
|
+
|
|
198
|
+
The SDK includes a comprehensive test suite. Run tests with:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# Install dev dependencies
|
|
202
|
+
uv pip install -e ".[dev]"
|
|
203
|
+
|
|
204
|
+
# Run tests
|
|
205
|
+
pytest
|
|
206
|
+
|
|
207
|
+
# Run with coverage
|
|
208
|
+
pytest --cov=memberful
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## ๐ค Contributing
|
|
212
|
+
|
|
213
|
+
We love contributions! If you've found a bug or have a feature request:
|
|
214
|
+
|
|
215
|
+
1. **Check existing issues** first to avoid duplicates
|
|
216
|
+
2. **Open an issue** to discuss the change
|
|
217
|
+
3. **Submit a PR** with your improvements
|
|
218
|
+
|
|
219
|
+
### Development Setup
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
# Clone the repo
|
|
223
|
+
git clone https://github.com/mikeckennedy/memberful.git
|
|
224
|
+
cd memberful
|
|
225
|
+
|
|
226
|
+
# Create virtual environment
|
|
227
|
+
python -m venv venv
|
|
228
|
+
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
229
|
+
|
|
230
|
+
# Install in development mode
|
|
231
|
+
uv pip install -e ".[dev]"
|
|
232
|
+
|
|
233
|
+
# Run tests
|
|
234
|
+
pytest
|
|
235
|
+
|
|
236
|
+
# Format code
|
|
237
|
+
ruff format
|
|
238
|
+
|
|
239
|
+
# Run linter
|
|
240
|
+
ruff check
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## ๐ Project Status
|
|
244
|
+
|
|
245
|
+
This SDK is under active development and currently supports:
|
|
246
|
+
|
|
247
|
+
- โ
Member operations (read)
|
|
248
|
+
- โ
Subscription operations (read)
|
|
249
|
+
- โ
All webhook event types
|
|
250
|
+
- โ
Signature verification
|
|
251
|
+
- โณ Member operations (create/update) - coming soon
|
|
252
|
+
- โ
GraphQL API integration with automatic retries
|
|
253
|
+
|
|
254
|
+
## ๐ License
|
|
255
|
+
|
|
256
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
257
|
+
|
|
258
|
+
## ๐ Acknowledgments
|
|
259
|
+
|
|
260
|
+
- Built with โค๏ธ for the [Memberful](https://memberful.com) community
|
|
261
|
+
- Inspired by modern Python SDK design patterns
|
|
262
|
+
- Special thanks to all contributors
|
|
263
|
+
|
|
264
|
+
## ๐ฌ Support
|
|
265
|
+
|
|
266
|
+
- ๐ [Read the documentation](reference/)
|
|
267
|
+
- ๐ [Report bugs](https://github.com/mikeckennedy/memberful/issues)
|
|
268
|
+
- ๐ก [Request features](https://github.com/mikeckennedy/memberful/issues)
|
|
269
|
+
- ๐ฌ [Discussions](https://github.com/mikeckennedy/memberful/discussions)
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
**Ready to integrate Memberful into your Python application? [Get started now!](#-quick-start)**
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Memberful Python SDK
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://docs.pydantic.dev/)
|
|
6
|
+
|
|
7
|
+
A modern, type-safe Python SDK for integrating with [Memberful](https://memberful.com)'s API and webhooks. Built with Pydantic models for comprehensive type hints and runtime validation.
|
|
8
|
+
|
|
9
|
+
## โจ Key Features
|
|
10
|
+
|
|
11
|
+
- **๐ Type Safety**: Full Pydantic model coverage for all API responses and webhook events
|
|
12
|
+
- **๐ Async First**: Built on `httpx` for high-performance async operations
|
|
13
|
+
- **โก GraphQL Powered**: Efficient data fetching with Memberful's GraphQL API
|
|
14
|
+
- **๐ Resilient**: Smart retry logic with exponential backoff handles network hiccups and rate limits automatically
|
|
15
|
+
- **๐ Auto-Complete Heaven**: Comprehensive type hints mean your IDE knows exactly what's available
|
|
16
|
+
- **๐ฏ Zero Guesswork**: No more digging through API docs to figure out response formats
|
|
17
|
+
- **๐ช Webhook Support**: Parse and validate webhook events with confidence
|
|
18
|
+
- **๐ Rich Documentation**: Detailed examples and comprehensive API documentation
|
|
19
|
+
- **๐งช Battle-Tested**: Extensive test suite ensures reliability
|
|
20
|
+
- **๐ Modern Python**: Supports Python 3.10+ with all the latest features
|
|
21
|
+
|
|
22
|
+
## ๐ฆ Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
uv pip install memberful
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or with uv project management:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv add memberful
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## ๐ Quick Start
|
|
35
|
+
|
|
36
|
+
### API Client
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from memberful.api import MemberfulClient
|
|
40
|
+
|
|
41
|
+
# Initialize the client
|
|
42
|
+
async with MemberfulClient(api_key="YOUR_API_KEY") as client:
|
|
43
|
+
# Get all members with full type safety
|
|
44
|
+
members = await client.get_all_members()
|
|
45
|
+
|
|
46
|
+
for member in members:
|
|
47
|
+
print(f"{member.full_name} - {member.email}")
|
|
48
|
+
|
|
49
|
+
# Your IDE provides auto-complete for all attributes!
|
|
50
|
+
if member.subscriptions:
|
|
51
|
+
active_subs = [s for s in member.subscriptions if s.active]
|
|
52
|
+
print(f" Active subscriptions: {len(active_subs)}")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Webhook Handling
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from memberful.webhooks import (
|
|
59
|
+
parse_payload,
|
|
60
|
+
validate_signature,
|
|
61
|
+
MemberSignupEvent,
|
|
62
|
+
SubscriptionCreatedEvent
|
|
63
|
+
)
|
|
64
|
+
import json
|
|
65
|
+
|
|
66
|
+
def handle_webhook(request_body: str, signature_header: str, webhook_secret: str):
|
|
67
|
+
# Verify the webhook signature
|
|
68
|
+
if not validate_signature(
|
|
69
|
+
payload=request_body,
|
|
70
|
+
signature=signature_header,
|
|
71
|
+
secret_key=webhook_secret
|
|
72
|
+
):
|
|
73
|
+
raise ValueError("Invalid webhook signature")
|
|
74
|
+
|
|
75
|
+
# Parse the event with full type safety
|
|
76
|
+
event = parse_payload(json.loads(request_body))
|
|
77
|
+
|
|
78
|
+
# Handle different event types with isinstance checks
|
|
79
|
+
match event:
|
|
80
|
+
case MemberSignupEvent():
|
|
81
|
+
print(f"New member: {event.member.email}")
|
|
82
|
+
case SubscriptionCreatedEvent():
|
|
83
|
+
print(f"New subscription for: {event.member.email}")
|
|
84
|
+
case _:
|
|
85
|
+
print(f"Received {event.event} event")
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## ๐ Documentation
|
|
89
|
+
|
|
90
|
+
### Comprehensive Guides
|
|
91
|
+
|
|
92
|
+
- **[API Documentation](reference/api.md)** - Complete guide to using the API client with examples
|
|
93
|
+
- **[Webhook Documentation](reference/webhooks.md)** - Detailed webhook event reference and handling guide
|
|
94
|
+
|
|
95
|
+
### Quick Examples
|
|
96
|
+
|
|
97
|
+
Check out the [examples directory](examples/) for ready-to-run code:
|
|
98
|
+
- [Basic API Usage](examples/basic_api_usage.py) - Simple examples to get started
|
|
99
|
+
- [Webhook Usage](examples/basic_webhook_usage.py) - Webhook handling patterns
|
|
100
|
+
- [Webhook Parsing](examples/webhook_parsing.py) - Detailed webhook parsing examples
|
|
101
|
+
- [FastAPI Integration](examples/fastapi_webhook_example/) - Complete FastAPI webhook server
|
|
102
|
+
|
|
103
|
+
## ๐ ๏ธ Core Features
|
|
104
|
+
|
|
105
|
+
### API Client Capabilities
|
|
106
|
+
|
|
107
|
+
- โ
Fetch members (individual, paginated, or all)
|
|
108
|
+
- โ
Retrieve subscriptions with full plan details
|
|
109
|
+
- โ
Automatic pagination handling
|
|
110
|
+
- โ
**Smart retry logic** with exponential backoff (3 attempts, handles network errors)
|
|
111
|
+
- โ
Configurable timeouts and retries
|
|
112
|
+
- โ
Type-safe responses with Pydantic models
|
|
113
|
+
- โ
Comprehensive error handling
|
|
114
|
+
|
|
115
|
+
### Webhook Features
|
|
116
|
+
|
|
117
|
+
- โ
Type-safe parsing of all webhook event types
|
|
118
|
+
- โ
Automatic signature verification
|
|
119
|
+
- โ
Support for all 16 Memberful webhook events:
|
|
120
|
+
- **Member events**: signup, updated, deleted
|
|
121
|
+
- **Subscription events**: created, updated, activated, deleted, renewed
|
|
122
|
+
- **Order events**: completed, suspended
|
|
123
|
+
- **Plan events**: created, updated, deleted
|
|
124
|
+
- **Download events**: created, updated, deleted
|
|
125
|
+
- โ
Pydantic models for each event type
|
|
126
|
+
- โ
Helper functions for event handling
|
|
127
|
+
|
|
128
|
+
## ๐๏ธ Architecture
|
|
129
|
+
|
|
130
|
+
This SDK is built with modern Python best practices:
|
|
131
|
+
|
|
132
|
+
- **GraphQL API** - leverages Memberful's GraphQL endpoint for efficient data fetching
|
|
133
|
+
- **Async/await** for efficient I/O operations
|
|
134
|
+
- **Pydantic v2** for fast data validation and serialization
|
|
135
|
+
- **Type hints** throughout for better IDE support
|
|
136
|
+
- **Minimal dependencies** - just `httpx`, `pydantic`, and `stamina` for resilient retries
|
|
137
|
+
- **100% test coverage** for reliability
|
|
138
|
+
|
|
139
|
+
## ๐งช Testing
|
|
140
|
+
|
|
141
|
+
The SDK includes a comprehensive test suite. Run tests with:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Install dev dependencies
|
|
145
|
+
uv pip install -e ".[dev]"
|
|
146
|
+
|
|
147
|
+
# Run tests
|
|
148
|
+
pytest
|
|
149
|
+
|
|
150
|
+
# Run with coverage
|
|
151
|
+
pytest --cov=memberful
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## ๐ค Contributing
|
|
155
|
+
|
|
156
|
+
We love contributions! If you've found a bug or have a feature request:
|
|
157
|
+
|
|
158
|
+
1. **Check existing issues** first to avoid duplicates
|
|
159
|
+
2. **Open an issue** to discuss the change
|
|
160
|
+
3. **Submit a PR** with your improvements
|
|
161
|
+
|
|
162
|
+
### Development Setup
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# Clone the repo
|
|
166
|
+
git clone https://github.com/mikeckennedy/memberful.git
|
|
167
|
+
cd memberful
|
|
168
|
+
|
|
169
|
+
# Create virtual environment
|
|
170
|
+
python -m venv venv
|
|
171
|
+
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
172
|
+
|
|
173
|
+
# Install in development mode
|
|
174
|
+
uv pip install -e ".[dev]"
|
|
175
|
+
|
|
176
|
+
# Run tests
|
|
177
|
+
pytest
|
|
178
|
+
|
|
179
|
+
# Format code
|
|
180
|
+
ruff format
|
|
181
|
+
|
|
182
|
+
# Run linter
|
|
183
|
+
ruff check
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## ๐ Project Status
|
|
187
|
+
|
|
188
|
+
This SDK is under active development and currently supports:
|
|
189
|
+
|
|
190
|
+
- โ
Member operations (read)
|
|
191
|
+
- โ
Subscription operations (read)
|
|
192
|
+
- โ
All webhook event types
|
|
193
|
+
- โ
Signature verification
|
|
194
|
+
- โณ Member operations (create/update) - coming soon
|
|
195
|
+
- โ
GraphQL API integration with automatic retries
|
|
196
|
+
|
|
197
|
+
## ๐ License
|
|
198
|
+
|
|
199
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
200
|
+
|
|
201
|
+
## ๐ Acknowledgments
|
|
202
|
+
|
|
203
|
+
- Built with โค๏ธ for the [Memberful](https://memberful.com) community
|
|
204
|
+
- Inspired by modern Python SDK design patterns
|
|
205
|
+
- Special thanks to all contributors
|
|
206
|
+
|
|
207
|
+
## ๐ฌ Support
|
|
208
|
+
|
|
209
|
+
- ๐ [Read the documentation](reference/)
|
|
210
|
+
- ๐ [Report bugs](https://github.com/mikeckennedy/memberful/issues)
|
|
211
|
+
- ๐ก [Request features](https://github.com/mikeckennedy/memberful/issues)
|
|
212
|
+
- ๐ฌ [Discussions](https://github.com/mikeckennedy/memberful/discussions)
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
**Ready to integrate Memberful into your Python application? [Get started now!](#-quick-start)**
|