code: def main(
      input_dir: Annotated[
          Path,
          typer.Argument(
              envvar="OCR_INPUT_DIRECTORY",
              exists=True,
              file_okay=False,
              dir_okay=True,
              readable=True,
              resolve_path=True,
          ),
      ] = "/input",
      output_dir: Annotated[
          Path,
          typer.Argument(
              envvar="OCR_OUTPUT_DIRECTORY",
              exists=True,
              file_okay=False,
              dir_okay=True,
              writable=True,
              resolve_path=True,
          ),
      ] = "/output",
      archive_dir: Annotated[
          Path,
          typer.Argument(
              envvar="OCR_ARCHIVE_DIRECTORY",
              exists=True,
              file_okay=False,
              dir_okay=True,
              writable=True,
              resolve_path=True,
          ),
      ] = "/processed",
      output_dir_year_month: Annotated[
          bool,
          typer.Option(
              envvar="OCR_OUTPUT_DIRECTORY_YEAR_MONTH",
              help="Create a subdirectory in the output directory for each year and month",
          ),
      ] = False,
      on_success_delete: Annotated[
          bool,
          typer.Option(
              envvar="OCR_ON_SUCCESS_DELETE",
              help="Delete the input file after successful OCR",
          ),
      ] = False,
      on_success_archive: Annotated[
          bool,
          typer.Option(
              envvar="OCR_ON_SUCCESS_ARCHIVE",
              help="Archive the input file after successful OCR",
          ),
      ] = False,
      deskew: Annotated[
          bool,
          typer.Option(
              envvar="OCR_DESKEW",
              help="Deskew the input file before OCR",
          ),
      ] = False,
      ocr_json_settings: Annotated[
          str,
          typer.Option(
              envvar="OCR_JSON_SETTINGS",
              help="JSON settings to pass to OCRmyPDF (JSON string or file path)",
          ),
      ] = None,
      poll_new_file_seconds: Annotated[
          int,
          typer.Option(
              envvar="OCR_POLL_NEW_FILE_SECONDS",
              help="Seconds to wait before polling a new file",
              min=0,
          ),
      ] = 1,
      use_polling: Annotated[
          bool,
          typer.Option(
              envvar="OCR_USE_POLLING",
              help="Use polling instead of filesystem events",
          ),
      ] = False,
      retries_loading_file: Annotated[
          int,
          typer.Option(
              envvar="OCR_RETRIES_LOADING_FILE",
              help="Number of times to retry loading a file before giving up",
              min=0,
          ),
      ] = 5,
      loglevel: Annotated[
          LoggingLevelEnum,
          typer.Option(
              envvar="OCR_LOGLEVEL",
              help="Logging level",
          ),
      ] = LoggingLevelEnum.INFO,
      patterns: Annotated[
          str,
          typer.Option(
              envvar="OCR_PATTERNS",
              help="File patterns to watch",
          ),
      ] = "*.pdf,*.PDF",
  ):
      ocrmypdf.configure_logging(
          verbosity=(
              ocrmypdf.Verbosity.default
              if loglevel != LoggingLevelEnum.DEBUG
              else ocrmypdf.Verbosity.debug
          ),
          manage_root_logger=True,
      )
      log.setLevel(loglevel.value)
      log.info(
          f"Starting OCRmyPDF watcher with config:\n"
          f"Input Directory: {input_dir}\n"
          f"Output Directory: {output_dir}\n"
          f"Output Directory Year & Month: {output_dir_year_month}\n"
          f"Archive Directory: {archive_dir}"
      )
      log.debug(
          f"INPUT_DIRECTORY: {input_dir}\n"
          f"OUTPUT_DIRECTORY: {output_dir}\n"
          f"OUTPUT_DIRECTORY_YEAR_MONTH: {output_dir_year_month}\n"
          f"ARCHIVE_DIRECTORY: {archive_dir}\n"
          f"ON_SUCCESS_DELETE: {on_success_delete}\n"
          f"ON_SUCCESS_ARCHIVE: {on_success_archive}\n"
          f"DESKEW: {deskew}\n"
          f"ARGS: {ocr_json_settings}\n"
          f"POLL_NEW_FILE_SECONDS: {poll_new_file_seconds}\n"
          f"RETRIES_LOADING_FILE: {retries_loading_file}\n"
          f"USE_POLLING: {use_polling}\n"
          f"LOGLEVEL: {loglevel.value}"
      )
  
      if ocr_json_settings and Path(ocr_json_settings).exists():
          json_settings = json.loads(
              Path(ocr_json_settings).read_text()
          )
      else:
          json_settings = json.loads(ocr_json_settings or "{}")
  
      if (
          "input_file" in json_settings
          or "output_file" in json_settings
      ):
          log.error(
              "OCR_JSON_SETTINGS (--ocr-json-settings) may not specify input/output file"
          )
          sys.exit(1)
  
      handler = HandleObserverEvent(
          patterns=patterns.split(","),
          settings={
              "archive_dir": archive_dir,
              "output_dir": output_dir,
              "ocrmypdf_kwargs": json_settings | {"deskew": deskew},
              "on_success_delete": on_success_delete,
              "on_success_archive": on_success_archive,
              "poll_new_file_seconds": poll_new_file_seconds,
              "retries_loading_file": retries_loading_file,
              "output_dir_year_month": output_dir_year_month,
          },
      )
      if use_polling:
          observer = PollingObserver()
      else:
          observer = Observer()
      observer.schedule(handler, input_dir, recursive=True)
      observer.start()
      typer.echo(
          f"Watching {input_dir} for new PDFs. Press Ctrl+C to exit."
      )
      try:
          while True:
              time.sleep(30)
      except KeyboardInterrupt:
          observer.stop()
      observer.join()
  
imports: import json
  import logging
  import shutil
  import sys
  import time
  from datetime import datetime
  from enum import Enum
  from pathlib import Path
  from typing import Annotated, Any
  import pikepdf
  import typer
  from dotenv import load_dotenv
  from watchdog.events import PatternMatchingEventHandler
  from watchdog.observers import Observer
  from watchdog.observers.polling import PollingObserver
  import ocrmypdf
label_desc: Use image node_id 4 for calling a global function with example usage: main(input_dir, output_dir, archive_dir, output_dir_year_month, on_success_delete, on_success_archive, deskew, ocr_json_settings, poll_new_file_seconds, use_polling, retries_loading_file, loglevel, patterns) without return types