I was tackling the same issue in a project I had previously worked on, and instead of piping the output, I created temporary files in a temporary folder, since I was worried about handling the intermediate files LaTeX produces. This is the code I used (note that it's a few years old, from when I was still new to Python/Django; I'm sure I could come up with something better if I was writing this today, but this definitely worked for me):
import os
from subprocess import call
from tempfile import mkdtemp, mkstemp
from django.template.loader import render_to_string
# In a temporary folder, make a temporary file
tmp_folder = mkdtemp()
os.chdir(tmp_folder)
texfile, texfilename = mkstemp(dir=tmp_folder)
# Pass the TeX template through Django templating engine and into the temp file
os.write(texfile, render_to_string('tex/base.tex', {'var': 'whatever'}))
os.close(texfile)
# Compile the TeX file with PDFLaTeX
call(['pdflatex', texfilename])
# Move resulting PDF to a more permanent location
os.rename(texfilename + '.pdf', dest_folder)
# Remove intermediate files
os.remove(texfilename)
os.remove(texfilename + '.aux')
os.remove(texfilename + '.log')
os.rmdir(tmp_folder)
return os.path.join(dest_folder, texfilename + '.pdf')
The dest_folder
variable is usually set to somewhere in the media directory, so that the PDF can then be served statically. The value returned is the path to the file on disk. The logic of what its URL would be is handled by whatever function sets the dest_folder
.