Skip to content

Commit 5a992b7

Browse files
committed
Switch to quiet output by default, Add verbose parameter to API calls
Fixes #84
1 parent bc7e71d commit 5a992b7

4 files changed

Lines changed: 70 additions & 23 deletions

File tree

README.rst

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,11 @@ You can specify all wkhtmltopdf `options <http://wkhtmltopdf.org/usage/wkhtmltop
9797
9898
pdfkit.from_url('http://google.com', 'out.pdf', options=options)
9999
100-
By default, PDFKit will show all ``wkhtmltopdf`` output. If you don't want it, you need to pass ``quiet`` option:
100+
By default, PDFKit will run ``wkhtmltopdf`` with ``quiet`` option turned on, since in most cases output is not needed and can cause excessive memory usage and corrupted results. If need to get ``wkhtmltopdf`` output you should pass ``verbose=True`` to API calls:
101101

102102
.. code-block:: python
103103
104-
options = {
105-
'quiet': ''
106-
}
107-
108-
pdfkit.from_url('google.com', 'out.pdf', options=options)
104+
pdfkit.from_url('google.com', 'out.pdf', verbose=True)
109105
110106
Due to wkhtmltopdf command syntax, **TOC** and **Cover** options must be specified separately. If you need cover before TOC, use ``cover_first`` option:
111107

@@ -179,6 +175,29 @@ Also you can use ``configuration()`` call to check if wkhtmltopdf is present in
179175
Troubleshooting
180176
---------------
181177

178+
Debugging issues with PDF generation
179+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
180+
181+
If you struggling to generate correct PDF firstly you should check wkhtmltopdf output for some clues, you can get it by passing ``verbose=True`` to API calls:
182+
183+
.. code-block:: python
184+
185+
pdfkit.from_url('http://google.com', 'out.pdf', verbose=True)
186+
187+
If you are getting strage results in PDF or some option looks like its ignored you should try to run ``wkhtmltopdf`` directly to see if it produces the same result. You can get CLI command by creating ``pdfkit.PDFKit`` class directly and then calling its ``command()`` method:
188+
189+
.. code-block:: python
190+
191+
import pdfkit
192+
193+
r = pdfkit.PDFKit('html', 'string', verbose=True)
194+
print(' '.join(r.command()))
195+
# try running wkhtmltopdf to create PDF
196+
output = r.to_pdf()
197+
198+
Common errors:
199+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
200+
182201
- ``IOError: 'No wkhtmltopdf executable found'``:
183202

184203
Make sure that you have wkhtmltopdf in your `$PATH` or set via custom configuration (see preceding section). *where wkhtmltopdf* in Windows or *which wkhtmltopdf* on Linux should return actual path to binary.

pdfkit/api.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
def from_url(url, output_path=None, options=None, toc=None, cover=None,
8-
configuration=None, cover_first=False):
8+
configuration=None, cover_first=False, verbose=False):
99
"""
1010
Convert file of files from URLs to PDF document
1111
@@ -16,18 +16,19 @@ def from_url(url, output_path=None, options=None, toc=None, cover=None,
1616
:param cover: (optional) string with url/filename with a cover html page
1717
:param configuration: (optional) instance of pdfkit.configuration.Configuration()
1818
:param cover_first: (optional) if True, cover always precedes TOC
19+
:param verbose: (optional) By default '--quiet' is passed to all calls, set this to False to get wkhtmltopdf output to stdout.
1920
2021
Returns: True on success
2122
"""
2223

2324
r = PDFKit(url, 'url', options=options, toc=toc, cover=cover,
24-
configuration=configuration, cover_first=cover_first)
25+
configuration=configuration, cover_first=cover_first, verbose=verbose)
2526

2627
return r.to_pdf(output_path)
2728

2829

2930
def from_file(input, output_path=None, options=None, toc=None, cover=None, css=None,
30-
configuration=None, cover_first=False):
31+
configuration=None, cover_first=False, verbose=False):
3132
"""
3233
Convert HTML file or files to PDF document
3334
@@ -39,18 +40,19 @@ def from_file(input, output_path=None, options=None, toc=None, cover=None, css=N
3940
:param css: (optional) string with path to css file which will be added to a single input file
4041
:param configuration: (optional) instance of pdfkit.configuration.Configuration()
4142
:param cover_first: (optional) if True, cover always precedes TOC
43+
:param verbose: (optional) By default '--quiet' is passed to all calls, set this to False to get wkhtmltopdf output to stdout.
4244
4345
Returns: True on success
4446
"""
4547

4648
r = PDFKit(input, 'file', options=options, toc=toc, cover=cover, css=css,
47-
configuration=configuration, cover_first=cover_first)
49+
configuration=configuration, cover_first=cover_first, verbose=verbose)
4850

4951
return r.to_pdf(output_path)
5052

5153

5254
def from_string(input, output_path=None, options=None, toc=None, cover=None, css=None,
53-
configuration=None, cover_first=False):
55+
configuration=None, cover_first=False, verbose=False):
5456
"""
5557
Convert given string or strings to PDF document
5658
@@ -62,12 +64,13 @@ def from_string(input, output_path=None, options=None, toc=None, cover=None, css
6264
:param css: (optional) string with path to css file which will be added to a input string
6365
:param configuration: (optional) instance of pdfkit.configuration.Configuration()
6466
:param cover_first: (optional) if True, cover always precedes TOC
67+
:param verbose: (optional) By default '--quiet' is passed to all calls, set this to False to get wkhtmltopdf output to stdout.
6568
6669
Returns: True on success
6770
"""
6871

6972
r = PDFKit(input, 'string', options=options, toc=toc, cover=cover, css=css,
70-
configuration=configuration, cover_first=cover_first)
73+
configuration=configuration, cover_first=cover_first, verbose=verbose)
7174

7275
return r.to_pdf(output_path)
7376

pdfkit/pdfkit.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def __str__(self):
3939
return self.msg
4040

4141
def __init__(self, url_or_file, type_, options=None, toc=None, cover=None,
42-
css=None, configuration=None, cover_first=False):
42+
css=None, configuration=None, cover_first=False, verbose=False):
4343

4444
self.source = Source(url_or_file, type_)
4545
self.configuration = (Configuration() if configuration is None
@@ -61,6 +61,7 @@ def __init__(self, url_or_file, type_, options=None, toc=None, cover=None,
6161
self.toc = {} if toc is None else toc
6262
self.cover = cover
6363
self.cover_first = cover_first
64+
self.verbose = verbose
6465
self.css = css
6566
self.stylesheets = []
6667

@@ -89,6 +90,9 @@ def _command(self, path=None):
8990

9091
yield self.wkhtmltopdf
9192

93+
if not self.verbose:
94+
self.options.update({'--quiet': ''})
95+
9296
for argpart in self._genargs(self.options):
9397
if argpart:
9498
yield argpart
@@ -133,10 +137,12 @@ def handle_error(exit_code, stderr):
133137
if exit_code == 0:
134138
return
135139

140+
stderr_lines = stderr.splitlines()
141+
136142
# Sometimes wkhtmltopdf will exit with non-zero
137143
# even if it finishes generation.
138144
# If will display 'Done' in the second last line
139-
if stderr.splitlines()[-2].strip() == 'Done':
145+
if len(stderr_lines) > 1 and stderr.splitlines()[-2].strip() == 'Done':
140146
return
141147

142148
if 'cannot connect to X server' in stderr:

tests/pdfkit-tests.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,9 @@ def test_skip_nonpdfkit_tags(self):
201201

202202
def test_toc_handling_without_options(self):
203203
r = pdfkit.PDFKit('hmtl', 'string', toc={'xsl-style-sheet': 'test.xsl'})
204-
self.assertEqual(r.command()[1], 'toc')
205-
self.assertEqual(r.command()[2], '--xsl-style-sheet')
204+
self.assertEqual(r.command()[1], '--quiet')
205+
self.assertEqual(r.command()[2], 'toc')
206+
self.assertEqual(r.command()[3], '--xsl-style-sheet')
206207

207208
def test_toc_with_options(self):
208209
options = {
@@ -217,16 +218,18 @@ def test_toc_with_options(self):
217218

218219
command = r.command()
219220

220-
self.assertEqual(command[1 + len(options) * 2], 'toc')
221-
self.assertEqual(command[1 + len(options) * 2 + 1], '--xsl-style-sheet')
221+
self.assertEqual(command[1 + len(options) * 2], '--quiet')
222+
self.assertEqual(command[2 + len(options) * 2], 'toc')
223+
self.assertEqual(command[2 + len(options) * 2 + 1], '--xsl-style-sheet')
222224

223225
def test_cover_without_options(self):
224226
r = pdfkit.PDFKit('html', 'string', cover='test.html')
225227

226228
command = r.command()
227229

228-
self.assertEqual(command[1], 'cover')
229-
self.assertEqual(command[2], 'test.html')
230+
self.assertEqual(command[1], '--quiet')
231+
self.assertEqual(command[2], 'cover')
232+
self.assertEqual(command[3], 'test.html')
230233

231234
def test_cover_with_options(self):
232235
options = {
@@ -241,8 +244,9 @@ def test_cover_with_options(self):
241244

242245
command = r.command()
243246

244-
self.assertEqual(command[1 + len(options) * 2], 'cover')
245-
self.assertEqual(command[1 + len(options) * 2 + 1], 'test.html')
247+
self.assertEqual(command[1 + len(options) * 2], '--quiet')
248+
self.assertEqual(command[2 + len(options) * 2], 'cover')
249+
self.assertEqual(command[2 + len(options) * 2 + 1], 'test.html')
246250

247251
def test_cover_and_toc(self):
248252
options = {
@@ -289,10 +293,25 @@ def test_filter_empty_and_none_values_in_opts(self):
289293
'quiet': False
290294
}
291295

292-
r = pdfkit.PDFKit('html', 'string', options=options)
296+
r = pdfkit.PDFKit('html', 'string', options=options, verbose=True)
293297
cmd = r.command()
294298
self.assertEqual(len(cmd), 6)
295299

300+
def test_verbose_option(self):
301+
options = {
302+
'outline': '',
303+
'footer-line': None,
304+
'quiet': True
305+
}
306+
307+
r = pdfkit.PDFKit('html', 'string')
308+
cmd = r.command()
309+
self.assertTrue('--quiet' in cmd)
310+
311+
r = pdfkit.PDFKit('html', 'string', options=options)
312+
cmd = r.command()
313+
self.assertTrue('--quiet' in cmd)
314+
296315

297316
class TestPDFKitGeneration(unittest.TestCase):
298317
"""Test to_pdf() method"""

0 commit comments

Comments
 (0)