Python SDK

mesta on PyPI: client options, request options, async client, raw responses and logging.

Python SDK

mesta is the official Python client for the Mesta API. It supports Python 3.10 and later, is typed, and uses httpx for transport and pydantic for models. Source, issues and the full method reference are at mestafi/mesta-python.

pip install mesta

Client options

import os

from mesta import Mesta, MestaEnvironment

client = Mesta(
    api_key=os.environ["MESTA_API_KEY"],
    api_secret=os.environ["MESTA_API_SECRET"],
    environment=MestaEnvironment.PRODUCTION,
)
OptionDefaultPurpose
api_key, api_secretrequiredSent as x-api-key and x-api-secret on every request.
environmentMestaEnvironment.PRODUCTIONMestaEnvironment.STAGING for the staging API.
base_urlunsetA full base URL, if you route through a proxy. Overrides environment.
timeout60Per-request timeout in seconds.
max_retries2Retries on 408, 409, 429 and 5xx, with exponential backoff. See Retries, timeouts and writes before relying on retries for writes.
headersunsetExtra headers sent on every request.
httpx_clientbuilt-inYour own httpx.Client, for proxies or custom transports.
loggingoffSee Logging.

Request options

Every method takes request_options, a dictionary that applies to that call only.

accounts = client.merchants.accounts.list(
    request_options={
        "max_retries": 0,
        "timeout": 30,
        "additional_headers": {"X-Request-Source": "payroll-run-42"},
    }
)

Keys: max_retries, timeout, additional_headers, additional_query_parameters and additional_body_parameters.

Async client

AsyncMesta has the same methods as Mesta, awaited. If you pass your own transport, use httpx.AsyncClient.

import asyncio

from mesta import AsyncMesta


async def main() -> None:
    client = AsyncMesta(api_key="...", api_secret="...")
    balances = await client.merchants.accounts.list_balances()
    print(balances.data)


asyncio.run(main())

Models

Responses are pydantic models. Fields use snake_case, so sourceCurrency in the API is source_currency on the model. Call .model_dump() for a plain dictionary.

quote = client.quotes.create(source_currency="USDC_SOL", target_currency="EUR", source_amount=10)
print(quote.data.source_currency, quote.data.target_currency)
print(quote.model_dump())

Raw responses

Every resource has a with_raw_response variant that returns the status code and headers next to the parsed body.

response = client.quotes.with_raw_response.list()
print(response.status_code, response.headers)
print(response.data)

Logging

The client logs through the standard logging module under the logger name mesta. At debug level it records each request and response with the credentials and other sensitive headers redacted.

import logging

logging.basicConfig(level=logging.DEBUG)
logging.getLogger("mesta").setLevel(logging.DEBUG)

Errors

Every error extends mesta.core.api_error.ApiError, which carries status_code and body. The status-specific classes are in mesta.errors: BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, ConflictError, TooManyRequestsError and InternalServerError.

from mesta.core.api_error import ApiError
from mesta.errors import UnauthorizedError

try:
    client.merchants.accounts.list()
except UnauthorizedError:
    raise SystemExit("check MESTA_API_KEY and MESTA_API_SECRET")
except ApiError as e:
    print(e.status_code, e.body)

Did this page help you?