Skip to content

Missing timeout: Python SDK — ApiClient configured without request timeout; all sidecar calls can hang indefinitely #682

@realfishsam

Description

@realfishsam

Location

sdks/python/pmxt/client.py:362–366

Code

config = Configuration(host=effective_base_url)
self._api_client = ApiClient(configuration=config)
self._api = DefaultApi(api_client=self._api_client)

And every call site throughout the file (representative example):

response = self._fetch_with_retry(
    lambda: self._api_client.call_api(
        method="POST",
        url=url,
        body=body,
        header_params=headers,
    )
)

No _request_timeout is passed to any call_api() invocation. The Configuration object is also constructed without a timeout attribute.

Risk

If the sidecar hangs processing a request (for example, because BaseExchange.http has no timeout — see issue #200 — and a venue API stalls), every Python SDK method blocks indefinitely. The _fetch_with_retry wrapper only catches connection-level errors; it has no wall-clock deadline.

This affects all Python callers in both local sidecar and hosted modes.

Affected Methods

Every public method on Exchange and Router that calls _api_client.call_api():

  • fetch_markets(), fetch_events(), fetch_market(), fetch_event()
  • fetch_order_book(), fetch_order_books()
  • fetch_ohlcv(), fetch_trades()
  • cancel_order(), fetch_order(), fetch_open_orders(), fetch_closed_orders()
  • fetch_positions(), fetch_balance(), fetch_my_trades()
  • fetch_market_matches(), compare_market_prices(), fetch_arbitrage(), etc.
  • All Router methods (inherits from Exchange)

Suggested Fix

Option A — per-call timeout (most explicit):

response = self._fetch_with_retry(
    lambda: self._api_client.call_api(
        method="POST",
        url=url,
        body=body,
        header_params=headers,
        _request_timeout=30,
    )
)

Option B — configuration-level default:

config = Configuration(host=effective_base_url)
config.timeout = 30  # seconds
self._api_client = ApiClient(configuration=config)

Found by automated missing timeout audit

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions