¿Cómo lanzar un subproceso pdftk en wsgi?

Necesito iniciar un proceso pdftk mientras sirvo una solicitud web en Django y esperar a que termine. Mi código pdftk actual se ve así:

proc = subprocess.Popen(["/usr/bin/pdftk", "/tmp/infile1.pdf", "/tmp/infile2.pdf", "cat", "output", "/tmp/outfile.pdf"]) proc.communicate() 

Esto funciona bien, siempre y cuando lo esté ejecutando bajo el servidor dev (ejecutando como usuario www-data ). Pero tan pronto como cambio a mod_wsgi, sin cambiar nada más, el código se cuelga en proc.communicate() , y “outfile.pdf” se deja como un identificador de archivo abierto de longitud cero.

He intentado varias variantes de la invocación de subproceso (así como también el sistema antiguo os.system): establecer stdin / stdout / stderr en PIPE o en varios manejadores de archivos no cambia nada. El uso de “shell = True” evita que proc.communicate() se bloquee, pero pdftk no puede crear el archivo de salida, tanto en devserver como en mod_wsgi. Esta discusión parece indicar que podría haber algún vudú más profundo con señales del sistema operativo y pdftk que no entiendo.

¿Hay alguna solución para que una llamada de subproceso como esta funcione correctamente bajo wsgi? Evito usar PyPDF para combinar archivos pdf, porque tengo que combinar un número suficientemente grande de archivos (varios cientos) que se queda sin memoria (PyPDF necesita mantener todos los archivos PDF de origen abiertos en la memoria al combinarlos).

Estoy haciendo esto bajo Ubuntu reciente, pythons 2.6 y 2.7.

Pruebe con las rutas absolutas del sistema de archivos para ingresar y enviar archivos. El directorio de trabajo actual bajo Apache no será el mismo directorio que el servidor de ejecución y podría ser cualquier cosa.


Segundo bash tras eliminar lo obvio.

El progtwig pdftk es un progtwig Java que se basa en poder generar / recibir señales SIGPWR para activar la recolección de basura o realizar otras acciones. El problema es que en Apache / mod_wsgi en modo daemon, las señales se bloquean dentro de los subprocesos del manejador de solicitudes para garantizar que solo sean recibidas por el subproceso principal en busca de eventos desencadenantes de cierre del proceso. Cuando está ejecutando el proceso para ejecutar pdftk, desafortunadamente está heredando la máscara de caracteres bloqueada del hilo del controlador de solicitudes. La consecuencia de esto es que impide el funcionamiento del proceso de recolección de basura de Java y hace que pdftk falle de formas extrañas.

La única solución para esto es usar el apio y hacer que la parte delantera envíe un trabajo a la cola de apio para que aplaste y luego ejecute pdftk. Debido a que esto se hace a partir de un proceso creado distinto de Apache, no tendrá este problema.

Para más detalles sangrientos, Google para mod_wsgi y pdftk, en particular en Grupos de Google.

http://groups.google.com/group/modwsgi/search?group=modwsgi&q=pdftk&qt_g=Search+this+group

Actualización: fusionando dos PDFs usando Pdftk en Python 3:

Han pasado varios años desde que esta pregunta fue publicada. (2011). El cartel original decía que os.system no funcionaba para ellos cuando ejecutaban versiones anteriores de python:

  • Python 2.6 y
  • Python 2.7

En Python 3.4 , os.system trabajó para mí:

  • importación OS
  • os.system (“pdftk” + template_file + “fill_form” + data_file + “output” + export_file )

Python 3.5 agrega subprocess.run

  • subprocess.run (“pdftk” + template_file + “fill_form” + data_file + “output” + export_file )

  • Utilicé rutas absolutas para mis archivos:

    • template_file = “/ var / www / myproject / static /”

Ejecuté esto con Django 1.10, y la salida resultante se guardó en el archivo export_file .

Cómo combinar dos archivos PDF y mostrar la salida de PDF:

 from django.http import HttpResponse, HttpResponseNotFound from django.core.files.storage import FileSystemStorage from fdfgen import forge_fdf import os template_file = = "/var/www/myproject/template.pdf" data_file = "/var/www/myproject/data.fdf" export_file ="/var/www/myproject/pdf_output.pdf" fields = {} fields['organization_name'] = organization_name fields['address_line_1'] = address_line_1 fields['request_date'] = request_date fields['amount'] = amount field_list = [(field, fields[field]) for field in fields] fdf = forge_fdf("",field_list,[],[],[]) fdf_file = open(data_file,"wb") fdf_file.write(fdf) fdf_file.close() os.system("pdftk " + template_file + " fill_form " + data_file + " output " + export_file) time.sleep(1) fs = FileSystemStorage() if fs.exists(export_file): with fs.open(export_file) as pdf: return HttpResponse(pdf, content_type='application/pdf; charset=utf-8') else: return HttpResponseNotFound('The requested pdf was not found in our server.') 

Bibliotecas

  • pdftk
  • fdfgen