Scheduling a job in Python - python

I wish to schedule a python script for every 30 minutes. I am currently using the Timer to run the python script but it is not working precisely. I am using Linux. This code works fine on windows but is not working correctly on Linux. It should be triggered after half an hour but it gets triggered within a minute.
from datetime import datetime, timedelta
from threading import Timer
j=1
while True :
x=datetime.today()
y = x + timedelta(minutes=10*j)
print(y)
delta_t=y-x
secs=delta_t.seconds + 1
def hello_world():
print ("hello world")
print("yes)")
t = Timer(secs, hello_world)
t.start()
j=j+1`
Can anyone point out the mistake in above code or suggest an alternative to run the python script in linux after every 30 minutes?
Thank you

You could use Python’s schedule library.
import schedule
def hello_world():
print ("hello world")
print("yes)")
schedule.every(30).minutes.do(hello_world)
while True:
# Checks whether a scheduled task
# is pending to run or not
schedule.run_pending()
Further information: https://www.geeksforgeeks.org/python-schedule-library/

Related

How can I run my code at a specific time? [duplicate]

This question already has answers here:
How do I get a Cron like scheduler in Python?
(9 answers)
Closed 1 year ago.
I am developing a software with python. And I want my code to run at certain hours. It will run once every 5 minutes without a break. But I want it to work exactly at certain hours and minutes. For example, such as 20:00, 20:05, 20:10...
I used time.sleep(300) but if for example 5 seconds passes after my program runs, it starts to delay 5 seconds in each run and for example it starts running 1 minute late after 12 runs. For example, it should work at 20:05, but it starts at 20:06.
How can I provide this?
You can use schedule module
import schedule
import time
from datetime import datetime
now = datetime.now()
def omghi():
print("omg hi there xD")
schedule.every(5).minutes.do(omghi)
while True:
schedule.run_pending()
time.sleep(1)
There is a useful model for that case.
It is an external model, you have to download it using pip and it is called
schedule
https://pypi.org/project/schedule/ - here you can see all the details.
I believe that using timed threads works the best with what you want. This excellent answer uses threading.Timer from the library threading as follows:
import threading
def printit():
threading.Timer(5.0, printit).start()
print "Hello, World!"
printit()
Thank you very much for the answers. But this is how I handled it and I wanted to share it with you :)
import time
from datetime import datetime
while True:
now = datetime.now()
if (now.minute % 5) == 0 and now.second == 0:
print("Fire!")
time.sleep(1)

schedule a python script to run every hour

I am trying to write a script that executes every hour
but, when I run it... it takes an hour to run the job for the first time and then, it starts running like every 5 seconds
I don't understand what am I doing wrong here
from apscheduler.schedulers.blocking import BlockingScheduler
def job():
print('excuting job')
scheduler = BlockingScheduler()
scheduler.add_job(job, 'interval', hours = 1)
scheduler.start()
this is another code that I have used, but it's the same result
schedule.every().hour.do(job)
while True:
schedule.run_pending()
time.sleep(20)
Don't do it in python.
Make a file called exehour.bat with this (assuming you're using Windows):
#echo off
cd DIRECTORY-OF-FILE
:loop
timeout 3600
FILE-NAME
goto loop
So this will execute a file every 1 hour when you run it
Or if you need it in python
import time
def runhour():
#YOUR PYTHON CODE GOES UNDERNEATH HERE
#
time.sleep(3600)
Might have something to do within your def, like a rogue brake or other bad while loop or sleep timer. Maybe the checking job timer not being short enough is affecting something as well?
import schedule # I'm not sure about the BlockingScheduler import but this one works for me
import time # Hate how we need an import for this and it's not built into python....
def job():
print('executing job')
# Run your job on first boot without the scheduler
job()
# Then setup the schedule to be used from now on
schedule.every().hour.do(job)
# Check every second if we can do our job yet or not
# Bonus heartbeat . so you know the while loop is running and not crashed.
while True:
schedule.run_pending()
print(".", end="", flush=True)
time.sleep(1) # seconds
If it runs our job() then gets stuck, boot loops or crashes then its in your job def.
if it runs fine the first time, sets up the schedule fine but then gets stuck with executing the schedule then I don't really have any ideas without seeing more of the job() def..
for shits and giggles you could pip uninstall and reinstall schedule again and see if that helps idk..

Best way to implement trial period or expire time

I want to show off some of my work, but i don't want it to be kept forever.
I've tried this trial period that checks on launch if date has past.
from datetime import datetime, timedelta
def check_trial():
trial_start = "2019-09-03"
trial_end = datetime.strptime(trial_start, '%Y-%m-%d') + timedelta(days=5)
today = datetime.now()
if today > trial_end:
print("Trial Expired")
os._exit()
def main():
print("running")
check_trial()
main()
Im scared if they just change their computer date then this wont run. What should be done to protect against that?
Not sure if this completes your requirement but here is an alternate method using signal module in python. Let us suppose that run() function runs your application and you want it to run for 10 mins.
import signal
signal.alarm(600)
run()
signal.alarm(0)
This will simply run your run() function till 600 seconds and if the function doesn't stop execution it will forcefully break the execution of the function.

How do I create a scheduled task using Python Win32com that runs every 5 seconds?

I am trying to create a scheduled task in Python using Win32com. I am able to create a daily trigger. However, I cannot find a way to create a trigger every 5 seconds or every minute for that matter. Does anybody have any pointers on how to do that?
As said in a comment, if you want to do stuff with this frequency you are better off just having your program run forever and do its own scheduling.
In a similar fashion to #Barmak Shemirani's answer, but without spawning threads:
import time
def screenshot():
# do your screenshot...
interval = 5.
target_time = time.monotonic() + interval
while True:
screenshot()
delay = target_time - time.monotonic()
if delay > 0.:
time.sleep(delay)
target_time += interval
or, if your screenshot is fast enough and you don't really care about precise timing:
while True:
screenshot()
time.sleep(interval)
If you want this to run from the system startup, you'll have to make it a service, and change the exit condition accordingly.
pywin32 is not required to create schedule or timer. Use the following:
import threading
def screenshot():
#pywin32 code here
print ("Test")
def starttimer():
threading.Timer(1.0, starttimer).start()
screenshot()
starttimer()
Use pywin32 for taking screenshot etc.

Trigger a Python function exactly on the minute

I have a function that I want to trigger at every turn of the minute — at 00 seconds. It fires off a packet over the air to a dumb display that will be mounted on the wall.
I know I can brute force it with a while loop but that seems a bit harsh.
I have tried using sched but that ends up adding a second every minute.
What are my options?
You might try APScheduler, a cron-style scheduler module for Python.
From their examples:
from apscheduler.scheduler import Scheduler
# Start the scheduler
sched = Scheduler()
sched.start()
def job_function():
print "Hello World"
sched.add_cron_job(job_function, second=0)
will run job_function every minute.
What if you measured how long it took your code to execute, and subtracted that from a sleep time of 60?
import time
while True:
timeBegin = time.time()
CODE(.....)
timeEnd = time.time()
timeElapsed = timeEnd - timeBegin
time.sleep(60-timeElapsed)
The simplest solution would be to register a timeout with the operating system to expire when you want it to.
Now there are quite a few ways to do so with a blocking instruction and the best option depends on your implementation. Simplest way would be to use time.sleep():
import time
current_time = time.time()
time_to_sleep = 60 - (current_time % 60)
time.sleep(time_to_sleep)
This way you take the current time and calculate the amount of time you need to sleep (in seconds). Not millisecond accurate but close enough.
APScheduler is the correct approach. The syntax has changed since the original answer, however.
As of APScheduler 3.3.1:
def fn():
print("Hello, world")
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()
scheduler.start()
scheduler.add_job(fn, trigger='cron', second=0)
You can try Threading.Timer
See this Example
from threading import Timer
def job_function():
Timer(60, job_function).start ()
print("Running job_funtion")
It will print "Running job_function" every Minute
Edit:
If we are critical about the time at which it should run
from threading import Timer
from time import time
def job_function():
Timer(int(time()/60)*60+60 - time(), job_function).start ()
print("Running job_funtion")
It will run exactly at 0th second of every minute.
The syntax has been changed, so in APScheduler of version 3.6.3 (Released: Nov 5, 2019) use the following snippet:
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
def fn():
print('Hello, world!')
sched = BlockingScheduler()
# Execute fn() at the start of each minute.
sched.add_job(fn, trigger=CronTrigger(second=00))
sched.start()
The Python time module is usually what I use for events like this. It has a method called sleep(t), where t equals the time in seconds you want to delay.
Combined with a while loop, you can get what you're looking for:
import time
while condition:
time.sleep(60)
f(x)
May use this example:
def do():
print("do do bi do")
while True:
alert_minutes= [15,30,45,0]
now=time.localtime(time.time())
if now.tm_min in alert_minutes:
do()
time.sleep(60)
you could use a while loop and sleep to not eat up the processor too much

Categories