fastapi-mpp 0.2.0__py3-none-any.whl

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.
@@ -0,0 +1,230 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi-mpp
3
+ Version: 0.2.0
4
+ Summary: Add Machine Payments Protocol (MPP) support to FastAPI endpoints in a few lines.
5
+ Project-URL: Homepage, https://github.com/your-org/fastapi-mpp
6
+ Project-URL: Repository, https://github.com/your-org/fastapi-mpp
7
+ Project-URL: Issues, https://github.com/your-org/fastapi-mpp/issues
8
+ Author: fastapi-mpp contributors
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: ai-agents,fastapi,machine-payments-protocol,mpp,payments
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Framework :: FastAPI
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Internet :: WWW/HTTP
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: fastapi>=0.115.0
24
+ Requires-Dist: httpx>=0.28.0
25
+ Requires-Dist: pydantic>=2.7.0
26
+ Provides-Extra: all
27
+ Requires-Dist: pympp>=0.4.1; extra == 'all'
28
+ Requires-Dist: python-dotenv>=1.0.0; extra == 'all'
29
+ Requires-Dist: stripe>=11.0.0; extra == 'all'
30
+ Provides-Extra: dev
31
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
32
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
33
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
34
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
35
+ Requires-Dist: uvicorn[standard]>=0.35.0; extra == 'dev'
36
+ Provides-Extra: dotenv
37
+ Requires-Dist: python-dotenv>=1.0.0; extra == 'dotenv'
38
+ Provides-Extra: stripe
39
+ Requires-Dist: stripe>=11.0.0; extra == 'stripe'
40
+ Provides-Extra: tempo
41
+ Requires-Dist: pympp>=0.4.1; extra == 'tempo'
42
+ Description-Content-Type: text/markdown
43
+
44
+ # fastapi-mpp
45
+
46
+ [![PyPI version](https://img.shields.io/pypi/v/fastapi-mpp.svg)](https://pypi.org/project/fastapi-mpp/)
47
+ [![Python versions](https://img.shields.io/pypi/pyversions/fastapi-mpp.svg)](https://pypi.org/project/fastapi-mpp/)
48
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
49
+ [![GitHub stars](https://img.shields.io/github/stars/your-org/fastapi-mpp?style=social)](https://github.com/your-org/fastapi-mpp)
50
+
51
+ Machine Payments Protocol middleware for FastAPI.
52
+
53
+ Version `v0.2` hardens receipt validation, replay protection, session binding, and
54
+ HTTP authentication semantics. This project is still beta.
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ pip install fastapi-mpp
60
+ ```
61
+
62
+ For production validation, install Tempo support so default cryptographic validation
63
+ is available:
64
+
65
+ ```bash
66
+ pip install "fastapi-mpp[tempo]"
67
+ ```
68
+
69
+ Optional extras:
70
+
71
+ ```bash
72
+ pip install "fastapi-mpp[dotenv]"
73
+ pip install "fastapi-mpp[stripe]"
74
+ pip install "fastapi-mpp[all]"
75
+ ```
76
+
77
+ ## Usage
78
+
79
+ ### Server setup
80
+
81
+ ```python
82
+ from fastapi import FastAPI, Request
83
+ from mpp_fastapi.core import MPP
84
+
85
+ app = FastAPI()
86
+
87
+ # Production mode (default): requires receipt_validator or fastapi-mpp[tempo].
88
+ mpp = MPP()
89
+
90
+ @app.get("/premium")
91
+ @mpp.charge(amount="0.05", currency="USD", description="Premium data")
92
+ async def premium(request: Request):
93
+ return {"data": "paid content"}
94
+ ```
95
+
96
+ ### HTTP flow (v0.2 hardened)
97
+
98
+ 1. Client calls endpoint without credential.
99
+ 2. Server responds `402 Payment Required` with:
100
+ - `WWW-Authenticate: Payment challenge="<base64url(JSON)>", realm="MyAPI", expires="..."`
101
+ - challenge body containing `challenge_id`, `intent`, `amount`, `currency`, `expires_at`, `hints`
102
+ 3. Wallet pays and retries with:
103
+ - `Authorization: Payment credential="<base64url(receipt-json)>"`
104
+ 4. Server validates receipt (fail-closed in production), applies replay checks, and returns success with:
105
+ - `Payment-Receipt: <base64url(receipt-json)>`
106
+ - optional session headers when session mode is enabled.
107
+
108
+ Legacy compatibility can be kept with `allow_legacy_headers=True`:
109
+ - `X-MPP-Receipt`
110
+ - `X-MPP-Session-Id`
111
+
112
+ ### Session budgets
113
+
114
+ ```python
115
+ from fastapi import FastAPI, Request
116
+ from mpp_fastapi.core import MPP
117
+ from mpp_fastapi.types import MPPChargeOptions
118
+
119
+ app = FastAPI()
120
+ mpp = MPP()
121
+
122
+ session_options = MPPChargeOptions(
123
+ amount="0.01",
124
+ currency="USD",
125
+ description="Session-metered call",
126
+ session=True,
127
+ max_amount="0.50",
128
+ require_idempotency_key=True,
129
+ )
130
+
131
+ @app.post("/agent/infer")
132
+ @mpp.charge(options=session_options)
133
+ async def infer(request: Request):
134
+ return {"result": "paid inference"}
135
+ ```
136
+
137
+ Sessions are HMAC-signed opaque tokens bound to:
138
+ - route scope
139
+ - optional payer source
140
+ - currency/provider
141
+ - issued-at and expiry (default 15 minutes)
142
+ - max budget tracked in store
143
+
144
+ ## Local Run
145
+
146
+ ```bash
147
+ uv venv
148
+ source .venv/bin/activate
149
+ uv pip install -e ".[dev]"
150
+ uvicorn examples.simple_app:app --reload
151
+ ```
152
+
153
+ Then test:
154
+
155
+ ```bash
156
+ curl -i http://127.0.0.1:8000/free
157
+ curl -i http://127.0.0.1:8000/premium
158
+ ```
159
+
160
+ Expected behavior demo:
161
+
162
+ ```text
163
+ GET /free -> 200 OK
164
+ GET /premium (without Authorization) -> 402 Payment Required
165
+ GET /premium (with Authorization: Payment credential="...") -> 200 OK
166
+ ```
167
+
168
+ ## Security
169
+
170
+ Read [SECURITY.md](SECURITY.md) before production usage.
171
+
172
+ - Beta warning: use with caution.
173
+ - In-memory replay/session/rate-limit stores are suitable for single-process deployments only.
174
+ - Production mode is fail-closed when receipt validation is not configured.
175
+ - HTTPS is enforced in production mode.
176
+
177
+ ## Headers
178
+
179
+ Incoming:
180
+ - `Authorization: Payment credential="..."` (preferred)
181
+ - `Payment-Receipt` (supported)
182
+ - `Payment-Session` (session spends)
183
+ - `X-MPP-Receipt` and `X-MPP-Session-Id` in legacy mode
184
+ - `Idempotency-Key` for safer retries
185
+
186
+ Response on 402:
187
+ - `WWW-Authenticate: Payment challenge="...", realm="...", expires="..."`
188
+ - JSON challenge payload
189
+
190
+ Response on success:
191
+ - `Payment-Receipt`
192
+ - `Payment-Session` when session authorization is established
193
+
194
+ ## Design Notes
195
+
196
+ - In-memory stores are intentionally simple for `v0.2`; Redis-backed stores are planned.
197
+ - Header size limit is enforced (`8KB`) for authorization and receipt headers.
198
+ - A basic in-memory challenge rate limiter is enabled (default `10` challenges/IP/minute).
199
+
200
+ ## Roadmap
201
+
202
+ - Redis-backed replay/session/rate-limit stores
203
+ - Full conformance with evolving HTTP Payment auth draft semantics
204
+ - Advanced rate limiting and abuse controls
205
+ - Payment provider adapters and richer telemetry
206
+
207
+ ## Contributing
208
+
209
+ 1. Fork the repository.
210
+ 2. Create a feature branch.
211
+ 3. Add tests for behavior changes.
212
+ 4. Run:
213
+
214
+ ```bash
215
+ uv pip install -e ".[dev]"
216
+ pytest
217
+ ruff check .
218
+ mypy src
219
+ ```
220
+
221
+ 5. Open a PR with clear before/after behavior.
222
+
223
+ ## Credits
224
+
225
+ Inspired by the MPP ecosystem work and early protocol specs from Tempo and Stripe collaborators.
226
+ Please refer to official protocol repos/specs for normative behavior and updates.
227
+
228
+ ## License
229
+
230
+ MIT
@@ -0,0 +1,10 @@
1
+ mpp_fastapi/__init__.py,sha256=tvNGWETOhM46t7SHlhOCPz_CMVNrwe8IV14LRO8SjQE,381
2
+ mpp_fastapi/core.py,sha256=QYN_7ek_wNS5uaRR-9w75UxsZYJqKY69RfvYK62SbCs,28586
3
+ mpp_fastapi/decorators.py,sha256=_Vn4gBS05AV-_rWnp4iva1Z6DI7JpDhbZE_grapR6qI,749
4
+ mpp_fastapi/dependencies.py,sha256=zO5FwAy4ST9wv7UDg_PH2vHGhu86usG8MtQrlr7xstM,4032
5
+ mpp_fastapi/exceptions.py,sha256=o_Jek5suQlszKM4uEePGBnVSGQeta_-_0ImYzIdy8xA,917
6
+ mpp_fastapi/types.py,sha256=pdp58Hpjo4JNnQHwpFR-qH1iOPVrqiS1drVXzDcFJek,5906
7
+ fastapi_mpp-0.2.0.dist-info/METADATA,sha256=kgBnb4WsPOSm9OwJop6KSl0I0uqoZ-KLbr49xQX1yLM,6699
8
+ fastapi_mpp-0.2.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
9
+ fastapi_mpp-0.2.0.dist-info/licenses/LICENSE,sha256=RcO5nByIvCe4t2iDd2SVDCYxjuOgNCiTff9DWYOZ6S8,1081
10
+ fastapi_mpp-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 fastapi-mpp contributors
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.
@@ -0,0 +1,17 @@
1
+ """fastapi-mpp public package exports."""
2
+
3
+ from .core import MPP
4
+ from .exceptions import InvalidReceiptError, MPPError, PaymentRequiredError
5
+ from .types import MPPChargeOptions, MPPReceipt, MPPSession
6
+
7
+ __all__ = [
8
+ "MPP",
9
+ "MPPChargeOptions",
10
+ "MPPReceipt",
11
+ "MPPSession",
12
+ "MPPError",
13
+ "PaymentRequiredError",
14
+ "InvalidReceiptError",
15
+ ]
16
+
17
+ __version__ = "0.2.0"