Pregunta

Me escribió un script en Python para procesar algunos datos de archivos CSV. La secuencia de comandos tarda entre 3 a 30 minutos para completarse, dependiendo del tamaño de la CSV.

Ahora quiero poner en una interfaz web para esto, para que pueda cargar los archivos de datos CSV desde cualquier lugar. Escribí una página básica de carga HTTP POST y se utiliza el módulo de Python CGI - pero el guión sólo el tiempo de espera después de algún tiempo.

El script salidas de las cabeceras HTTP en la salida, y salidas de bits de datos después de la iteración en cada línea de la CSV. A modo de ejemplo, esta declaración de impresión activaría cada 30 segundos más o menos.

# at the very top, with the 'import's
print "Content-type: text/html\n\n Processing ... <br />"

# the really long loop.
for currentRecord in csvRecords:
    count = count + 1
    print "On line " + str(count) + " <br />"

I asumió el navegador recibiría las cabeceras, y esperar, ya que sigue recibiendo pequeños trozos de datos. Pero lo que realmente parece suceder es que no recibe ningún dato en absoluto, y los tiempos de espera cuando Error 504 dado un CSV con una gran cantidad de líneas.

Tal vez hay algo de almacenamiento en caché sucediendo en alguna parte? Desde los registros,

[Wed Jan 20 16:59:09 2010] [error] [client ::1] Script timed out before returning headers: datacruncher.py, referer: http://localhost/index.htm
[Wed Jan 20 17:04:09 2010] [warn] [client ::1] Timeout waiting for output from CGI script /Library/WebServer/CGI-Executables/datacruncher.py, referer: http://localhost/index.htm

¿Cuál es la mejor manera de resolver esto, o, ¿no es apropiado para ejecutar este tipo de scripts en un navegador?

Editar Este es un script para mi propio uso - que normalmente la intención de usarlo en mi equipo, pero me pareció una interfaz basada en la web podría ser útil durante el viaje, o por ejemplo, de un teléfono. Además, no hay realmente nada que descarga -. El guión más probable que un correo electrónico un informe al final

¿Fue útil?

Solución

Yo separaría el trabajo de esta manera:

  1. Una URL de la aplicación web que aceptan el archivo CSV publicado. La aplicación web pone el contenido CSV en una cola fuera de línea, por ejemplo, una tabla de base. La respuesta de la aplicación web debe ser un identificador único para el elemento en cola (utilizar una columna de ID de auto-incrementa, por ejemplo). El cliente debe almacenar esta identificación para la parte 3.

  2. Una aplicación de servicio autónomo que las encuestas de la cola para el trabajo, y realiza el procesamiento. Una vez completado el procesamiento, almacenar los resultados en otra tabla de base de datos, utilizando el identificador único como clave.

  3. Resultados Una URL aplicación web que pueden quedar procesados, http://server/getresults/uniqueid/. Si el procesamiento se termina (es decir, el identificador único se encuentra en la tabla de base de datos de resultados), a continuación, devolver los resultados. Si no ha terminado, la respuesta debería ser un código que indica esto. Por ejemplo, un encabezado HTTP personalizado, una respuesta HTTP de estado, cuerpo de la respuesta 'pendiente' o similar.

Otros consejos

He tenido esta situación antes y lo utiliza cronjobs. La secuencia de comandos HTTP que acaba de escribir en una cola de un trabajo a realizar (una base de datos o un archivo en un directorio) y la tarea programada la leería y ejecutar ese trabajo.

Usted probablemente tendrá que hacer un stdout.flush(), ya que el guión no está realmente escrito nada todavía al servidor web hasta que haya escrito el valor de un búfer de página de los datos -. Que no ocurre antes de que el tiempo de espera

Sin embargo, la forma correcta de resolver esto es, como otros sugirieron, para hacer el procesamiento en un tema / proceso separado, y mostrar al usuario una página de auto-refrescado que muestra el estado, con una barra de progreso o algún otro de fantasía visual para evitar que se aburre.

Ver Randal Schwartz es observación de procesos largos a través de CGI . El artículo utiliza Perl, pero la técnica no depende de la lengua.

aquí . Sugiero desove frente a la lentitud del proceso y devolver una barra de progreso basado en Ajax para el usuario. De esta manera el usuario se da el lujo de la interfaz web y usted tiene el lujo de no hay tiempos de espera.

mi humilde opinión la mejor forma sería la de ejecutar un script independiente que actualiza los mensajes algún lugar (archivo plano, base de datos, etc ...). No sé cómo el tenedor de un proceso independiente de Python, así que no puedo dar ningún ejemplo de código.

Para mostrar el progreso en un sitio web implementar una petición AJAX a una página que lee esas actualizaciones de estado y por ejemplo, muestra una buena barra de progreso.

Añadir algo así como setTimeout ( "refreshProgressBar [...]) o meta-actualización para la actualización automática.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top