Как ограничить скорость запросов к веб-сервисам в Python?

Я работаю над библиотекой Python, которая взаимодействует с API веб-сервисов. Как и многие веб-службы, с которыми я столкнулся, этот запрос требует ограничения скорости запросов. Я хотел бы предоставить необязательный параметр, limit , для экземпляра класса, который, если он предоставлен, будет содержать исходящие запросы до тех пор, пока не пройдет указанное количество секунд.

Я понимаю, что общий сценарий следующий: экземпляр класса делает запрос через метод. Когда это происходит, метод испускает какой-то сигнал, который где-то устанавливает переменную блокировки, и начинает таймер обратного отсчета для количества секунд в limit . (По всей вероятности, блокировка – это сам таймер обратного отсчета.) Если в течение этого временного кадра выполняется другой запрос, он должен быть поставлен в очередь до тех пор, пока таймер обратного отсчета не достигнет нуля и блокировка не будет отключена; на этом этапе отправляется самый старый запрос в очереди, и таймер обратного отсчета сбрасывается, и замок снова включается.

Это случай для нарезания резьбы? Есть ли другой подход, который я не вижу?

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

Кроме того, вообще-то это плохая идея предоставить функции ограничения скорости в библиотеке? Я считаю, что по умолчанию обратный отсчет равен нулю, библиотека по-прежнему позволяет разработчикам использовать библиотеку и предоставлять свои собственные схемы ограничения скорости. Тем не менее, для любых разработчиков, использующих эту услугу, все равно нужно будет ограничивать количество запросов, однако я полагаю, что для библиотеки было бы удобнее обеспечить ограничение скорости.

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

Большое спасибо за ваши предложения!

Крис

5 Solutions collect form web for “Как ограничить скорость запросов к веб-сервисам в Python?”

Это лучше работает с очередью и диспетчером.

Вы разделите свою обработку на две части: источник и отправку . Это могут быть отдельные потоки (или отдельные процессы, если это проще).

Сторона источника создает и завершает запросы по любой ставке, что делает их счастливыми.

Сторона отправки делает это.

  1. Получить время начала запроса, с .

  2. Удаляет запрос, обрабатывает запрос через удаленную службу.

  3. Получить текущее время, т . Сон для скорости – ( tс ) секунд.

Если вы хотите запустить источник, подключенный напрямую к удаленной службе, вы можете сделать это и ограничить скорость обхода. Это хорошо для внутреннего тестирования с макетной версией удаленного сервиса.

Трудная часть этого заключается в создании некоторого представления для каждого запроса, который вы можете заключить в очередь. Поскольку Python Queue будет обрабатывать почти все, вам не нужно много делать.

Если вы используете многопроцессорную обработку, вам придется рассортировать ваши объекты, чтобы поместить их в трубу.

Очередь может быть чрезмерно сложной. Более простое решение – дать вашему классу переменную на время последнего вызова службы. Всякий раз, когда услуга вызывается (! 1), установите waitTime на delay - Now + lastcalltime . delay должна быть равна минимально допустимому времени между запросами. Если это число положительное, засыпайте это задолго до совершения звонка (! 2). Недостатком этого преимущества является то, что он обрабатывает запросы веб-сервисов как синхронные. Преимущество в том, что это абсурдно просто и легко реализовать.

  • (! 1): должно произойти сразу после получения ответа от службы внутри обертки (возможно, в нижней части обертки).
  • (! 2): должно произойти, когда оболочка python вокруг веб-службы вызывается в верхней части обертки.

Разумеется, решение S.Lott более элегантно.

На вашу схему ограничения скорости должны в значительной степени влиять вызывающие соглашения базового кода (синхронный или асинхронный), а также какая область (поток, процесс, машина, кластер?) Будет ограничивать ограничение скорости.

Я бы предложил сохранить все переменные в экземпляре, так что вы можете легко реализовать несколько периодов / ставок контроля.

Наконец, похоже, что вы хотите быть промежуточным компонентом. Не пытайтесь быть приложением и вводить темы самостоятельно. Просто блокируйте / спящий режим, если вы синхронны, и используйте инфраструктуру отправки async, если вы вызываетесь одним из них.

Если ваша библиотека спроектирована так, чтобы быть синхронной, я бы рекомендовал оставить ограничение соблюдения (хотя вы могли отслеживать ставки и, по крайней мере, помогать вызывающему абоненту решать, как соблюдать лимиты).

В настоящее время я использую скрученный интерфейс с почти всем. Это упрощает выполнение этого типа, имея модель, которая отделяет представление запроса от обработки ответа. Если вы не хотите, чтобы ваши пользователи API могли использовать скрученные, вам, по крайней мере, было бы лучше понять их API для отложенного исполнения.

Например, у меня есть интерфейс twitter, который отталкивает довольно абсурдное количество запросов от имени пользователей xmpp . Я не оцениваю ограничение, но мне пришлось немного потрудиться, чтобы все запросы не возникали одновременно.

Итак, я предполагаю что-то простое, например, время импорта time.sleep (2) не будет работать в ожидании 2 секунды между запросами

Python - лучший язык программирования в мире.