Metadata-Version: 2.5
Name: weft-sdk
Version: 0.32.2
Summary: Unified Weft SDK for the Weft API and x402 Facilitator
Project-URL: Homepage, https://weftlabs.com
Project-URL: Documentation, https://weft.network/docs
Project-URL: Repository, https://github.com/weftlabs/weft-sdk
Author: Weft Labs
License: Apache-2.0
Keywords: micropayments,payments,sdk,weft,x402
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2
Requires-Dist: python-dateutil>=2.8.2
Requires-Dist: typing-extensions>=4.7.1
Requires-Dist: urllib3<3,>=1.25.3
Requires-Dist: x402<3,>=2.25.0
Description-Content-Type: text/markdown

# `weft-sdk` for Python

The supported Python buyer client for Weft. Generated OpenAPI APIs remain
available under `weft_sdk.generated` as an advanced escape hatch.

## Install and authenticate

Use Python compatible with the `requires-python` contract in
[pyproject.toml](pyproject.toml). For source development, use the pinned Mise
runtime and installation/build/unit steps in the
[repository README](../README.md#local-development-tools); those checks need
no buyer key. This package is a library, not a server, so no independent
start/stop step applies.

The examples below call a real Weft account and are optional consumer usage,
not source setup verification. Create a buyer `wk_*` key in
[Dashboard → API keys](https://weft.network/dashboard/buyer/api_keys), then:

```sh
pip install weft-sdk
export WEFT_API_KEY="wk_..."
```

## Search

```python
import os

from weft_sdk import Client

api_key = os.environ["WEFT_API_KEY"]
with Client(api_key=api_key) as weft:
    account = weft.me()
    results = weft.search(query="weather data API", max_results=5)

print(account.data)
print(results.results)
```

The client defaults to `https://weft.network`.

## Bounded paid fetch

Paid fetches require both a maximum cost and an idempotency key. Reuse the key
when retrying the same logical purchase after an uncertain response.

```python
from uuid import uuid4

idempotency_key = str(uuid4())
artifact = weft.fetch(
    url="https://merchant.example/data",
    max_cost_usd="0.05",
    idempotency_key=idempotency_key,
)
```

## Handle API errors

All buyer-client methods raise the same `WeftError` shape, including the HTTP
status, stable error code, request ID, retry hint, and structured details.

```python
from weft_sdk import WeftError

try:
    results = weft.search(query="weather data API")
except WeftError as error:
    print(error.status, error.code, error.request_id, error.retryable, error.charge)
    print(error.details)
    raise
```

- `401`: confirm that `WEFT_API_KEY` contains a current buyer `wk_*` key.
- `403`: inspect `code` and `details` for an insufficient balance or spending
  policy denial before changing the request.
- `409` (`IDEMPOTENCY_CONFLICT`): this buyer already used the supplied
  idempotency key for a different fetch request. Generate a new key for the
  new operation; the original operation retries unchanged with its own key.
  `retryable` is `False` — resending the conflicting request will conflict
  again.
- `429`: honor `Retry-After` and back off.
- `5xx`: retry transient failures with backoff; reuse the idempotency key for a
  paid fetch.
- `status == 0` (`NETWORK_ERROR`): the request failed before any Weft
  response, so the outcome is uncertain. `retryable` is `True`; retry with
  backoff and reuse the idempotency key for a paid fetch.
- `charge`: `"none"` means this call cannot have paid. For a fetch, Weft
  refused before it signed a payment (for example `EXCEEDED_MAX_COST` or
  `MERCHANT_RETURNED_NON_402`). `"possible"` means this fetch can have paid
  (a 5xx, a network error, `PAID_DELIVERY_FAILED`). After `"possible"`, retry
  only with the same idempotency key and the same request: Weft returns the
  stored response or reuses the existing payment. A new key can pay again.
  `"none"` covers this call only; an earlier call with the same key can still
  have paid.

See the [API reference](https://weft.network/docs) for the complete contract.
Product guides live on [weftlabs.com](https://weftlabs.com).

## Seller middleware

Use `WeftASGIMiddleware`. `weft_require_payment`, `weft_flask_require_payment`, and `WeftPaymentMiddleware` do not work on x402 2.x.
`create_auth_headers` must be synchronous. x402 reads those headers on a sync call.
