From 10c8e4f8b405dcb84269cbe0af54dbf4fb6e610d Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Tue, 20 Oct 2020 01:29:22 -0700 Subject: [PATCH] Only create debug.log when running from command line When used as a library ocrmypdf shouldn't make policy decisions, like where to put a log file. Unsurprisingly, creating it causes problems for library users because we deleted the temporary folder which held the log file and made no effort to move it to a new location. Also update the documentation to better described how an application should handle this. Closes #657 --- src/ocrmypdf/_sync.py | 7 +++++-- src/ocrmypdf/api.py | 32 ++++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/ocrmypdf/_sync.py b/src/ocrmypdf/_sync.py index 22b9afa8..68c24da5 100644 --- a/src/ocrmypdf/_sync.py +++ b/src/ocrmypdf/_sync.py @@ -330,9 +330,12 @@ def run_pipeline(options, *, plugin_manager, api=False): work_folder = Path(mkdtemp(prefix="com.github.ocrmypdf.")) debug_log_handler = None - if (options.keep_temporary_files or options.verbose >= 1) and not os.environ.get( - 'PYTEST_CURRENT_TEST', '' + if ( + (options.keep_temporary_files or options.verbose >= 1) + and not os.environ.get('PYTEST_CURRENT_TEST', '') + and not api ): + # Debug log for command line interface only with verbose output debug_log_handler = configure_debug_logging(Path(work_folder) / "debug.log") pikepdf_enable_mmap() diff --git a/src/ocrmypdf/api.py b/src/ocrmypdf/api.py index 898d9e11..f8809157 100644 --- a/src/ocrmypdf/api.py +++ b/src/ocrmypdf/api.py @@ -11,6 +11,7 @@ import sys from enum import IntEnum from pathlib import Path from typing import BinaryIO, Iterable, Union +from warnings import warn from ocrmypdf._logging import PageNumberFilter, TqdmConsole from ocrmypdf._plugin_manager import get_plugin_manager @@ -44,16 +45,28 @@ def configure_logging( ): """Set up logging. - Library users may wish to use this function if they want their log output to be - similar to ocrmypdf command line interface. If not used, the external application - should configure logging on its own. + Before calling :func:`ocrmypdf.ocr()`, you can use this function to + configure logging, if you want ocrmypdf's output to look like the ocrmypdf + command line interface. It will register log handlers, log filters, and + formatters, configure color logging to standard error, and adjust the log + levels of third party libraries. Details of this are fine-tuned and subject + to change. The ``verbosity`` argument is equivalent to the argument + ``--verbose`` and applies those settings. - ocrmypdf will perform all of its logging under the ``"ocrmypdf"`` logging namespace. - In addition, ocrmypdf imports pdfminer, which logs under ``"pdfminer"``. A library - user may wish to configure both; note that pdfminer is extremely chatty at the log - level ``logging.INFO``. + If this function is not called, ocrmypdf will not configure logging, and it + is up to the caller of ``ocrmypdf.ocr()`` to set up logging as it wishes using + the Python standard library's logging module. If this function is called, + the caller may of course make further adjustments to logging. - Library users may perform additional configuration afterwards. + Regardless of whether this function is called, ocrmypdf will perform all of + its logging under the ``"ocrmypdf"`` logging namespace. In addition, + ocrmypdf imports pdfminer, which logs under ``"pdfminer"``. A library user + may wish to configure both; note that pdfminer is extremely chatty at the + log level ``logging.INFO``. + + This function does not set up the ``debug.log`` log file that the command + line interface does at certain verbosity levels. Applications should configure + their own debug logging. Args: verbosity (Verbosity): Verbosity level. @@ -294,6 +307,9 @@ def ocr( # pylint: disable=unused-argument } create_options_kwargs.update(kwargs) + if 'verbose' in kwargs: + warn("ocrmypdf.ocr(verbose=) is ignored. Use ocrmypdf.configure_logging().") + options = create_options(**create_options_kwargs) check_options(options, _plugin_manager) return run_pipeline(options=options, plugin_manager=_plugin_manager, api=True)