Reputation: 201
This is part of a python program under windows environment. I am trying to do the following: from an html, I want to create a pdf and then open it:
#create the pdf os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name)) #open the current pdf os.system("start %s%s" %(output_directory, pdf_document_name))
The issue is that sometimes the script of creating the pdf is slower, so I get an error from the terminal saying that there is no file with such name.
I want to ask whether it's possible to call the pdf open only when the creation is successful and finished. I know how to do it by invoking a time.sleep() , but I think that's not too professional.
Many thanks,
D
Upvotes: 0
Views: 123
Reputation: 6352
Regardless of the method you use to execute shell commands (subprocess, os.system, etc.), you should verify that your file exists before trying to open it. You can then instrument the delay into the File-Exists-Else-Wait-Repeat loop before trying to open it. You can do this using os.path.exists():
#create the pdf
os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name))
#loop until pdf exists, but add some timer to avoid endless repetition
maxiterations = 60
exists = False
for i in range(maxiterations):
if os.path.exists(os.path.join(output_directory, pdf_document_name)):
exists = True
break;
time.sleep(1)
#open the current pdf
if exists:
os.system("start %s%s" %(output_directory, pdf_document_name))
else:
print 'Could not find file %s to open' % os.path.join(output_directory, pdf_document_name)
The other thing to look at is that this introduces a security vulnerability, as the file could change in the time that passed between your verifying it and opening it (e.g. it could have been replaced with malicious code). Another way to handle this is to try to open it within a try... except... block, but this doesn't really resolve the security issue (the file could have been replaced between creation and your attempt at opening it anyway).
Upvotes: 2
Reputation: 151077
I don't think there's anything "unprofessional" about using time.sleep()
. Actually the thing that's least professional (or least Pythonic, anyway) about the solution you suggest is the use of os.system
. Use a function from the subprocess
module instead. In this case, you can use subprocess.call
, which waits for the program to exit before continuing. So for example if you do this in the interactive interpreter:
import subprocess, shlex
subprocess.call(shlex.split('sleep 5'))
You'll see that Python waits five seconds for sleep
to finish before continuing. (It then returns the exit code.) Shlex simply splits a command line into a list of arguments for consumption by call
or by several other functions and classes provided by subprocess
.
>>> shlex.split("start wkhtmltopdf.exe result.html %s%s" %('out_dir/', 'pdf_name'))
['start', 'wkhtmltopdf.exe', 'result.html', 'out_dir/pdf_name']
Upvotes: 1