¿Cómo descargar archivos grandes en python a través de ftp (con monitoreo y reconectar)?

ACTUALIZACIÓN # 1

El código en la pregunta funciona bastante bien para una conexión estable (como una red local o intranet).

ACTUALIZACIÓN # 2

Implementé la clase FTPClient con ftplib que puede:

  1. monitorear un progreso de descarga
  2. volver a conectar en caso de tiempo de espera o desconectar
  3. Hace varios bashs para descargar el archivo.
  4. muestra la velocidad de descarga actual.

Después de la reconexión, continúa el proceso de descarga desde el punto de desconexión (si el servidor FTP lo admite). Para más detalles vea mi respuesta a continuación.


Pregunta

Tengo que implementar la tarea en python que diariamente descarga un montón de archivos grandes (0.3-1.5Gb por archivo * 200-300 archivos) a través de FTP y luego hace un procesamiento con los archivos. Lo hice a través de ftplib. Pero de vez en cuando se cuelga y no se puede completar la descarga de algunos archivos. Para solucionar el problema, comencé a jugar con la configuración de KEEPALIVE, pero todavía no he recibido un buen resultado.

 with closing(ftplib.FTP()) as ftp: try: ftp.connect(self.host, self.port, 30*60) #30 mins timeout # print ftp.getwelcome() ftp.login(self.login, self.passwd) ftp.set_pasv(True) ftp.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 75) ftp.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60) with open(local_filename, 'w+b') as f: res = ftp.retrbinary('RETR %s' % orig_filename, f.write) if not res.startswith('226 Transfer complete'): logging.error('Downloaded of file {0} is not compile.'.format(orig_filename)) os.remove(local_filename) return None os.rename(local_filename, self.storage + filename + file_ext) ftp.rename(orig_filename, orig_filename + '.copied') return filename + file_ext except: logging.exception('Error during download from FTP') 

Detalles

  • Por lo general, se tarda 7-15 minutos para descargar un archivo.
  • El servidor FTP siempre me muestra en los registros que los archivos están completamente descargados, pero la parte del cliente se cuelga. No siempre, sino de vez en cuando.

Preguntas

  • ¿Puede ser por una desconexión?
  • Cómo implementar un monitor para el proceso de descarga y volver a conectarlo en caso de que esté desconectado

Como no pude encontrar ninguna buena sugerencia o ejemplo de código, implementé mi propia solución. Muchas gracias a la comunidad de Stackoverflow por algunas ideas que utilicé en mi código. Puse el código en GitHub ( pyFTPclient ) debido al tamaño del código (~ 120 líneas).

Probé la solución en una red de mala calidad (incluye internet móvil 3G) y funcionó bien para mí. Pero por supuesto puede tener algunos errores.

Apreciaré cualquier comentario o sugerencia. Gracias de antemano.