Recuut Python SDK
The base package is a framework-neutral client for Recuut's Merchant API.
pip install recuut
export RECUUT_API_KEY="recuut_test_..."
from recuut import Recuut
from recuut.merchant_api import TransactionFilter, TransactionStatus
with Recuut() as client:
for transaction in client.transactions.list(
max=100,
page_size=50,
filter=TransactionFilter(status=TransactionStatus.SUCCEEDED),
):
print(transaction.id, transaction.status)
for resource in client.resources.list(max=100, page_size=25):
print(resource.id, resource.name)
The same namespaces are available asynchronously:
from recuut import AsyncRecuut
async with AsyncRecuut(api_key="recuut_live_...") as client:
page = await client.payers.list(max=100, page_size=25)
async for payer in page:
print(payer.identifier, payer.created_at)
The top-level resource groups come from Merchant OpenAPI tags, while method
names come from each operation ID: client.payers.list(),
client.transactions.list(), client.transactions.get(), and
client.resources.list(). A list call returns the first page immediately.
Its items, count, resolved as_of, and nullable next describe that HTTP
page. Iterate over the page to fetch later pages lazily; max bounds the total
items yielded by that iterator. Generated filter objects contain backend-owned
selection fields. page_size and order are sent to the backend, while max
only limits SDK iteration.
Every operation accepts request_options with per-request headers and
timeout. Use with_raw_response when successful HTTP metadata matters:
with Recuut() as client:
response = client.resources.with_raw_response.list(
page_size=25,
request_options={"headers": {"X-Trace-ID": "trace-123"}},
)
print(response.status_code, response.headers, response.data.items)
Test and live isolation
The API key selects one environment. A recuut_test_* key sees only test
resources, contracts, payers, and transactions, while a recuut_live_* key
sees only live data. Equivalent resources may use the same immutable
integration key in both environments even though their res_… and revision
IDs differ. Client methods intentionally accept no organization or environment
parameter.
Pull typed contracts
Configure the only directory the generator may manage:
[tool.recuut]
contracts-output-dir = "src/my_app/recuut_contracts"
recuut pull-contracts -v
The directory must be named recuut_contracts. Recuut creates one
<integration_key>__generated.py module per integration and re-exports its
public symbols from a generated __init__.py. Existing generated packages keep
their module and symbol names when upgraded. Generated packages expose
INTEGRATION_KEY and GENERATED_INTEGRATIONS while retaining RESOURCE_ID and
GENERATED_RESOURCES.
Before creating, updating, or deleting managed files, the command prints a plan
and asks for confirmation. --yes applies it non-interactively. --check never
writes or prompts and exits unsuccessfully only when generated source has
drifted. Files without Recuut's generated banner are never overwritten or
deleted. The schema digest describes immutable revision value shapes and does
not include mutable pricing policy.
RECUUT_API_URL defaults to https://api.recuut.com; set it, pass --api-url,
or configure api-url under [tool.recuut] for local or staging use.
FastAPI
pip install "recuut[fastapi]"
from fastapi import FastAPI
from pydantic import BaseModel
from recuut import recuut
from my_app.recuut_contracts import TextGenerationPayment, TextGenerationV1
app = FastAPI()
class GenerateRequest(BaseModel):
prompt: str
class GenerateResponse(BaseModel):
text: str
@app.post("/generate")
@recuut(TextGenerationV1)
async def generate(
payload: GenerateRequest,
payment: TextGenerationPayment,
) -> GenerateResponse:
payment.report(input_tokens=len(payload.prompt.split()))
return GenerateResponse(text=payload.prompt.upper())
The decorator hides and injects payment, validates the request before access
negotiation, relays a 402 challenge unchanged, completes a paid transaction,
then attaches PAYMENT-RESPONSE and releases the protected result. Sync handlers
run through FastAPI's thread pool. A returned 4xx or 5xx fails the
transaction and reports only status, duration, media type, and response size
when available. Response bodies and headers are never sent to recuut. Streaming
responses are rejected in v1.
Django
pip install "recuut[django]"
from django.http import HttpRequest
from pydantic import BaseModel
from recuut.django import recuut
from my_app.recuut_contracts import TextGenerationPayment, TextGenerationV1
class GenerateRequest(BaseModel):
prompt: str
class GenerateResponse(BaseModel):
text: str
@recuut(TextGenerationV1)
async def generate(
request: HttpRequest,
payload: GenerateRequest,
payment: TextGenerationPayment,
) -> GenerateResponse:
payment.report(input_tokens=len(payload.prompt.split()))
return GenerateResponse(text=payload.prompt.upper())
Django uses the same negotiation and completion client. It validates Pydantic payloads and responses, runs sync views through Django's thread-sensitive worker path, relays challenges, reports only safe response metadata, and rejects streaming before protected content is read.
Runtime and raw contracts
Framework integrations call the generated payments.access and
transactions.complete façade methods. Generated payments validate exact
value keys and decimal constraints before completion. For a revision that has
not been pulled into your application, use the explicit escape hatch:
from recuut import RawPayment, RawRevision, recuut
@recuut(RawRevision("acr_00000000000070008000000000000000"))
async def raw_endpoint(payment: RawPayment) -> dict[str, bool]:
payment.report({"items": 1})
return {"ok": True}
Errors
Configuration problems raise RecuutConfigurationError, and network failures
raise RecuutTransportError. Documented non-successful HTTP responses raise a
generated RecuutResponseError; future statuses, undocumented error codes, and
malformed payloads raise RecuutUnexpectedResponseError. Response errors retain
the exact status, body, and headers so integrations can preserve protocol
challenges.
Runnable examples
Each example is an independently locked consumer project kept beside the SDK:
Metadata
Release files for recuut 0.5.0
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 | Actions |
|---|---|---|---|---|
| recuut-0.5.0.tar.gz | 84.2 kB | With provenance | Details for recuut-0.5.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| recuut-0.5.0-py3-none-any.whl | Python 3 | none | any | Details for recuut-0.5.0-py3-none-any.whl |
Total release size: 302.3 kB
Release files / recuut-0.5.0.tar.gz
| Download URL | recuut-0.5.0.tar.gz |
|---|---|
| Size | 84.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
361ad0c1f40f999b58e57b5b30977950c5239268ecce4dd1667835de1ce58f30
|
|
BLAKE2b-256 checksum How to use checksums |
e4a820a80ce40b7f4291984499f82066cad89cf94cc154f37fa7fc2303057f45
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.
Transparency logRelease files / recuut-0.5.0-py3-none-any.whl
| Download URL | recuut-0.5.0-py3-none-any.whl |
|---|---|
| Size | 218.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
67788651c22955eee3c5f2ada55db25bc3c3c18509871006e045a14b844df1d4
|
|
BLAKE2b-256 checksum How to use checksums |
7d0456715438ae408c2ce3b3f66f2e8b15088647febc9e85875ac7d979a62237
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.
Transparency logSecurity for recuut 0.5.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for recuut-0.5.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.
Transparency logA 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.