2

i need to check data on an API. The API is refreshed with new data every 5 minutes (10:00, 10:05, 10:10 etc...)

I don't want to use time.sleep(300) because i want my script to do something at 10:05:03, then 10:05:03 etc. and not 5 min avec the script started (maybe it started at 10h12 How can i build this?

Thanks y'all.

Stitry
  • 23
  • 4
  • Does this answer your question? [Python threading.timer - repeat function every 'n' seconds](https://stackoverflow.com/questions/12435211/python-threading-timer-repeat-function-every-n-seconds) – Fred Larson Jan 04 '22 at 14:53
  • Thanks for the help but i do not want to use something based on 300sec. Because i want it to perfectly start on HH:05 then HH:10 then HH:15 etc... not HH:18 for example. – Stitry Jan 04 '22 at 15:03

2 Answers2

2

UPDATE:

Just wanted to remove the possibility of recursion error, so I have rewritten the code:

from threading import Thread
from time import sleep
import datetime

def check_api():
    # ... your code here ...
    pass

def schedule_api():
    while datetime.datetime.now().minute % 5 != 0:
        sleep(1)
    check_api()
    while True:
        sleep(300)
        check_api()

thread = Thread(target=schedule_api)
thread.start()

Also if you want your thread to quit when the main program exits you could set daemon as True on the thread like:

thread.daemon = True

But this does not enforce a clean termination of this thread so you could also try this approach below:

# ...
RUNNING = True
# ...
thread = Thread(target=schedule_api)
thread.start()
#...
def main():
    # ... all main code ...
    pass

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        RUNNING = False


You can use the following code:

import threading

def check_api():
    pass

timer_thread = threading.Timer(300, check_api)
timer_thread.start()
# call timer_thread.cancel() when you need it to stop

This will call your check_api function every 5 minutes and will not block your main code's execution.

as mentioned by @scotyy3785 the above code will only run once but I realize what you want and have written the code for it:

from threading import Thread
from time import sleep
import datetime


def check_api():
    # ... your code here ...
    pass


def caller(callback_func, first=True):
    if first:
        while not datetime.datetime.now().minute % 5 == 0:
            sleep(1)
    callback_func()
    sleep(300)
    caller(callback_func, False)


thread = Thread(target=caller, args=(check_api,))
thread.start()

# you'll have to handle the still running thread on exit

The above code will call check_api at minutes like 00, 05, 10, 15...

Sujal Singh
  • 532
  • 1
  • 5
  • 14
0

Check the time regularly in a loop and do something at certain minute marks:

import time

# returns the next 5 minute mark
# e.g. at minute 2 return 5
def get_next_time():
    minute = time.localtime().tm_min
    result = 5 - (minute % 5) + minute
    if result == 60:
        result = 0
    return result

next_run = get_next_time()

while True:
    now = time.localtime()
    # at minute 0, 5, 10... + 3 seconds:
    if next_run == now.tm_min and now.tm_sec >= 3:
        print("checking api")
        next_run = get_next_time()
    time.sleep(1)
Wups
  • 2,489
  • 1
  • 6
  • 17