Is it possible make this .py script time out every 20 minutes and auto run again by it self?

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)

Upvotes: 0

Views: 298

Answers (1)

Arount
Arount

Reputation: 10403

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.

Upvotes: 1

Related Questions