When using the schedule package in Python, I would like to schedule a task to start at a specific time, and then run every 10 seconds. I was able to get the task to run every 10 seconds, using schedule.every(10).seconds.do(x) and I also got it to run at a set time, using schedule.every().day.at('13:25').do(x). But how would I put these together? I tried to combine them into the following, but I got RecursionError: maximum recursion depth exceeded
import schedule
import time
def test():
print('Hello, World!')
def sched_job():
schedule.every(10).seconds.do(test)
while True:
schedule.run_pending()
time.sleep(1)
schedule.every().day.at('13:56').do(sched_job)
while True:
schedule.run_pending()
time.sleep(1)
sched_job()
Don't call run_pending() from inside your job, just schedule an additional job and use your main loop to call it. The only thing you need to change in your code is removing the while True block in sched_job(). Also, in order to prevent a second schedule to be created every 10 seconds on the next day at the given time, the outer job should immediately cancel itself once it is executed once. You can do this by returning schedule.CancelJob.
Here is the modified code:
import schedule
import time
def test():
print('Hello, World!')
def sched_job():
schedule.every(10).seconds.do(test)
return schedule.CancelJob
schedule.every().day.at('13:56').do(sched_job)
while True:
schedule.run_pending()
time.sleep(1)
Related
I want to write a program that keeps running in the background and performs a certain task at each hour of the day. How do I achieve this?
for production i would add cron or schedule
# Schedule Library imported
import schedule
import time
# Functions setup
def sudo_placement():
print("Get ready for Sudo Placement at Geeksforgeeks")
def good_luck():
print("Good Luck for Test")
def work():
print("Study and work hard")
def bedtime():
print("It is bed time go rest")
def geeks():
print("Shaurya says Geeksforgeeks")
# Task scheduling
# After every 10mins geeks() is called.
schedule.every(10).minutes.do(geeks)
# After every hour geeks() is called.
schedule.every().hour.do(geeks)
# Every day at 12am or 00:00 time bedtime() is called.
schedule.every().day.at("00:00").do(bedtime)
# After every 5 to 10mins in between run work()
schedule.every(5).to(10).minutes.do(work)
# Every monday good_luck() is called
schedule.every().monday.do(good_luck)
# Every tuesday at 18:00 sudo_placement() is called
schedule.every().tuesday.at("18:00").do(sudo_placement)
# Loop so that the scheduling task
# keeps on running all time.
while True:
# Checks whether a scheduled task
# is pending to run or not
schedule.run_pending()
time.sleep(1)
You can write a if condition in a infinite while loop to check if current time is equals to your time say (12:00:00pm, 04:00:00am) or you can make use of the sleep method, it stops the exexution of your code for the specified amount of time, you must find that by calculating the difference between your time and the current time and this method does not consume much memory and cpu cycles like the previous method.
I'd advise setting up a cron job to run your python program at specific time
Try this:
from datetime import datetime # Import datetime
def schedule(time, function): # Syntax:
cur_time = datetime.strftime("%T") # time: 24 hour time hh:mm:ss (09:00:00 or 21:00:00)
if cur_time == time: # function: lampda: to_execute()
function()
def scheduled_function():
print("TEST")
while True:
schedule("15:00:00", lampda:scheduled_function()) # Schedule scheduled_function() to execute at 3:00 pm
I would like to start my code at the start of every hour I have tried using the minutes function of schedule however, the start time of the next process is dependent upon the end of the previous process and with the code I am trying to process the delay accumulates pretty quickly hence, I am trying this method instead. All help is appreciated. Thanks.
The code:
import schedule
import time
schedule.every().day.at("00:00").do(consolidated)
schedule.every().day.at("01:00").do(consolidated)
schedule.every().day.at("02:00").do(consolidated)
schedule.every().day.at("03:00").do(consolidated)
schedule.every().day.at("04:00").do(consolidated)
schedule.every().day.at("05:00").do(consolidated)
schedule.every().day.at("06:00").do(consolidated)
schedule.every().day.at("07:00").do(consolidated)
schedule.every().day.at("08:34").do(consolidated)
schedule.every().day.at("09:00").do(consolidated)
schedule.every().day.at("10:00").do(consolidated)
schedule.every().day.at("11:00").do(consolidated)
schedule.every().day.at("12:00").do(consolidated)
schedule.every().day.at("13:00").do(consolidated)
schedule.every().day.at("14:00").do(consolidated)
schedule.every().day.at("15:00").do(consolidated)
schedule.every().day.at("16:00").do(consolidated)
schedule.every().day.at("17:00").do(consolidated)
schedule.every().day.at("18:00").do(consolidated)
schedule.every().day.at("19:00").do(consolidated)
schedule.every().day.at("20:00").do(consolidated)
schedule.every().day.at("21:00").do(consolidated)
schedule.every().day.at("22:00").do(consolidated)
schedule.every().day.at("23:00").do(consolidated)
while True:
schedule.run_pending()
time.sleep(1)
The schedule package has an option for doing a task every hour:
import schedule
import time
schedule.every().hour.do(consolidated)
while True:
schedule.run_pending()
time.sleep(1)
How do I run a scheduled job at random times daily starting with today? I want to use the schedule package.
pip install schedule
import schedule
def job()
print("foo")
return schedule.CancelJob
while True:
time_str = '{:02d}:{:02d}'.format(random.randint(6, 10), random.randint(0, 59))
print("Scheduled for {}".format(time_str))
schedule.every().day.at(time_str).do(job)
schedule.run_pending()
The above code just spins:
Scheduled for 06:36
Scheduled for 10:00
Scheduled for 06:18
You're providing a moving target by putting your random time generator inside you while loop. Specifically, after reviewing the source code here, it is clear that the job will only run if datetime.datetime.now() >= self.next_run is true (see scheduler.run_pending() and job.should_run() definitions). Because you are always moving job.next_run, you will only hit it if it happens to be in the past on that particular iteration of the loop. Interestingly, I think this would cause a bug where the probability of actually running your job increases as you approach 24:00, though this has yet to be shown. I think you need to create a separate function for generating the next random time, and call it from your job function. For example:
import schedule
import time
import random
def job():
print("foo")
schedule_next_run()
return schedule.CancelJob
def schedule_next_run():
time_str = '{:02d}:{:02d}'.format(random.randint(6, 10), random.randint(0, 59))
schedule.clear()
print("Scheduled for {}".format(time_str))
schedule.every().day.at(time_str).do(job)
schedule_next_run()
while True:
schedule.run_pending()
time.sleep(60)
Note that the example may not be random for the day that the job starts, as your random time may be before the time you happen to start your script. You could work in a way to pick a random time in the future on the first day to circumvent this as needed.
To verify the above example, I used shorter time spans. The following works for me:
import schedule
import time
import random
def job():
print("foo")
schedule_next_run()
return schedule.CancelJob
def schedule_next_run():
time_span = random.randint(1, 5)
schedule.clear()
print(f'Scheduled in {time_span} seconds')
schedule.every(time_span).seconds.do(job)
schedule_next_run()
while True:
schedule.run_pending()
I have a section of code that I need to get the output from:
gps = get_gps_data()
Though if it takes too long to get the output from get_gps_data(), I would like to cancel the process and set gps to None. Modifying the function is impossible, so is there a way to specify the max amount of time to wait for some code to run and abort if it reaches that time, say 5 seconds?
You can do some thing like below. This will work for any logic or function that you want to check and stop after some time. The function that you want to check and cancel is executed in a separate thread and monitored. After waiting for 3 seconds, it is cancelled.
Just put your code inside the test function (you can rename the functions). test function tries to sleep for 100 seconds (could be any logic). But the main call future.result(3), waits only for 3 seconds else TimeoutError is thrown and some other logic follows.
import time
import concurrent.futures as futures
def test():
print('Sleeping for 100 seconds')
time.sleep(100)
# Add your code here
# gps = get_gps_data()
return 'Done'
# Main
with futures.ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(test)
try:
resp = future.result(3)
except futures.TimeoutError:
print('Some other resp')
else:
print(resp)
executor._threads.clear()
futures.thread._threads_queues.clear()
You can try to minimise the wait time inside the test function to some value less than 3 seconds. In this case, the original result returned from test function will be used.
I'm having a hard hard time with Timer function from threading.
Basically, when my program starts, I want to log stats every x second.
So I thought I could do it with the Timer function (launch function every 5 second).
For now, I did :
from threading import Timer
def startLogger():
while True:
t = Timer(5, function)
t.start()
def function():
print("hey")
But it launch error, so I think it's not the good way to do it.
RuntimeError: can't start new thread
If someone can give me a clue, it would be appreciated!
Instead of starting a new thread every five seconds, you can create just one thread and run all your code from there.
from time import sleep
from threading import Thread
def startLogger():
while True:
function()
sleep(5)
def function():
print("hey")
Thread(target=startLogger).start()
startLogger will continually run. It'll call function, then pause for 5 seconds, then start again, calling function and so on.
It goes in its own thread so that the sleep(5) doesn't also stop your main thread for 5 seconds.
You can try the following. The idea is, that you are scheduling the next function call just at the end of this function's body:
import threading
def mylog():
print "hey"
` threading.Timer(5.0, mylog)`.start()
mylog()