Python sched scheduler and reboots - python

I have read about python sched (task scheduler), it works like a cron.
but I have a question :
lets say if I schedule a function to run after every 2 hours and in the mean time my system gets shut down, then I again restart the system...
Does the scheduler automatically start and run the function after 2 hours? Or do I have to start that again after shutting down the system?
Does sched work like a daemon?

Answer to all three questions is No.
sched is different from cron. It takes a generic timer or counter function and a delay function and lets you to schedule a function call after a particular time (an event as defined by your generic timer function).
It won't run after you close your program, unless you maintain state by writing to a file or db. This is complicated and using cron would be better.
sched works on events, but not on background. so, it not is not exactly a deamon, but you can deamonize it running the program in the background using OS facilities.

and if this is so :
will this also work even after system restart?
answer is : NO then how can turbogear scheduler can run using cronos in cron? scheduled events in turbogear will also be vanished after SYSTEM restart.
PLEASE CORRECT ME IF I AM WRONG.
import time
import sched
import datetime
import threading
import calendar
#from datetime import datetime
class test:
def __init__(self):
self.name = ''
def getSec(self):
now = datetime.datetime.now()
print "now - ", now
currentYear = now.year
currentMonth = now.month
currentDay = now.day
currentHour = now.hour
currentMinute = now.minute
currentSecond = now.second
currentMicroseconds = now.microsecond
command = "python runbackup.py"
print "command is - ", command
print "currentMinute - ", currentMinute
print "currentSecond - ", currentSecond
# current time
a = datetime.datetime(currentYear, currentMonth, currentDay, currentHour, currentMinute, currentSecond, currentMicroseconds)
last_date_of_current_month = calendar.monthrange(currentYear, currentMonth)[1]
print "last_date_of_current_month - ", last_date_of_current_month
b = datetime.datetime(currentYear, currentMonth, int(last_date_of_current_month), 23, 59, 59, 000000)
#b = datetime.datetime(currentYear, currentMonth, int(29), 18, 29, 00, 000000)
#print "date time of b is - %s %s " % (18, 29)
c = b-a
print "c is - ", c
time.sleep(1)
scheduler = sched.scheduler(time.time, time.sleep)
#scheduler.cancel(e1)
sec = c.seconds
print "second - ", sec
print "scheduler entered."
e1 = scheduler.enter(sec, 1, self.getSec, ())
t = threading.Thread(target=scheduler.run)
print "thread started."
print "======================================"
t.start()
#scheduler.cancel(e1)
#print "canceled."
return True
if __name__=='__main__' :
obj = test()
obj.getSec()

Related

Run a program on a specific time using python

I want to run a batch file(say wanted to run calculator) on a specific date and time using python (but don't use the default scheduler).
My program:
a = "C:\Windows\system32\calc.exe"
mybat = open(r"D:\Cyber_security\Python\cal.bat", "w+")
mybat.write(a)
mybat.close()
import datetime
start = datetime.datetime.now()
end = datetime.datetime(2022, 7, 12, 17, 29, 10)
while(True):
if(end - start == 0):
import subprocess
subprocess.call([r"D:\Cyber_security\Python\cal.bat"])
when I run it it doesn't show error but the batch file is not running at specific time. where is the wrong?
Ever tried schedule package?
import schedule
import time
def job():
print("I'm working...")
schedule.every(10).seconds.do(job)
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every(5).to(10).minutes.do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
schedule.every().minute.at(":17").do(job)
while True:
schedule.run_pending()
time.sleep(1)
What about Rocketry?
from rocketry import Rocketry
app = Rocketry()
#app.task('every 1 hour')
def do_hourly():
...
#app.task('daily between 10:00 and 14:00 & time of week on Monday')
def do_once_a_day_on_monday():
...
#app.task("after task 'do_hourly'")
def do_after_another():
...
if __name__ == "__main__":
app.run()
It also has parametrization, parallelization and Pythonic conditions if you dislike the string-based condition language.
Documentation: https://rocketry.readthedocs.io/
Source code: https://github.com/Miksus/rocketry
I already found my answer.
a = "C:\Windows\system32\calc.exe"
mybat = open(r"D:\Cyber_security\Python\cal.bat", "w+")
mybat.write(a)
mybat.close()
import sched
from datetime import datetime
import time
def action():
import subprocess
subprocess.call([r"D:\Cyber_security\Python\cal.bat"])
s = sched.scheduler(time.time, time.sleep)
e_x = s.enterabs(time.strptime('Tue Jul 12 19:57:17 2022'), 0, action)
s.run()

Run Function at Given DateTime [duplicate]

How can I run a function in Python, at a given time?
For example:
run_it_at(func, '2012-07-17 15:50:00')
and it will run the function func at 2012-07-17 15:50:00.
I tried the sched.scheduler, but it didn't start my function.
import time as time_module
scheduler = sched.scheduler(time_module.time, time_module.sleep)
t = time_module.strptime('2012-07-17 15:50:00', '%Y-%m-%d %H:%M:%S')
t = time_module.mktime(t)
scheduler_e = scheduler.enterabs(t, 1, self.update, ())
What can I do?
Reading the docs from http://docs.python.org/py3k/library/sched.html:
Going from that we need to work out a delay (in seconds)...
from datetime import datetime
now = datetime.now()
Then use datetime.strptime to parse '2012-07-17 15:50:00' (I'll leave the format string to you)
# I'm just creating a datetime in 3 hours... (you'd use output from above)
from datetime import timedelta
run_at = now + timedelta(hours=3)
delay = (run_at - now).total_seconds()
You can then use delay to pass into a threading.Timer instance, eg:
threading.Timer(delay, self.update).start()
Take a look at the Advanced Python Scheduler, APScheduler: http://packages.python.org/APScheduler/index.html
They have an example for just this usecase:
http://packages.python.org/APScheduler/dateschedule.html
from datetime import date
from apscheduler.scheduler import Scheduler
# Start the scheduler
sched = Scheduler()
sched.start()
# Define the function that is to be executed
def my_job(text):
print text
# The job will be executed on November 6th, 2009
exec_date = date(2009, 11, 6)
# Store the job in a variable in case we want to cancel it
job = sched.add_date_job(my_job, exec_date, ['text'])
Might be worth installing this library: https://pypi.python.org/pypi/schedule, basically helps do everything you just described. Here's an example:
import schedule
import time
def job():
print("I'm working...")
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
while True:
schedule.run_pending()
time.sleep(1)
Here's an update to stephenbez' answer for version 3.5 of APScheduler using Python 2.7:
import os, time
from apscheduler.schedulers.background import BackgroundScheduler
from datetime import datetime, timedelta
def tick(text):
print(text + '! The time is: %s' % datetime.now())
scheduler = BackgroundScheduler()
dd = datetime.now() + timedelta(seconds=3)
scheduler.add_job(tick, 'date',run_date=dd, args=['TICK'])
dd = datetime.now() + timedelta(seconds=6)
scheduler.add_job(tick, 'date',run_date=dd, kwargs={'text':'TOCK'})
scheduler.start()
print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
try:
# This is here to simulate application activity (which keeps the main thread alive).
while True:
time.sleep(2)
except (KeyboardInterrupt, SystemExit):
# Not strictly necessary if daemonic mode is enabled but should be done if possible
scheduler.shutdown()
I've confirmed the code in the opening post works, just lacking scheduler.run(). Tested and it runs the scheduled event. So that is another valid answer.
>>> import sched
>>> import time as time_module
>>> def myfunc(): print("Working")
...
>>> scheduler = sched.scheduler(time_module.time, time_module.sleep)
>>> t = time_module.strptime('2020-01-11 13:36:00', '%Y-%m-%d %H:%M:%S')
>>> t = time_module.mktime(t)
>>> scheduler_e = scheduler.enterabs(t, 1, myfunc, ())
>>> scheduler.run()
Working
>>>
I ran into the same issue: I could not get absolute time events registered with sched.enterabs to be recognized by sched.run. sched.enter worked for me if I calculated a delay, but is awkward to use since I want jobs to run at specific times of day in particular time zones.
In my case, I found that the issue was that the default timefunc in the sched.scheduler initializer is not time.time (as in the example), but rather is time.monotonic. time.monotonic does not make any sense for "absolute" time schedules as, from the docs, "The reference point of the returned value is undefined, so that only the difference between the results of consecutive calls is valid."
The solution for me was to initialize the scheduler as
scheduler = sched.scheduler(time.time, time.sleep)
It is unclear whether your time_module.time is actually time.time or time.monotonic, but it works fine when I initialize it properly.
dateSTR = datetime.datetime.now().strftime("%H:%M:%S" )
if dateSTR == ("20:32:10"):
#do function
print(dateSTR)
else:
# do something useful till this time
time.sleep(1)
pass
Just looking for a Time of Day / Date event trigger:
as long as the date "string" is tied to an updated "time" string, it works as a simple TOD function. You can extend the string out to a date and time.
whether its lexicographical ordering or chronological order comparison,
as long as the string represents a point in time, the string will too.
someone kindly offered this link:
String Comparison Technique Used by Python
had a really hard time getting these answers to work how i needed it to,
but i got this working and its accurate to .01 seconds
from apscheduler.schedulers.background import BackgroundScheduler
sched = BackgroundScheduler()
sched.start()
def myjob():
print('job 1 done at: ' + str(dt.now())[:-3])
dt = datetime.datetime
Future = dt.now() + datetime.timedelta(milliseconds=2000)
job = sched.add_job(myjob, 'date', run_date=Future)
tested accuracy of timing with this code:
at first i did 2 second and 5 second delay, but wanted to test it with a more accurate measurement so i tried again with 2.55 second delay and 5.55 second delay
dt = datetime.datetime
Future = dt.now() + datetime.timedelta(milliseconds=2550)
Future2 = dt.now() + datetime.timedelta(milliseconds=5550)
def myjob1():
print('job 1 done at: ' + str(dt.now())[:-3])
def myjob2():
print('job 2 done at: ' + str(dt.now())[:-3])
print(' current time: ' + str(dt.now())[:-3])
print(' do job 1 at: ' + str(Future)[:-3] + '''
do job 2 at: ''' + str(Future2)[:-3])
job = sched.add_job(myjob1, 'date', run_date=Future)
job2 = sched.add_job(myjob2, 'date', run_date=Future2)
and got these results:
current time: 2020-12-10 19:50:44.632
do job 1 at: 2020-12-10 19:50:47.182
do job 2 at: 2020-12-10 19:50:50.182
job 1 done at: 2020-12-10 19:50:47.184
job 2 done at: 2020-12-10 19:50:50.183
accurate to .002 of a second with 1 test
but i did run a lot of tests and accuracy ranged from .002 to .011
never going under the 2.55 or 5.55 second delay
#everytime you print action_now it will check your current time and tell you should be done
import datetime
current_time = datetime.datetime.now()
current_time.hour
schedule = {
'8':'prep',
'9':'Note review',
'10':'code',
'11':'15 min teabreak ',
'12':'code',
'13':'Lunch Break',
'14':'Test',
'15':'Talk',
'16':'30 min for code ',
'17':'Free',
'18':'Help ',
'19':'watever',
'20':'watever',
'21':'watever',
'22':'watever'
}
action_now = schedule[str(current_time.hour)]

To schedule tasks and stop tasks after some time

Well, I am making this program which will click a link sent on zoom and close zoom at the end of meeting
This is the code
import pyautogui
import time
import pause
import datetime
import schedule
YEAR = 2020
MONTH = 11
DATE = 6
HOUR = 10
MINUTES = 1
SECONDS = 00
now = datetime.datetime.now()
EndTime = now.replace(hour=HOUR, minute=MINUTES, second=SECONDS, microsecond=0)
JustBefore= now.replace(hour=HOUR, minute=MINUTES-1, second=SECONDS, microsecond=0)
def leave_the_meeting():
pyautogui.click(1198, 1072)
time.sleep(3)
pyautogui.click(1443, 998)
time.sleep(1)
pyautogui.click(1398, 933)
def click_the_attendance_link():
pyautogui.click(1665, 674)
time.sleep(9)
I want click_the_attendance_link() to keep functioning over and over again until JustBefore and then stop.
and then I want leave_the_meeting() to start functioning for just one time at EndTime.
What code should I add?
How about this:
def keep_click_attendance_link():
while datetime.datetime.now() < JustBefore:
click_attendance_link()
# Sleep for 60 secs before trying again
time.sleep(60)
while datetime.datetime.now() < Endtime:
# Sleep for 1 sec intervals:
time.sleep(1)
# eventually Leave the meeting at Endtime
leave_the_meeting()

Initial delay whilst looping a function every n seconds in Python 2.7

I would like to loop the function "logger" every second, ideally start and stop at certain times of the day too, however I haven't worked out the best way to do that yet. I've noticed in the log file that there's a delay between the first and second entry when printing the data. How do I solve this problem?
[u'(LON:SXX)'] - [u'14.38'] - [u'3.88M/6.72M'] - 12:12:36
[u'(LON:SXX)'] - [u'14.38'] - [u'3.88M/6.72M'] - 12:12:43
[u'(LON:SXX)'] - [u'14.38'] - [u'3.88M/6.72M'] - 12:12:44
[u'(LON:SXX)'] - [u'14.38'] - [u'3.88M/6.72M'] - 12:12:45
from selenium.webdriver.firefox import webdriver
from datetime import datetime
import time
starttime=time.time()
driver = webdriver.WebDriver()
driver.get('https://www.google.co.uk/finance?q=LON:SXX')
def logger():
with open("log.txt", "a") as f:
# get the current price & time
tme = datetime.now().strftime('%H:%M:%S')
current_price = [price.text for price in driver.find_elements_by_xpath('//*[#id="price-panel"]/div[1]/span') if price.text]
volume = [vol.text for vol in driver.find_elements_by_xpath('/html/body/div[1]/div/div[3]/div[2]/div/div[2]/div/div/div[2]/div[2]/div[1]/div[2]/div[1]/table[1]/tbody/tr[4]/td[2]') if vol.text]
symbol = [sym.text for sym in driver.find_elements_by_xpath('/html/body/div/div/div[3]/div[1]/div/div[2]/div[2]/span') if sym.text]
f.write ("%s - %s - %s - %s \n" % (symbol, current_price, volume, tme))
f.close
while True:
logger()
time.sleep(1.0 - ((time.time() - starttime) % 1.0))
You may choose one of this:
- use your OS crontab,
- use python crontab module
- use a scheduler module
Please see bellow your code example modified to use the python apscheduler module:
https://apscheduler.readthedocs.org/en/latest/
from selenium.webdriver.firefox import webdriver
from datetime import datetime
import time
#to install 'apscheduler' use this command 'pip install apscheduler'
from apscheduler.scheduler import Scheduler
#init the scheduler
sched = Scheduler()
starttime=time.time()
driver = webdriver.WebDriver()
driver.get('https://www.google.co.uk/finance?q=LON:SXX')
#here we are decor the logger function
#sched.interval_schedule(seconds=1)
def logger():
with open("log.txt", "a") as f:
# get the current price & time
tme = datetime.now().strftime('%H:%M:%S')
current_price = [price.text for price in driver.find_elements_by_xpath('//*[#id="price-panel"]/div[1]/span') if price.text]
volume = [vol.text for vol in driver.find_elements_by_xpath('/html/body/div[1]/div/div[3]/div[2]/div/div[2]/div/div/div[2]/div[2]/div[1]/div[2]/div[1]/table[1]/tbody/tr[4]/td[2]') if vol.text]
symbol = [sym.text for sym in driver.find_elements_by_xpath('/html/body/div/div/div[3]/div[1]/div/div[2]/div[2]/span') if sym.text]
f.write ("%s - %s - %s - %s \n" % (symbol, current_price, volume, tme))
f.close
sched.start()

Program to automate software usage

I want to write a program that can:
Open an application. (I successfully executed the application using the subprocess module)
Use the application. (How do I automate a task on that particular software? Is it possible? For example, the software would require me login and python and automatically login with my credentials and proceed to automate my typical usage like opening projects)
Close the application.
from datetime import datetime
import time
import os
import subprocess
os.chdir("../../Desktop/Sublime/Sublime Text 2") #Directory need to adjust to find teamviewer
print "Starting python..."
switch = True
activator1 = True
activator2 = True
startBoolean = True
exitBoolean = True
container = None
def startTimer(startTime , exitTime):
global dateTime
global startBoolean
global exitBoolean
dateTime = datetime.now().strftime('%H%M%S')
print "Current Time: " +dateTime+ "| Start Time: " +startTime +"| Exit Time: "+exitTime
if dateTime >= startTime:
startBoolean = False
print "start boolean: "+ str(startBoolean)
if dateTime >= exitTime:
exitBoolean = False
print "exit boolean: "+ str(exitBoolean)
return [startBoolean,exitBoolean]
def startApplication(startTime):
if dateTime >= startTime:
print "Launching Application..."
process = subprocess.Popen(["./sublime_text"],shell=True) #This is using ubuntu terminal command. Might need to change the command to fits other OS.
def stopApplication(exitTime):
if dateTime >= exitTime:
print "Exiting Application..."
process = subprocess.Popen(["killall sublime_text"],shell=True)
startTime = raw_input("Project Launch Time: ")
exitTime = raw_input("Project Exit time: ")
while switch:
startTimer(startTime , exitTime)
global container
container = startTimer(startTime , exitTime)
if container!=None:
if activator1==True:
if container[0] == False:
print "clear1"
activator1 = False #Cannot activate < 1.
startApplication(startTime)
if activator2==True:
if container[1] == False:
print "clear2"
activator2 = False #Cannot activate < 1.
stopApplication(exitTime)
Hi you can use pyAutoIt
I am giving sample code for Notepad to save it in required location and required path.
import autoit,time
autoit.run("notepad.exe")
autoit.win_wait_active("Untitled - Notepad")
time.sleep(5)
autoit.control_send("Untitled - Notepad", "Edit1", "hello world{!}")
autoit.control_send("Untitled - Notepad", "Edit1", "test-2")
#time.sleep(5)
autoit.win_close("Untitled - Notepad")
autoit.control_click("Notepad", "Button1")
#time.sleep(5)
autoit.win_wait_active("Save As")
#time.sleep(5)
autoit.control_send("Save As", "Edit1","Path-to-save")
autoit.control_send("Save As", "Edit1", "file-name")
autoit.control_click("Save As", "Button1")
pywinauto is also great GUI automation solution on Python.
Example:
from pywinauto import Application
app = Application().start(r"C:\Program Files\Sublime Text 2\sublime_text.exe")
app.untitled_SublimeText2.Wait('ready', timeout=10) # just for possible slow start
app.untitled_SublimeText2.MenuSelect('File->Open file')
app.Open.FilenameEdit.SetText('path to the project')
app.Open.Open.Click()
app.Open.WaitNot('visible') # just to make sure it's closed
main_window = app["project_name - Sublime Text 2"]
# print access names for all available controls on the main window
main_window.PrintControlIdentifiers()
There is also GUI helper SWAPY, pywinauto object inspector and code generator.

Categories