1

I have a python flask application where I cache some data in memory when app.py runs.

There's a function call like this:

cache_data()

I want this function to be ran once every night. Is there a way I can schedule the script to rerun by itself or just the function to be called whenever the date of current_date has changed?

if __name__ == "__main__":
    port = 80
    os.system("open http://localhost:{0}".format(port))

    app.debug = True # Turn False later
    app.run(host='0.0.0.0', port=port)
user3422637
  • 3,967
  • 17
  • 49
  • 72
  • If you're on UNIX, consider writing a cron job. – nneonneo May 07 '15 at 19:12
  • On Windows, I can schedule via a windows task scheduler. Is it going to stop the execution of the app.py that was already running before trying to run it again? – user3422637 May 07 '15 at 19:14
  • No, it should create an entirely new process (instance). To generalize on the first comment, this largely depends on where your app is hosted -- in otherwords, more about the OS, not Flask per se. – Two-Bit Alchemist May 07 '15 at 19:16
  • I don't want it to create a new instance. Isn't it possible to reload the same instance or just recall the function at an interval? – user3422637 May 07 '15 at 19:18

4 Answers4

0

You could put a queue system in with Python Rq.

nadermx
  • 2,596
  • 7
  • 31
  • 66
0

You could spawn a thread in app.py that calls a /cache call and sleeps for 24 hours.

Adam Matan
  • 128,757
  • 147
  • 397
  • 562
0

You could do something like this:

if __name__ == "__main__":

    when_to_run = # Set first run datetime
    time_to_wait = when_to_run - datetime.now()

    while True:
        time.sleep(time_to_wait.seconds)
        # run your stuff here

        when_to_run = # Set next run datetime
        time_to_wait = when_to_run - datetime.now()

Say you want this to run every day at 10 AM, you set when_to_run to today at 10 AM or if that's already in the past, tomorrow at 10 AM, and add a day with timedelta in the loop. If you just set to sleep for 24 hours, the time of execution will get delayed by the time it took to execute it each time.

Example:

Run stuff every day at 1 PM:

if __name__ == "__main__":

    when_to_run = datetime.now().replace(hour=13, minute=0, second=0, microsecond=0)
    if datetime.now() > when_to_run:
        # First run is tomorrow
        when_to_run += timedelta(days=1)
    time_to_wait = when_to_run - datetime.now()

    while True:
        time.sleep(time_to_wait.seconds)

        # run your stuff here
        stuff.run()

        when_to_run += timedelta(days=1)
        time_to_wait = when_to_run - datetime.now()
Tomás Mena
  • 208
  • 2
  • 7
  • Can you please modify the answer with a sample datetime value . Let's say if we had to run it at Current_date 1:00 PM – user3422637 May 08 '15 at 18:25
0

I'm not sure if this is correct for your specific use case, but you could cache the result of the function for a given period of time:

import functools
from datetime import datetime, timedelta

def cache(delta):
    if not hasattr(cache, 'results'):
        cache.results = {}
        cache.timeout = {}

    def decorator(function):
        @functools.wraps(function)
        def inner(*args, **kwargs):
            key = repr((function, args, kwargs))

            if key not in cache.results or cache.timeout[key] <= datetime.now():
                cache.results[key] = function(*args, **kwargs)
                cache.timeout[key] = datetime.now() + delta

            return cache.results[key]

        return inner

    return decorator

@cache(timedelta(seconds=2))
def f():
    return datetime.now()

Calling f() twice within the same 2 second interval will return the same result.

Blender
  • 289,723
  • 53
  • 439
  • 496
  • I don't understand this very well. It is quite complicated. Where do I place my app.run() now? Can you help me modify the code provided in the question to incorporate scheduled reloads? – user3422637 May 08 '15 at 18:38
  • Well, your sample code *is* just `app.run()`. Can you add more detail to your question? – Blender May 09 '15 at 01:17