Chambers
-- -- --

How to limit API request to 2 every 90 seconds?

Anonymous in /c/coding_help

848
I'm using Python and using Keysight's API for DMM. The device can only do 2 requests every 90 seconds. If it sends more, it just doesn't register the commands.<br><br>May be overcomplicating this, but here's what I have tried so far:<br><br>```python<br>import time<br>import datetime <br><br>class APILimiter:<br> def __init__(self):<br> self._last_time = datetime.datetime.now()<br> self._last_request_time_list = []<br><br> def sleep(self,func):<br> last_time = datetime.datetime.now()<br><br> print(f"Last API request time: {self._last_time}")<br> time.sleep(0.005) #add a tiny bit of time to account for the latency of the sleep function<br><br> if last_time - self._last_time > datetime.timedelta(seconds=90):<br> self._last_time = last_time<br> self._last_request_time_list = []<br><br> if len(self._last_request_time_list) >= 2:<br> min_index = self._last_request_time_list.index(min(self._last_request_time_list))<br> self._last_request_time_list.remove(self._last_request_time_list[min_index])<br> self._last_request_time_list.append(last_time)<br><br> #print("Exceed 2 requests. Wait for 90 seconds")<br> while last_time - self._last_request_time_list[min_index] < datetime.timedelta(seconds=90):<br> last_time = datetime.datetime.now()<br> time.sleep(0.005) #add a tiny bit of time to account for the latency of the sleep function<br><br> else:<br> self._last_request_time_list.append(last_time)<br> self._last_time = last_time<br><br> func()<br><br>#Test the APILimiter<br>def test_func():<br> print("API request send")<br> print(f"Sleep for {20} seconds")<br> time.sleep(20)<br> print("===========================================================")<br><br>limiter = APILimiter()<br>limiter.sleep(test_func)<br>limiter.sleep(test_func)<br>limiter.sleep(test_func)<br><br>time.sleep(100)<br>print("After 100 seconds")<br>limiter.sleep(test_func)<br>limiter.sleep(test_func)<br>limiter.sleep(test_func)<br><br>time.sleep(100)<br>print("After another 100 seconds")<br>limiter.sleep(test_func)<br>limiter.sleep(test_func)<br>limiter.sleep(test_func)<br>```<br><br>This will run into problem if I run multiple threads or processes with the same APILimiter instance as the API may not be received in the same order as they are sent out. And the code is not clean either.<br><br>Is this a known problem? Any pattern that can handle this problem?<br><br>TIA.

Comments (18) 32335 👁️