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 mestaClient 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,
)| Option | Default | Purpose |
|---|---|---|
api_key, api_secret | required | Sent as x-api-key and x-api-secret on every request. |
environment | MestaEnvironment.PRODUCTION | MestaEnvironment.STAGING for the staging API. |
base_url | unset | A full base URL, if you route through a proxy. Overrides environment. |
timeout | 60 | Per-request timeout in seconds. |
max_retries | 2 | Retries on 408, 409, 429 and 5xx, with exponential backoff. See Retries, timeouts and writes before relying on retries for writes. |
headers | unset | Extra headers sent on every request. |
httpx_client | built-in | Your own httpx.Client, for proxies or custom transports. |
logging | off | See 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)Updated about 7 hours ago

