text: from os.path import dirname
  
  import numpy as np
  from app.utils.moderation.text_moderation import BadWordTextModerator
  from cv2 import COLOR_BGR2RGB, IMREAD_COLOR, cvtColor, imdecode
  from dotenv import load_dotenv
  from pytesseract import image_to_data, image_to_string
  
  # Windows users: uncomment and add local Tesseract path, example below
  # This should not be necessary if running through Docker (or for Mac users)
  # from pytesseract import pytesseract
  # pytesseract.tesseract_cmd = "C:/Program Files/Tesseract-OCR/tesseract.exe"
  
  # Get name of directory where this file is located
  DIR = dirname(__file__)
  
  # Setup globals
  BAD_WORDS_CSV = DIR + "/../moderation/bad_single.csv"
  MODEL_DIR = DIR + "/../../../models/"
  TESSDATA_DIR = MODEL_DIR
  
  # Tell tesseract to look in TESSDATA_DIR for lang trainedata files
  TESS_CONFIG = f'--tessdata-dir "{TESSDATA_DIR}"'
  
  
  class TesseractAPI:
      """
      Interface to Tesseract OCR engine
      Takes single image page and returns transcribed text
      """
  
      def __init__(self, lang="storysquad"):
          """
          Arguments:
          Tesseract model (default is 'storysquad')
  
          Actions:
          Prepares TesseractAPI to handle requests from the endpoints
          """
  
          load_dotenv()
          self.text_moderator = BadWordTextModerator(BAD_WORDS_CSV)
          self.lang = lang
  
      def img_preprocess(self, image):
          """
          Arguments:
          Single full-page image
  
          Actions:
          1. Convert image data bytestring to image object
          2. Convert order of image colors from BGR to RGB
  
          Returns:
          Full-page processed image
          """
  
          nparr = np.fromstring(image, np.uint8)
          image_array = imdecode(nparr, IMREAD_COLOR)
  
          processed_img = cvtColor(image_array, COLOR_BGR2RGB)
  
          return processed_img
  
      def extract_data(self, image):
          """
          Arguments:
          Single full-page image
  
          Actions:
          Extract data on image with Tesseract OCR
  
          Returns:
          Dictionary with data for:
          1. Content moderation by word: data_dict['text']
          2. Confidence scoring (values are per word): data_dict['conf']
          """
  
          data_dict = image_to_data(
              image, lang=self.lang, config=TESS_CONFIG, output_type="dict"
          )
          return data_dict
  
      def extract_text(self, image):
          """
          Arguments:
          Single full-page image
  
          Actions:
          Extract text from image with Tesseract OCR
  
          Returns:
          Transcribed text (string)
          """
  
          text = image_to_string(image, lang=self.lang, config=TESS_CONFIG)
  
          return text
  
      def word_moderation(self, data_dict):
          """
          Arguments:
          Data dictionary generated by Tesseract from extract_data method
  
          Actions:
          Moderate content by word
  
          Returns:
          Bad content flag (T/F)
          """
  
          content_flagged = False
          for word in data_dict["text"]:
              if self.text_moderator.check_word(str(word).lower()):
                  content_flagged = True
  
          return content_flagged
  
      def confidence_flag(self, data_dict):
          """
          Arguments:
          Data dictionary generated by Tesseract from extract_data method
  
          Actions:
          Calculate mean confidence for entire page
  
          Returns:
          Low confidence flag (T/F)
          """
  
          confidence_list = list(map(int, data_dict["conf"]))
          page_confidence = sum(confidence_list) / len(confidence_list) / 100
  
          return page_confidence < 0.85
  
      def transcribe(self, image):
          """
          Arguments:
          Single full-page image
  
          Actions:
          1. Preprocesses image
          2. Extract text
          3. Moderate content
          4. Get confidence
  
          Returns:
          1. Transcribed text (string)
          2. Bad content flag (T/F)
          3. Low confidence flag (T/F)
          """
  
          features = self.img_preprocess(image)
          text = self.extract_text(features)
          data_dict = self.extract_data(features)
          content_flagged = self.word_moderation(data_dict)
          low_confidence = self.confidence_flag(data_dict)
  
          return low_confidence, content_flagged, text
  