Tengo un script de Python que hace algunas actualizaciones en mi base de datos.

Los archivos que necesita este script se guardan en un directorio alrededor de las 3AM por algún otro proceso.

Así que voy a programar un trabajo cron para que se ejecute diariamente a las 3AM; pero quiero manejar el caso si el archivo no está disponible exactamente a las 3 AM, podría retrasarse por algún intervalo.

Así que básicamente necesito seguir verificando si el archivo de algún nombre en particular existe cada 5 minutos a partir de las 3AM. Lo intentaré durante aproximadamente 1 hora y me rendiré si no funciona.

¿Cómo puedo lograr este tipo de cosas en Python?

2
user1265125 2 sep. 2014 a las 11:08

5 respuestas

La mejor respuesta

Pruebe algo como esto (necesitará cambiar las declaraciones de impresión para que sean llamadas a funciones si está usando Python 3).

#!/usr/bin/env python

import os
import time

def watch_file( filename, time_limit=3600, check_interval=60 ):
    '''Return true if filename exists, if not keep checking once every check_interval seconds for time_limit seconds.
    time_limit defaults to 1 hour
    check_interval defaults to 1 minute
    '''

    now = time.time()
    last_time = now + time_limit

    while time.time() <= last_time:
        if os.path.exists( filename ):
             return True
        else:
            # Wait for check interval seconds, then check again.
            time.sleep( check_interval )

    return False

if __name__ == '__main__':
    filename = '/the/file/Im/waiting/for.txt'
    time_limit = 3600 # one hour from now.
    check_interval = 60 # seconds between checking for the file.

    if watch_file( filename, time_limit, check_interval ):
        print "File present!"
    else:
        print "File not found after waiting:", time_limit, " seconds!"
3
deadcode 2 sep. 2014 a las 08:09

Eso es lo que primero viene a mi mente, bastante sencillo:

from time import sleep
counter = 0
working = True
while counter < 11 and working:
    try:
        # Open file and do whatever you need
        working = False
    except IOError:
        counter +=1
        sleep(5*60)

Mejor solución

from time import sleep
counter = 0
working = True
while counter < 11 and working:
    if os.path.isfile('path/to/your/file')
        # Open file and do whatever you need
        working = False
    else:
        counter +=1
        sleep(5*60)
0
Pawel Wisniewski 2 sep. 2014 a las 07:16

Para este tipo de tarea, debe usar watchdog una biblioteca para escuchar y monitorear eventos del sistema .

Uno de los eventos que puede monitorear son los eventos del sistema de archivos, a través de FileSystemEventHandler clase, que tiene el método on_created().

Terminará escribiendo un script "envoltorio", puede ejecutarse continuamente. Este script usará watchdog para escuchar en ese directorio en particular. En el momento en que se crea un archivo, se le notificará a este script: deberá verificar si el archivo creado coincide con el patrón del archivo de destino y luego ejecutar su código personalizado.

Afortunadamente, como esta es una tarea común, ya hay un PatternMatchingEventHandler disponible, que hereda de FileSystemEventHandler pero busca archivos que coincidan con un patrón.

Su script de envoltura se convierte en:

from watchdog.observers import Observer  
from watchdog.events import PatternMatchingEventHandler

class FileWatcher(PatternMatchingEventHandler):
    patterns = ["*.dat"] # adjust as required

    def process(self, event):
       # your actual code goes here

       # event.src_path will be the full file path
       # event.event_type will be 'created', 'moved', etc.
       print('{} observed on {}'.format(event.event_type, event.src_path))

    def on_created(self, event):
       self.process(event)

if __name__ == '__main__':
    obs = Observer() # This is what manages running of your code
    obs.schedule(FileWatcher(), path='/the/target/dir')
    obs.start() # Start watching

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        ob.stop()

    obs.join()
3
Burhan Khalid 2 sep. 2014 a las 07:33

En Python puedes verificar si el archivo existe

import os.path
os.path.isfile(filename)

Luego configura su cron para que se ejecute cada 5 minutos desde las 3 a.m.: * / 5 3 * * * /path-to-your/script.py

Puede escribir en un archivo simple para controlar si ya leyó los datos del archivo o no (o una base de datos si ya está usando uno)

0
danielfranca 2 sep. 2014 a las 07:19

¡Puedes usar Twisted, y es un reactor, es mucho mejor que un bucle infinito! También puede usar reactor.callLater (myTime, myFunction), y cuando se llama a myFunction puede ajustar myTime y agregar otra devolución de llamada con la misma API callLater ().

-1
e-nouri 2 sep. 2014 a las 07:24