From f0c292f4e17f77ecc614e32b579d1b06ad952014 Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Fri, 12 Dec 2025 01:17:22 -0800 Subject: [PATCH] refactor: Remove CLI-parser dependencies in experimental API functions This commit updates `_pdf_to_hocr` and `_hocr_to_ocr_pdf` to use direct OCROptions construction, eliminating the last vestiges of CLI-parser dependency in the experimental APIs. Key changes: - Removed `parser = get_parser()` calls - Added plugin validation similar to main `ocr()` function - Simplified plugin manager hook calls - Added None value filtering to use OCROptions defaults - Maintained error handling and extra_attrs logic The refactoring makes these experimental APIs truly API-first and simplifies the code by removing unnecessary CLI-related complexity. Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) --- src/ocrmypdf/api.py | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/ocrmypdf/api.py b/src/ocrmypdf/api.py index a05093fb..482367a7 100644 --- a/src/ocrmypdf/api.py +++ b/src/ocrmypdf/api.py @@ -444,6 +444,16 @@ def _pdf_to_hocr( # noqa: D417 output_folder: Output folder path. **kwargs: Keyword arguments. """ + if plugins and plugin_manager: + raise ValueError("plugins= and plugin_manager are mutually exclusive") + + if not plugins: + plugins = [] + elif isinstance(plugins, str | Path): + plugins = [plugins] + else: + plugins = list(plugins) + # Prepare kwargs for direct OCROptions construction options_kwargs = kwargs.copy() @@ -460,10 +470,13 @@ def _pdf_to_hocr( # noqa: D417 ): options_kwargs[param_name] = param_value - # Handle plugins separately + # Handle plugins if plugins: options_kwargs['plugins'] = plugins + # Remove None values to let OCROptions use its defaults + options_kwargs = {k: v for k, v in options_kwargs.items() if v is not None} + # Remove any kwargs that aren't OCROptions fields and store in extra_attrs extra_attrs = {'output_folder': output_folder} ocr_fields = set(OCROptions.model_fields.keys()) @@ -473,12 +486,10 @@ def _pdf_to_hocr( # noqa: D417 if key not in ocr_fields and key not in known_extra: extra_attrs[key] = options_kwargs.pop(key) - parser = get_parser() - with _api_lock: if not plugin_manager: plugin_manager = get_plugin_manager(plugins) - plugin_manager.hook.add_options(parser=parser) # pylint: disable=no-member + plugin_manager.hook.add_options(parser=get_parser()) # pylint: disable=no-member # Create OCROptions directly try: @@ -529,6 +540,16 @@ def _hocr_to_ocr_pdf( # noqa: D417 output_file: Output PDF file path. **kwargs: Keyword arguments. """ + if plugins and plugin_manager: + raise ValueError("plugins= and plugin_manager are mutually exclusive") + + if not plugins: + plugins = [] + elif isinstance(plugins, str | Path): + plugins = [plugins] + else: + plugins = list(plugins) + # Prepare kwargs for direct OCROptions construction options_kwargs = kwargs.copy() @@ -545,10 +566,13 @@ def _hocr_to_ocr_pdf( # noqa: D417 ): options_kwargs[param_name] = param_value - # Handle plugins separately + # Handle plugins if plugins: options_kwargs['plugins'] = plugins + # Remove None values to let OCROptions use its defaults + options_kwargs = {k: v for k, v in options_kwargs.items() if v is not None} + # Remove any kwargs that aren't OCROptions fields and store in extra_attrs extra_attrs = {'work_folder': work_folder} ocr_fields = set(OCROptions.model_fields.keys()) @@ -558,12 +582,10 @@ def _hocr_to_ocr_pdf( # noqa: D417 if key not in ocr_fields and key not in known_extra: extra_attrs[key] = options_kwargs.pop(key) - parser = get_parser() - with _api_lock: if not plugin_manager: plugin_manager = get_plugin_manager(plugins) - plugin_manager.hook.add_options(parser=parser) # pylint: disable=no-member + plugin_manager.hook.add_options(parser=get_parser()) # pylint: disable=no-member # Create OCROptions directly try: