diff --git a/.gitignore b/.gitignore index 3faf7f2..2ea88d5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ pdfkit.egg-info # Tests .tox .python-version + +# ENV +venv diff --git a/HISTORY.rst b/HISTORY.rst index 7e1809d..cccd071 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,5 +1,7 @@ Changelog --------- +* `1.0.1` + * By default PDFKit handle errors from wkhtmltopdf. Now if you need to get clear output from wkhtmltopdf output, if it existed, you should pass "raise_exceptions=False" to API calls * `1.0.0` * By default PDFKit now passes "quiet" option to wkhtmltopdf. Now if you need to get output you should pass "verbose=True" to API calls * Fix different issues with searching for wkhtmltopdf binary diff --git a/README.rst b/README.rst index 9119ea3..d99f1eb 100644 --- a/README.rst +++ b/README.rst @@ -146,6 +146,12 @@ You can also pass any options through meta tags in your HTML: pdfkit.from_string(body, 'out.pdf') #with --page-size=Legal and --orientation=Landscape +By default, PDFKit will handle errors from ``wkhtmltopdf``, but in some cases ``wkhtmltopdf`` return pdf data in ``stdout`` despite errors. To tell PDFKit do not handle errors from ``wkhtmltopdf`` you should pass ``raise_exceptions=False`` to API calls, but you should consider that in case of empty ``stdout`` error handling will be started anyway: + +.. code-block:: python + + pdfkit.from_url('google.com', 'out.pdf', raise_exceptions=False) + Configuration ------------- diff --git a/pdfkit/__init__.py b/pdfkit/__init__.py index a54653a..31c052e 100644 --- a/pdfkit/__init__.py +++ b/pdfkit/__init__.py @@ -4,7 +4,7 @@ """ __author__ = 'Golovanov Stanislav' -__version__ = '1.0.0' +__version__ = '1.0.1' __license__ = 'MIT' from .pdfkit import PDFKit diff --git a/pdfkit/api.py b/pdfkit/api.py index 86d9656..c250452 100644 --- a/pdfkit/api.py +++ b/pdfkit/api.py @@ -4,8 +4,8 @@ from .pdfkit import Configuration -def from_url(url, output_path=None, options=None, toc=None, cover=None, - configuration=None, cover_first=False, verbose=False): +def from_url(url, output_path=None, options=None, toc=None, cover=None, configuration=None, cover_first=False, + verbose=False, raise_exceptions=True): """ Convert file of files from URLs to PDF document @@ -21,14 +21,14 @@ def from_url(url, output_path=None, options=None, toc=None, cover=None, Returns: True on success """ - r = PDFKit(url, 'url', options=options, toc=toc, cover=cover, - configuration=configuration, cover_first=cover_first, verbose=verbose) + r = PDFKit(url, 'url', options=options, toc=toc, cover=cover, configuration=configuration, cover_first=cover_first, + verbose=verbose, raise_exceptions=raise_exceptions) return r.to_pdf(output_path) def from_file(input, output_path=None, options=None, toc=None, cover=None, css=None, - configuration=None, cover_first=False, verbose=False): + configuration=None, cover_first=False, verbose=False, raise_exceptions=True): """ Convert HTML file or files to PDF document @@ -45,14 +45,14 @@ def from_file(input, output_path=None, options=None, toc=None, cover=None, css=N Returns: True on success """ - r = PDFKit(input, 'file', options=options, toc=toc, cover=cover, css=css, - configuration=configuration, cover_first=cover_first, verbose=verbose) + r = PDFKit(input, 'file', options=options, toc=toc, cover=cover, css=css, configuration=configuration, + cover_first=cover_first, verbose=verbose, raise_exceptions=raise_exceptions) return r.to_pdf(output_path) def from_string(input, output_path=None, options=None, toc=None, cover=None, css=None, - configuration=None, cover_first=False, verbose=False): + configuration=None, cover_first=False, verbose=False, raise_exceptions=True): """ Convert given string or strings to PDF document @@ -69,8 +69,8 @@ def from_string(input, output_path=None, options=None, toc=None, cover=None, css Returns: True on success """ - r = PDFKit(input, 'string', options=options, toc=toc, cover=cover, css=css, - configuration=configuration, cover_first=cover_first, verbose=verbose) + r = PDFKit(input, 'string', options=options, toc=toc, cover=cover, css=css, configuration=configuration, + cover_first=cover_first, verbose=verbose, raise_exceptions=raise_exceptions) return r.to_pdf(output_path) diff --git a/pdfkit/pdfkit.py b/pdfkit/pdfkit.py index 784aad0..a4b3fa2 100644 --- a/pdfkit/pdfkit.py +++ b/pdfkit/pdfkit.py @@ -38,8 +38,8 @@ def __init__(self, msg): def __str__(self): return self.msg - def __init__(self, url_or_file, type_, options=None, toc=None, cover=None, - css=None, configuration=None, cover_first=False, verbose=False): + def __init__(self, url_or_file, type_, options=None, toc=None, cover=None, css=None, configuration=None, + cover_first=False, verbose=False, raise_exceptions=True): self.source = Source(url_or_file, type_) self.configuration = (Configuration() if configuration is None @@ -64,6 +64,7 @@ def __init__(self, url_or_file, type_, options=None, toc=None, cover=None, self.verbose = verbose self.css = css self.stylesheets = [] + self.raise_exceptions = raise_exceptions def _genargs(self, opts): """ @@ -198,7 +199,11 @@ def to_pdf(self, path=None): stderr = stderr or stdout or b"" stderr = stderr.decode('utf-8', errors='replace') exit_code = result.returncode - self.handle_error(exit_code, stderr) + + # In some cases we don't want to handle errors if we want clean wkhtmltopdf output, + # but if we don't have stdout, we have to do it anyway + if not stdout or self.raise_exceptions: + self.handle_error(exit_code, stderr) # Since wkhtmltopdf sends its output to stderr we will capture it # and properly send to stdout diff --git a/tests/pdfkit-tests.py b/tests/pdfkit-tests.py index 969afbd..6451569 100644 --- a/tests/pdfkit-tests.py +++ b/tests/pdfkit-tests.py @@ -492,5 +492,27 @@ def test_issue_169_quiet_boolean_True(self): output = r.to_pdf() self.assertEqual(output[:4].decode('utf-8'), '%PDF') + def test_raise_exceptions_kwarg(self): + + # exception raised with stdout and raise_exceptions=True + r = pdfkit.PDFKit('Hai!', 'string', options={'bad-option': None}, + raise_exceptions=True) + with self.assertRaises(IOError): + r.to_pdf() + + # exception raised despite raise_exceptions=False because no stdout + r = pdfkit.PDFKit('clearlywrongurl.asdf', 'url', raise_exceptions=False) + with self.assertRaises(IOError): + r.to_pdf() + + # exception not raised with stdout and raise_exceptions=False + r = pdfkit.PDFKit('Hai!', 'string', options={'bad-option': None}, + raise_exceptions=False) + try: + r.to_pdf() + except IOError: + self.fail("r.to_pdf() raised an IOError exception despite 'raise_exceptions=False' kwarg") + + if __name__ == "__main__": unittest.main()