Tinkoff / invest-python

Tinkoff Invest Python gRPC client
https://tinkoff.github.io/invest-python/
Apache License 2.0
300 stars 87 forks source link

[Feature] Управление таймаутами запросов #91

Open mancubus721 opened 1 year ago

mancubus721 commented 1 year ago

Описание

При запросе сделок эпизодически происходит такая ошибка: File "C:\Users\ftp-user2\Trading\Phyton\tinklib.py", line 73, in get_trades resp = client.market_data.get_last_trades(figi = fg, File "C:\Users\Admin\anaconda3\lib\site-packages\tinkoff\invest_errors.py", line 28, in wrapper raise RequestError( tinkoff.invest.exceptions.RequestError: (<StatusCode.UNAVAILABLE: (14, 'unavailable')>, 'upstream request timeout', Metadata(tracking_id=None, ratelimit_limit='300, 300;w=60', ratelimit_remaining=298, ratelimit_reset=55, message=None)) Проблема в том, что мой скрипт на этой ошибке подвисает на 1 минуту, похоже где-то внутри библиотеки установлен такой таймаут. Ошибка нечастая, но неприятная, я бы предпочел поставить меньшее время ожидания, чтобы либо послать новый запрос, либо корректно обработать ситуацию. Как правило ошибка происходит в самом начале торгов, примерно в 10.01-10.03.

Желаемое решение

Добавить возможность устанавливать таймаут в секундах, в виде параметра или настроить этот таймаут глобально для всей библиотеки в целом, в виде: resp = client.market_data.get_lasttrades(figi = fg, from=ex_from1, to=ex_to1, timeout = 5) либо client.market_data.set_request_params(timeout = 5)

Дополнительно

No response

NikolayXHD commented 1 year ago

Документация написана так, будто бы у нас есть кнотроль над дедлайном, но выглядит так, что на текущий момент это не поддерживается.

Есть отсылка на gRPC and Deadlines, с примерами, только там нет примеров для Python, есть Go, C++, C#. Те примеры не помогают.

Судя по ответам stackoverflow и по коду в этом репозитории, в Python используется как раз параметр timeout, только его нельзя передать через API, которое нам предоставлено:

https://github.com/Tinkoff/invest-python/blob/abfe8c666482502ecdacb4bc83eb5110fbb74d95/tinkoff/invest/services.py#L414

class InstrumentsService(_grpc_helpers.Service):
    # ...
    @handle_request_error("TradingSchedules")
    def trading_schedules(
        # ...
    )
        response, call = self.stub.TradingSchedules.with_call(
            request=_grpc_helpers.dataclass_to_protobuff(
                request, instruments_pb2.TradingSchedulesRequest()
            ),
            metadata=self.metadata,
            # <-- здесь мог бы передаваться timeout=value
        )
NikolayXHD commented 1 year ago

Как временное решение, в библиотеке grpc для Python поддерживается управление дефолтным таймаутом через переменную среды "GRPC_PYTHON_DEFAULT_TIMEOUT_SECONDS"

https://github.com/grpc/grpc/blob/2d4f3c56001cd1e1f85734b2f7c5ce5f2797c38a/src/python/grpcio/grpc/_simple_stubs.py#L52