You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'd like to add the ability to pass in a file-like object instead of a file name for writing to.
Before I start I have some questions:
currently if the output_path paramater of the API calls is False the stdout of wkhtmltopdf is send to the stdout of the python process. Correct?
I'm curious what the use case is for this. It doesn't seem to be a useful feature in a library - is it for debugging?
Keeping this feature complicates support for file-like objects - would you object to me removing it?
subprocess.Popen objects are used for ipc. However the communicate method is only called if self.source.isString() or (self.source.isFile() and self.css) (refactoring the logic slightly).
Why is this? I am guessing that when the source is a url we don't want to block on wkhtmltopdf blocking on network. But what about the case when self.source.isFile() and not self.css ?
what about this block:
if '--quiet' not in args:
while True:
if result.poll() is not None:
break
out = result.stdout.read(1).decode('utf-8')
if out != '':
sys.stdout.write(out)
sys.stdout.flush()
why have you done things this way? I'm guessing that you're only reading a piece at a time so that output will appear on the python processes' stdout as it is produced by wkhtmltopdf .
Also there will only be something produced here when wkhtmltopdf is passed '-' as an output file, right?
For now output of wkhtmltopdf always goes to stdout, except when you specify --quiet option. Currently if output_path evaluates to False it will append '-' to the end of command ( in command method ). If '-' is at the end of command wkhtmltopdf will pass generated PDF to stdout ( can be used for piping :) ). It is not used in pdfkit at the moment, so this is my mistake for not checking output_path for valid input. So, you can change this behaviour but dont forget to run tests because it can break some of them.
Moving to communicate: if we use from_string API call we need to pass our input string to stdin of wkhtmltopdf ( wkhtmltopdf requirement ). We dont need to pass something to stdin when using from_file or from_url, except one case: self.source.isFile() and self.css - if we want to add custom CSS to file - it basically reads input file to string and prepends css to it and then passes it to stdin. This is a workaround for a bug in wkhtmltopdf ( look closely in README ). If self.source.isFile() and not self.css - we dont need to pass anything to stdin.
Yea, it reads only a piece at a time because wkhtmltopdf have a progress-bar in output and this is the only way to properly show it.
Yes, it will pass resulting PDF document to stdout
which means that stderr of wkhtmltopdf goes directly to the stderr of the parent process - i.e. generally it will go directly to the user's terminal. Your code does not handle the stderr (progress bar) at all.
If you want to handle stderr then the instantiation should be:
Also you can't really mix calls to the communicatte() and poll() methods of Popen objects - in this case communicate() consumes all the output of wkhtmltopdf before result() is called. This means that this block actually does nothing:
if '--quiet' not in args:
while True:
if result.poll() is not None:
break
out = result.stdout.read(1).decode('utf-8')
if out != '':
sys.stdout.write(out)
sys.stdout.flush()
stuff appears on the console because (as already mentioned) the stderr of wkhtmltopdf is piped to there directly, bypassing pdfkit.
Activity
JazzCore commentedon Feb 5, 2013
For now output of
wkhtmltopdfalways goes to stdout, except when you specify--quietoption. Currently ifoutput_pathevaluates toFalseit will append'-'to the end of command ( incommandmethod ). If'-'is at the end of commandwkhtmltopdfwill pass generated PDF to stdout ( can be used for piping :) ). It is not used in pdfkit at the moment, so this is my mistake for not checkingoutput_pathfor valid input. So, you can change this behaviour but dont forget to run tests because it can break some of them.Moving to
communicate: if we usefrom_stringAPI call we need to pass our input string to stdin ofwkhtmltopdf(wkhtmltopdfrequirement ). We dont need to pass something to stdin when usingfrom_fileorfrom_url, except one case:self.source.isFile() and self.css- if we want to add custom CSS to file - it basically reads input file to string and prepends css to it and then passes it to stdin. This is a workaround for a bug in wkhtmltopdf ( look closely in README ). Ifself.source.isFile() and not self.css- we dont need to pass anything to stdin.Yea, it reads only a piece at a time because
wkhtmltopdfhave a progress-bar in output and this is the only way to properly show it.Yes, it will pass resulting PDF document to stdout
tomscytale commentedon Feb 5, 2013
great, this looks like it will be very helpful - thanks
tomscytale commentedon Feb 27, 2013
some comments about the handling of the output of
wkhtmltopdfthe progress bar and associated details are output to stderr, not stdout
if, when calling
wkhtmltopdf, the output file is specified as '-' the pdf output goes to stdoutin your call to
subprocess.Popenyou do not open a pipe to stderr:which means that stderr of
wkhtmltopdfgoes directly to the stderr of the parent process - i.e. generally it will go directly to the user's terminal. Your code does not handle the stderr (progress bar) at all.If you want to handle stderr then the instantiation should be:
Also you can't really mix calls to the
communicatte()andpoll()methods ofPopenobjects - in this casecommunicate()consumes all the output ofwkhtmltopdfbeforeresult()is called. This means that this block actually does nothing:stuff appears on the console because (as already mentioned) the stderr of
wkhtmltopdfis piped to there directly, bypassingpdfkit.