Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start/stop a Python function within a time period (ex. from 10 am to 12:30pm)?

I am trying to create a function (e.g. def startTime()) that executes another function like def runFunc() that starts every day on execution with python script at 10 am and stops automatically (or script ends) at 12:30 pm.

Example: startTime(start_time, stop_time,runFunc)

Can anyone help me with that?

I am trying to schedule startTime from 10 am to 12:30 pm.

import threading
import schedule
import time

def runFunc(interval, innerFunc, iterations = 0):
   if iterations != 1:
      threading.Timer (interval,runFunc, [interval, innerFunc , 0 ]).start ()
   innerFunc ()

def A():
     print "Hello World- A"
def B():
     print "Hello World- B"

I tried this but didn't work:

def startTime(job):
      schedule.every().day.at("10:00").do(job)
      while True:
           schedule.run_pending()

startTime(runFunc(60,A))
startTime(runFunc(300,B))

runFunc(60,A) runs fine, but it is unable to schedule the runFunc from 10 am to 12:30 pm.

Another way

from datetime import datetime, time
now = datetime.now()
now_time = now.time()
now_time
if time(5,27) <= now.time() <= time(5,28):
    runFunc(10,A)

runFunc does stop, but it keeps on executing after the end time.

like image 851
Devinderjeet Singh Avatar asked Dec 22 '16 18:12

Devinderjeet Singh


People also ask

How do I stop a Python program after a certain line?

Ctrl + C on Windows can be used to terminate Python scripts and Ctrl + Z on Unix will suspend (freeze) the execution of Python scripts. If you press CTRL + C while a script is running in the console, the script ends and raises an exception.

How do you stop a program from a certain time in Python?

Python sleep() function will pause Python code or delay the execution of program for the number of seconds given as input to sleep(). The sleep() function is part of the Python time module. You can make use of Python sleep function when you want to temporarily halt the execution of your code.

How do you stop a function in Python?

How do I end a function in Python? A return statement effectively ends a function; that is, when the Python interpreter executes a function's instructions and reaches the return , it will exit the function at that point.


1 Answers

The whole story is kind of complicated and it highly depends on what you really want to with your script. For example this code will work ok:

import threading
import schedule
import time
import datetime
import sys
def test():
    print('{} This is a test'.format(datetime.datetime.now())) #this works ok

def exit():
    print('{} Now the system will exit '.format(datetime.datetime.now())) #this works ok
    sys.exit()

schedule.every().day.at("09:57").do(test)
schedule.every().day.at('09:58').do(exit)

while True:
    schedule.run_pending()
    time.sleep(1)

You will see in your terminal the "test message" and after one minute you will see the "exit message" which actually terminates the script.

But If you apply some loops inside function test above like :

def test():
    while True: 
        print "This is a test"
        time.sleep(5)

then script will not exit. In reality function exit will not be even called since Python is trapped by the while loop inside function test and will keep going on and on.

Schedule documentation points out that scheduled jobs are called in series, so if the previous job is not finished the next job is not starting actually.

I suspect that your purpose is to have a kind of function running continuously at 10:00 and you want to force stop this function at 12:30. If it was not like this , your main function will exit as soon as he complete it's job and you wouldn't need a time frame.

In this case and in order to work around the serialize way of Python & Schedule you need to work with threads.

Combining info from Schedule Documentation on "how to execute jobs in parallel" section and info from other answers in Overflow like how to stop a running thread, this example worked fine in my pc with Python 2.7:

import threading
    import schedule
    import time
    import datetime
    import sys

def doit(stop_event, arg):
    while not stop_event.wait(1): 
        #By wait(1) you repeat the loop every 1 sec. 
        #Applying wait(0) , loops run immediatelly until to be stopped by  stop_event
        print ("working on %s" % arg)
    print("Stopping as you wish.")


def startit():
    global pill2kill
    global t
    pill2kill = threading.Event()
    t = threading.Thread(target=doit, args=(pill2kill, "task"))
    t.start()

def stopit():
    global pill2kill
    global t
    pill2kill.set()
    t.join()

#startit() #Manual call for Testing 
#time.sleep(5) #Wait 5 seconds
#stopit() #Manual call for Testing

schedule.every().day.at("12:48").do(startit)
schedule.every().day.at('12:49').do(stopit)

#schedule.every().day.at("12:50").do(startit) #Uncomment this to recall it for testing
#schedule.every().day.at('12:51').do(stopit) #Unocmment this to recall it for testing

while 1:
    schedule.run_pending()
    time.sleep(1)

You could also check out the Python Crontab library in case that suits your needs.

PS: By the way, with a quick look at source code of Python Schedule Lib it seems that the whole story is made by trapping the whole script and continuously compare date.now() with date set to run a job. This logic could be reconstructed with a couple of default commands and an infinite master loop to continiously compare dates (like Schedule Lib does).
This post has some nice snippets to make your own cron jobs, but just for testing this simplified script also works fine without external libs, calling function test when the datetime.now is within the required start/stop frame.

from datetime import datetime
import time

def test():
    global hasrun
    print('{} This is a test'.format(datetime.now()))
    time.sleep(5)
    hasrun=True

year,month,day,hour,minute=2016,12,23,15,55 
hasrun=False
now=datetime.now()

print "Now the time is :", now
jobstart=datetime(year,month,day,hour,minute)
jobstop=datetime(year,month, day,hour,minute+1)
print "Job will run at: ", jobstart
print "Job will finish at: ", jobstop
#print datetime.now() - jobstart
while True:
    while ((datetime.now() > jobstart) and (datetime.now() < jobstop )): 
        test()
    else:
        print('{} Please Wait...'.format(datetime.now()))
        if hasrun:
#           day=day+1
            minute=minute+2 #Just for Testing
            jobstart=datetime(year,month,day,hour,minute)
            jobstop=datetime(year,month, day,hour,minute+1)
            print "the job will run again ", jobstart
            print "and will finish at ", jobstop
            hasrun=False
        time.sleep(5)
like image 83
George Vasiliou Avatar answered Sep 28 '22 04:09

George Vasiliou