Let's say I have the following python program:
def Is_it_Midnight(args):
print("It's midnight!")
and I want the .py script to execute itself when a certain condition is true, say "when the clock strikes midnight".
Is that possible?
You can use the threading library to have the routine restart itself periodically. In this specific case, every 86400 seconds (1 day).
modify your code to:
import threading
import time
def Is_it_Midnight(args):
threading.Timer(86400, Is_it_Midnight).start()
print("It's midnight!")
Then you just have to get the code to run at midnight the first time. Something like:
seconds = time.time()
since_midnight = seconds % 86400
time.sleep(86400-since_midnight)
Is_it_Midnight()
I'm not sure how you'd handle passing args into the routine.
There are a few options to run a script.
My favorite is to create myscript.py and within it define a function, let's say def alarm()... and then in your main script:
import myscript
And when the time comes, call:
myscript.alar()
There is another way, you can call execfile("myscript.py")
Related
I want to execute a file at a specific time as I won't be around at that time to execute it.
I was thinking if there is a way in which I can write some code in another file, that will start that code, and leave it running so that it can start that code at that specific time - Maybe using os and time, or command line.
How about something like:
import time, subprocess, sys
time.sleep(3600) # wait 1 hour
subprocess.call([sys.executable, 'another-script.py'])
You can use Python's builtin sched module:
import sched, time
def action():
print("hello world")
# Set up scheduler
s = sched.scheduler(time.localtime, time.sleep)
# Schedule when you want the action to occur
s.enterabs(time.strptime('Tue March 15 15:55:17 2020'), 0, action)
# Block until the action has been run
s.run()
Is it possible make this .py script time out every 20 minutes and auto run again by it self?
Currently I'm using crontab to rerun it every 20 minutes but the thing is it's running multiple .py sometime and not actually rerunning the program. I just want it to rerun every 20 minutes not rerun another instance of it every 20 minutes.
#!/usr/bin/env python
from TwitterFollowBot import TwitterBot
my_bot = TwitterBot("/home/TwitterFollowBot/config.txt")
my_bot.sync_follows()
my_bot.auto_unfollow_nonfollowers()
my_bot.auto_rt("#RtwtKing", count=2000)
my_bot.auto_rt("#ShoutGamers", count=2000)
You have several ways to do this.
If you want to do it only with Python you can:
Use threads, it will work pretty well, but it's not really what threads are designed for.
Use Daemon (good example here)
Do a Python wrapper which will loop forever and call you script when needed. It's less clean, but less overkill too.
Example of the wrapper solution:
The goal is to create a new python script which will handle timer and so execute your Twitter code when needed.
1. Update your current code to encapsulate it in a method
let's say your current file is named core.py
core.py:
from datetime import datetime
from TwitterFollowBot import TwitterBot
def get_feed():
print "({}) LOG: get_feed starting".format(datetime.now())
my_bot = TwitterBot("/home/TwitterFollowBot/config.txt")
my_bot.sync_follows()
my_bot.auto_unfollow_nonfollowers()
my_bot.auto_rt("#RtwtKing", count=2000)
my_bot.auto_rt("#ShoutGamers", count=2000)
This just make your code in a function and add a logging line which print current time when function is executed.
2. Make a wrapper which handle timer and call your twitter code
wrapper.py:
import time
from datetime import datetime
# Import your twitter code, so you can use it by calling 'get_feed()'
from core import get_feed
# Define constants here because it's easier to find it on top of file
# Delta between the last call and the next one, bascially time between two calls: 20 minutes
DELTA = 20 * 60
# Time your wrapper will take between each verification: 5 minutes
SLEEP_TIME = 5 * 60
# Initialize timer and call for the first time your method
# last_run will store timestamp of the last time you called get_feed()
last_run = time.time()
get_feed()
# Start an inifinite loop
while True:
# Compute delta since last call
# last_run_delta will store the time in seconds between last call and now
last_run_delta = time.time() - last_run
# If last_run_delta is upper than DELTA so the number of seconds you want to separate two calls is reached.
if last_run_delta >= DELTA:
# Because time is reached you want to run again your code and reset timer to can handle next call
last_run = time.time()
get_feed()
# If you have not reach delta time yet, you want to sleep to avoid stack overflow and because you don't need to check each microseconds
else:
time.sleep(SLEEP_TIME)
Ouput with DELTA = 10 and SLEEP_TIME = 5 (core.py is called every 10 seconds and check is done each 5 seconds):
(2016-11-29 10:43:07.405750) LOG: get_feed starting
(2016-11-29 10:43:17.414629) LOG: get_feed starting
(2016-11-29 10:43:27.422033) LOG: get_feed starting
(2016-11-29 10:43:37.430698) LOG: get_feed starting
(2016-11-29 10:43:47.436595) LOG: get_feed starting
The only real good point with this method is you can't launch same process two times at once. Because it's not asynchronous, get_feed can't be called twice, but if get_feed take more time than SLEEP_TIME or DELTA you will miss some calls and so do not run it each 20min.
Last thing, because you are importing core.py in wrapper.py you have to create a __init__.py file in the same folder than the two others files. (/path/to/project/ should contains __init__.py (empty), core.py and wrapper.py).
The real good way will is to create a daemon, but it require more skills.
Looked at all the similar questions but unable to get the syntax correct. I have a python script that runs a single command at the moment. What I need to do is have this command repeat itself over and over...indefinitely...at certain intervals. Here is my script:
#! /usr/bin/env python
import sys
from scapy.all import sr1,IP,ICMP,UDP,send,DNS,DNSQR
p=send(IP(dst="192.168.1.128")/UDP()/DNS(rd=1,qd=DNSQR(qname="domain.com")), count=100 )
if p:
p.show()
This runs fine from the command line. However I need it to repeat every 30 seconds or 1 minute. How would I tell it to do that inside the script? I know I can probably set this up as a cron job but I'd like to know how to script it. Thanks!
You can use the time module's sleep() method inside a while True loop.
#! /usr/bin/env python
import sys
import time
from scapy.all import sr1,IP,ICMP,UDP,send,DNS,DNSQR
while True:
p=send(IP(dst="192.168.1.128")/UDP()/DNS(rd=1,qd=DNSQR(qname="domain.com")), count=100)
if p:
p.show()
time.sleep(60) # sleep for one minute
you can put a infinite while loop and add sleep of 30 seconds in every iteration. The other option could be set the script into cron job.
The advisable option is cronjob as in case python script exit due to any exception or error, cron can re-run it in next cycle.
Create a while loop. True is always True, so the loop keeps running. After the commands wait a while.
#! /usr/bin/env python
import sys, time
interval = 60 #1 minute
from scapy.all import sr1,IP,ICMP,UDP,send,DNS,DNSQR
while True:
p=send(IP(dst="192.168.1.128")/UDP()/DNS(rd=1,qd=DNSQR(qname="domain.com")), count=100 )
if p:
p.show()
time.sleep(interval)
The infinite loop with the sleep as mentioned in the above answers is the simplest way to do what you want. However, if you do that, your program becomes a daemon which you have to monitor and make sure is running. This has some costs that you should be aware of up front.
I would prefer to use cron to run it every n minutes or something similar. Yet another way, which is similar to the inifinite loop is to the use the python sched module to run a mini cron like system inside your program.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the best way to repeatedly execute a function every x seconds in Python?
Hi so here is the code I have:
client = myclient(info1,info2)
sellor()
Contractor()
It works perfectly but what I would like to do is to make python launch that code every 60 seconds indefinitely...
I don't actually understand how I have to put the code together with the time loop
Any help is appreciated
Thank's
If the 60 seconds ignores the time it takes to execute your code):
from time import sleep
while True:
sleep(60)
# your code here
but if the 60 seconds takes into account the time it takes to execute your code:
from time import sleep
from os import fork
while True:
sleep(60)
fork() # create child process
# your code here
Use the sleep method. Just create a loop (while, for, whatever) and sleep for 60 secs every iteration.
import time
while True:
client = myclient(info1,info2)
sellor()
Contractor()
time.sleep(10)
hope it works,all the best mate
import time
repeat_time = 3.0
while True:
start_time = time.time()
# Your code goes here
time.sleep(max(repeat_time - (time.time() - start_time), 0.0))
And your code will be executed exactly every "repeat_time"
You could use sleep as already mentioned. But because there may be a variable amount of time needed for your own functions to run, this wouldn't necessarily mean your functions are run every 60 seconds.
If it was important that the period between each start of your functions is closer to 60 seconds, you could use time. I haven't tried this but something like
import time
while True:
# Get the current time
startTime = time.time()
# Your functions
client = myclient(info1,info2)
sellor()
Contractor()
delay = True
while delay:
if time.time() - startTime > 60:
delay = False # Break the delay
You might also think of just scheduling the task through windows scheduler. The benefit here would end the script once run and then execute the script again after scheduled interval. In the second approach it seems that the script instance process would continually run and only use the sleep function to do nothing for the specified time. I take it this way if the scripts fails at any instance you might have to keep a check to restart the script. While as a scheduled activity the script will be executed in any case at that specified intervals.
You might also not want the process thread to be kept running for the python script executed. I will research on this and you might get to hear form our other folks in the mean while.
Regards,
Harshal
I'm working on a python script that needs to run between two given times. I'm required to use the build in sched module as this script needs to be able to run directly on any machine that has python 2.7 as to reduce configuration time. (SO CRON IS NOT AN OPTION)
A few variables define the settings for the time to run, here set_timer_start=0600 and set_timer_end=0900 are written in HHMM. I'm able to stop the script at the right time.
I don't know exactly how sched works (the python doc page doesn't make to much sense to me), but as far as I understand It runs at a date/time (epoch) while I only want it to run at a given time (HHMM).
Can anyone give me an example (or link) on how to use the scheduler and perhaps calculate the next run date/time?
If I got your requirements right, what you need is probably a loop, that will re-enter a task in the queue every time it will be executed. Something along the lines of:
# This code assumes you have created a function called "func"
# that returns the time at which the next execution should happen.
s = sched.scheduler(time.time, time.sleep)
while True:
if not s.queue(): # Return True if there are no events scheduled
time_next_run = func()
s.enterabs(time_next_run, 1, <task_to_schedule_here>, <args_for_the_task>)
else:
time.sleep(1800) # Minimum interval between task executions
However, using the scheduler is - IMO - overkilling. Using datetime objects could suffice, for example a basic implementation would look like:
from datetime import datetime as dt
while True:
if dt.now().hour in range(start, stop): #start, stop are integers (eg: 6, 9)
# call to your scheduled task goes here
time.sleep(60) # Minimum interval between task executions
else:
time.sleep(10) # The else clause is not necessary but would prevent the program to keep the CPU busy.
HTH!