> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://mpp.dev/api/mcp` to find what you need.

# Python SDK \[The pympp Python library]

## Overview

The `mpp` Python library provides a typed interface over the Machine Payments Protocol, from high-level abstractions to low-level primitives and building blocks.

<div className="flex gap-2">
  [GitHub: tempoxyz/pympp](https://github.com/tempoxyz/pympp)

  Maintained by [Tempo](https://github.com/tempoxyz)
</div>

## Install

```bash [install.sh]
$ pip install pympp
```

With Tempo blockchain support:

```bash [install-with-tempo.sh]
$ pip install "pympp[tempo]"
```

## Requirements

* Python 3.10+
* `httpx` for async HTTP
* `eth-account` for Tempo signing (with `[tempo]` extra)

## Quick start

### Server

```python [server.py]
import os
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from mpp import Challenge
from mpp.server import Mpp
from mpp.methods.tempo import tempo, ChargeIntent

app = FastAPI()

mpp = Mpp.create(
    method=tempo(
        currency="0x20c0000000000000000000000000000000000000",
        intents={"charge": ChargeIntent()},
        recipient="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
    ),
    secret_key=os.environ["MPP_SECRET_KEY"],
)

@app.get("/resource")
async def get_resource(request: Request):
    result = await mpp.charge(
        authorization=request.headers.get("Authorization"),
        amount="0.50",
    )

    if isinstance(result, Challenge):
        return JSONResponse(
            status_code=402,
            content={"error": "Payment required"},
            headers={"WWW-Authenticate": result.to_www_authenticate(mpp.realm)},
        )

    credential, receipt = result
    return {"data": "paid content", "payer": credential.source}
```

Set `MPP_SECRET_KEY` in your environment before you start the server, or pass `secret_key` explicitly to `Mpp.create()`.

### Client

```python [client.py]
import asyncio
from mpp.client import Client
from mpp.methods.tempo import tempo, TempoAccount, ChargeIntent

async def main():
    account = TempoAccount.from_env()

    async with Client(methods=[tempo(account=account, intents={"charge": ChargeIntent()})]) as client:
        response = await client.get("https://mpp.dev/api/ping/paid")
        print(response.json())

asyncio.run(main())
```

## Next steps

[Core types](/sdk/python/core) — Challenge, Credential, Receipt types

[Client](/sdk/python/client) — Handle 402 responses automatically

[Server](/sdk/python/server) — Protect endpoints with payments
