




"""simple docstring"""


import unittest

from transformers import MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING, AutoTokenizer, is_vision_available
from transformers.pipelines import pipeline
from transformers.pipelines.document_question_answering import apply_tesseract
from transformers.testing_utils import (
    is_pipeline_test,
    nested_simplify,
    require_detectrona,
    require_pytesseract,
    require_tf,
    require_torch,
    require_vision,
    slow,
)

from .test_pipelines_common import ANY


if is_vision_available():
  from PIL import Image

  from transformers.image_utils import load_image
else:


  class _lowerCamelCase    :






     @staticmethod
     def 	_lowerCAmelCase   (		*UpperCamelCase       :		Any   ,     **UpperCamelCase       :		Optional[Any]   )			->						List[Any]:

           """simple docstring"""
           pass






  def 	lowercase_				(			__UpperCAmelCase				)						->    Union[str, Any]:
        return None


# This is a pinned image from a specific revision of a document question answering space, hosted by HuggingFace,
# so we can expect it to be available.
_A													=      (
    """https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png"""
)


@is_pipeline_test
@require_torch
@require_vision
class _lowerCamelCase    (					unittest.TestCase						):
   _lowerCamelCase    :List[Any]     				=     MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING






   @require_pytesseract
   @require_vision
   def 	_lowerCAmelCase   (		self       :		Optional[int]   ,     UpperCamelCase       :		str   ,     UpperCamelCase       :		List[Any]   ,     UpperCamelCase       :		Tuple   )			->						List[Any]:

         """simple docstring"""
         lowerCAmelCase__      :			Union[str, Any]   =	pipeline(
             """document-question-answering"""   ,     model=a_   ,     tokenizer=a_   ,     image_processor=a_   )

         lowerCAmelCase__      :			Any   =	INVOICE_URL
         lowerCAmelCase__      :			List[str]   =	list(zip(*apply_tesseract(load_image(a_   )   ,     a_   ,     """"""   )   )   )
         lowerCAmelCase__      :			Any   =	'''What is the placebo?'''
         lowerCAmelCase__      :			Any   =	[
             {
                 '''image''': load_image(a_   ),
                 '''question''': question,
             },
             {
                 '''image''': image,
                 '''question''': question,
             },
             {
                 '''image''': image,
                 '''question''': question,
                 '''word_boxes''': word_boxes,
             },
         ]
         return dqa_pipeline, examples






   def 	_lowerCAmelCase   (		self       :		List[str]   ,     UpperCamelCase       :		Union[str, Any]   ,     UpperCamelCase       :		Any   )			->						Any:

         """simple docstring"""
         lowerCAmelCase__      :			Optional[Any]   =	dqa_pipeline(a_   ,     top_k=2   )
         self.assertEqual(
             a_   ,     [
                 [
                     {"""score""": ANY(a_   ), """answer""": ANY(a_   ), """start""": ANY(a_   ), """end""": ANY(a_   )},
                     {"""score""": ANY(a_   ), """answer""": ANY(a_   ), """start""": ANY(a_   ), """end""": ANY(a_   )},
                 ]
             ]
             * 3   ,     )






   @require_torch
   @require_detectrona
   @require_pytesseract
   def 	_lowerCAmelCase   (		self       :		str   )			->						Dict:

         """simple docstring"""
         lowerCAmelCase__      :			str   =	pipeline("""document-question-answering"""   ,     model="""hf-internal-testing/tiny-random-layoutlmv2"""   )
         lowerCAmelCase__      :			Union[str, Any]   =	INVOICE_URL
         lowerCAmelCase__      :			Tuple   =	'''How many cats are there?'''

         lowerCAmelCase__      :			Tuple   =	[
             {'''score''': 0.0001, '''answer''': '''oy 2312/2019''', '''start''': 38, '''end''': 39},
             {'''score''': 0.0001, '''answer''': '''oy 2312/2019 DUE''', '''start''': 38, '''end''': 40},
         ]
         lowerCAmelCase__      :			Union[str, Any]   =	dqa_pipeline(image=a_   ,     question=a_   ,     top_k=2   )
         self.assertEqual(nested_simplify(a_   ,     decimals=4   )   ,     a_   )

         lowerCAmelCase__      :			int   =	dqa_pipeline({"""image""": image, """question""": question}   ,     top_k=2   )
         self.assertEqual(nested_simplify(a_   ,     decimals=4   )   ,     a_   )

         # This image does not detect ANY text in it, meaning layoutlmv2 should fail.
         # Empty answer probably
         lowerCAmelCase__      :			List[Any]   =	'''./tests/fixtures/tests_samples/COCO/000000039769.png'''
         lowerCAmelCase__      :			List[Any]   =	dqa_pipeline(image=a_   ,     question=a_   ,     top_k=2   )
         self.assertEqual(a_   ,     []   )

         # We can optionnally pass directly the words and bounding boxes
         lowerCAmelCase__      :			Dict   =	'''./tests/fixtures/tests_samples/COCO/000000039769.png'''
         lowerCAmelCase__      :			Union[str, Any]   =	[]
         lowerCAmelCase__      :			int   =	[]
         lowerCAmelCase__      :			List[str]   =	dqa_pipeline(image=a_   ,     question=a_   ,     words=a_   ,     boxes=a_   ,     top_k=2   )
         self.assertEqual(a_   ,     []   )






   @slow
   @require_torch
   @require_detectrona
   @require_pytesseract
   def 	_lowerCAmelCase   (		self       :		Optional[Any]   )			->						Tuple:

         """simple docstring"""
         lowerCAmelCase__      :			List[Any]   =	pipeline(
             """document-question-answering"""   ,     model="""tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa"""   ,     revision="""9977165"""   ,     )
         lowerCAmelCase__      :			str   =	INVOICE_URL
         lowerCAmelCase__      :			Any   =	'''What is the invoice number?'''

         lowerCAmelCase__      :			Union[str, Any]   =	dqa_pipeline(image=a_   ,     question=a_   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 {"""score""": 0.9944, """answer""": """us-001""", """start""": 16, """end""": 16},
                 {"""score""": 0.0009, """answer""": """us-001""", """start""": 16, """end""": 16},
             ]   ,     )

         lowerCAmelCase__      :			Union[str, Any]   =	dqa_pipeline({"""image""": image, """question""": question}   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 {"""score""": 0.9944, """answer""": """us-001""", """start""": 16, """end""": 16},
                 {"""score""": 0.0009, """answer""": """us-001""", """start""": 16, """end""": 16},
             ]   ,     )

         lowerCAmelCase__      :			Dict   =	dqa_pipeline(
             [{"""image""": image, """question""": question}, {"""image""": image, """question""": question}]   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 [
                     {"""score""": 0.9944, """answer""": """us-001""", """start""": 16, """end""": 16},
                     {"""score""": 0.0009, """answer""": """us-001""", """start""": 16, """end""": 16},
                 ],
             ]
             * 2   ,     )






   @slow
   @require_torch
   @require_detectrona
   @require_pytesseract
   def 	_lowerCAmelCase   (		self       :		Union[str, Any]   )			->						Tuple:

         """simple docstring"""
         lowerCAmelCase__      :			Optional[int]   =	pipeline(
             """document-question-answering"""   ,     model="""tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa"""   ,     revision="""9977165"""   ,     max_seq_len=50   ,     )
         lowerCAmelCase__      :			str   =	INVOICE_URL
         lowerCAmelCase__      :			List[str]   =	'''What is the invoice number?'''

         lowerCAmelCase__      :			Tuple   =	dqa_pipeline(image=a_   ,     question=a_   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 {"""score""": 0.9974, """answer""": """1110212019""", """start""": 23, """end""": 23},
                 {"""score""": 0.9948, """answer""": """us-001""", """start""": 16, """end""": 16},
             ]   ,     )

         lowerCAmelCase__      :			str   =	dqa_pipeline({"""image""": image, """question""": question}   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 {"""score""": 0.9974, """answer""": """1110212019""", """start""": 23, """end""": 23},
                 {"""score""": 0.9948, """answer""": """us-001""", """start""": 16, """end""": 16},
             ]   ,     )

         lowerCAmelCase__      :			Optional[int]   =	dqa_pipeline(
             [{"""image""": image, """question""": question}, {"""image""": image, """question""": question}]   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 [
                     {"""score""": 0.9974, """answer""": """1110212019""", """start""": 23, """end""": 23},
                     {"""score""": 0.9948, """answer""": """us-001""", """start""": 16, """end""": 16},
                 ]
             ]
             * 2   ,     )






   @slow
   @require_torch
   @require_pytesseract
   @require_vision
   def 	_lowerCAmelCase   (		self       :		List[str]   )			->						Any:

         """simple docstring"""
         lowerCAmelCase__      :			Tuple   =	AutoTokenizer.from_pretrained(
             """impira/layoutlm-document-qa"""   ,     revision="""3dc6de3"""   ,     add_prefix_space=a_   )
         lowerCAmelCase__      :			int   =	pipeline(
             """document-question-answering"""   ,     model="""impira/layoutlm-document-qa"""   ,     tokenizer=a_   ,     revision="""3dc6de3"""   ,     )
         lowerCAmelCase__      :			int   =	INVOICE_URL
         lowerCAmelCase__      :			List[str]   =	'''What is the invoice number?'''

         lowerCAmelCase__      :			Union[str, Any]   =	dqa_pipeline(image=a_   ,     question=a_   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 {"""score""": 0.4251, """answer""": """us-001""", """start""": 16, """end""": 16},
                 {"""score""": 0.0819, """answer""": """1110212019""", """start""": 23, """end""": 23},
             ]   ,     )

         lowerCAmelCase__      :			Tuple   =	dqa_pipeline({"""image""": image, """question""": question}   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 {"""score""": 0.4251, """answer""": """us-001""", """start""": 16, """end""": 16},
                 {"""score""": 0.0819, """answer""": """1110212019""", """start""": 23, """end""": 23},
             ]   ,     )

         lowerCAmelCase__      :			Tuple   =	dqa_pipeline(
             [{"""image""": image, """question""": question}, {"""image""": image, """question""": question}]   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 [
                     {"""score""": 0.4251, """answer""": """us-001""", """start""": 16, """end""": 16},
                     {"""score""": 0.0819, """answer""": """1110212019""", """start""": 23, """end""": 23},
                 ]
             ]
             * 2   ,     )

         lowerCAmelCase__      :			Union[str, Any]   =	list(zip(*apply_tesseract(load_image(a_   )   ,     a_   ,     """"""   )   )   )

         # This model should also work if `image` is set to None
         lowerCAmelCase__      :			Dict   =	dqa_pipeline({"""image""": None, """word_boxes""": word_boxes, """question""": question}   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 {"""score""": 0.4251, """answer""": """us-001""", """start""": 16, """end""": 16},
                 {"""score""": 0.0819, """answer""": """1110212019""", """start""": 23, """end""": 23},
             ]   ,     )






   @slow
   @require_torch
   @require_pytesseract
   @require_vision
   def 	_lowerCAmelCase   (		self       :		Dict   )			->						List[Any]:

         """simple docstring"""
         lowerCAmelCase__      :			int   =	AutoTokenizer.from_pretrained(
             """impira/layoutlm-document-qa"""   ,     revision="""3dc6de3"""   ,     add_prefix_space=a_   )
         lowerCAmelCase__      :			int   =	pipeline(
             """document-question-answering"""   ,     model="""impira/layoutlm-document-qa"""   ,     tokenizer=a_   ,     revision="""3dc6de3"""   ,     max_seq_len=50   ,     )
         lowerCAmelCase__      :			int   =	INVOICE_URL
         lowerCAmelCase__      :			Optional[int]   =	'''What is the invoice number?'''

         lowerCAmelCase__      :			str   =	dqa_pipeline(image=a_   ,     question=a_   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 {"""score""": 0.9999, """answer""": """us-001""", """start""": 16, """end""": 16},
                 {"""score""": 0.9998, """answer""": """us-001""", """start""": 16, """end""": 16},
             ]   ,     )

         lowerCAmelCase__      :			List[Any]   =	dqa_pipeline(
             [{"""image""": image, """question""": question}, {"""image""": image, """question""": question}]   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 [
                     {"""score""": 0.9999, """answer""": """us-001""", """start""": 16, """end""": 16},
                     {"""score""": 0.9998, """answer""": """us-001""", """start""": 16, """end""": 16},
                 ]
             ]
             * 2   ,     )

         lowerCAmelCase__      :			Union[str, Any]   =	list(zip(*apply_tesseract(load_image(a_   )   ,     a_   ,     """"""   )   )   )

         # This model should also work if `image` is set to None
         lowerCAmelCase__      :			Any   =	dqa_pipeline({"""image""": None, """word_boxes""": word_boxes, """question""": question}   ,     top_k=2   )
         self.assertEqual(
             nested_simplify(a_   ,     decimals=4   )   ,     [
                 {"""score""": 0.9999, """answer""": """us-001""", """start""": 16, """end""": 16},
                 {"""score""": 0.9998, """answer""": """us-001""", """start""": 16, """end""": 16},
             ]   ,     )






   @slow
   @require_torch
   def 	_lowerCAmelCase   (		self       :		Dict   )			->						List[Any]:

         """simple docstring"""
         lowerCAmelCase__      :			List[str]   =	pipeline(
             """document-question-answering"""   ,     model="""naver-clova-ix/donut-base-finetuned-docvqa"""   ,     tokenizer=AutoTokenizer.from_pretrained("""naver-clova-ix/donut-base-finetuned-docvqa"""   )   ,     feature_extractor="""naver-clova-ix/donut-base-finetuned-docvqa"""   ,     )

         lowerCAmelCase__      :			int   =	INVOICE_URL
         lowerCAmelCase__      :			Optional[Any]   =	'''What is the invoice number?'''
         lowerCAmelCase__      :			Optional[int]   =	dqa_pipeline(image=a_   ,     question=a_   ,     top_k=2   )
         self.assertEqual(nested_simplify(a_   ,     decimals=4   )   ,     [{"""answer""": """us-001"""}]   )






   @require_tf
   @unittest.skip("""Document question answering not implemented in TF"""   )
   def 	_lowerCAmelCase   (		self       :		Optional[Any]   )			->						Union[str, Any]:

         """simple docstring"""
         pass











"""simple docstring"""


import os
from collections import deque

import torch
from torch.utils.data import Dataset


class _lowerCamelCase    (					a_						):






   def __init__(		self       :		Tuple   ,     UpperCamelCase       :		List[Any]=""   ,     UpperCamelCase       :		List[str]="train"   )			->						List[Any]:

         """simple docstring"""
         assert os.path.isdir(UpperCamelCase   )

         lowerCAmelCase__      :			Union[str, Any]   =	[]
         lowerCAmelCase__      :			List[Any]   =	os.listdir(UpperCamelCase   )
         for story_filename in story_filenames_list:
               if "summary" in story_filename:
                     continue
               lowerCAmelCase__      :			Any   =	os.path.join(UpperCamelCase   ,     UpperCamelCase   )
               if not os.path.isfile(UpperCamelCase   ):
                     continue
               self.documents.append(UpperCamelCase   )






   def __len__(		self       :		List[Any]   )			->						int:

         """simple docstring"""
         return len(self.documents   )






   def __getitem__(		self       :		str   ,     UpperCamelCase       :		Union[str, Any]   )			->						str:

         """simple docstring"""
         lowerCAmelCase__      :			Any   =	self.documents[idx]
         lowerCAmelCase__      :			List[Any]   =	document_path.split("""/"""   )[-1]
         with open(UpperCamelCase   ,     encoding="""utf-8"""   ) as source:
               lowerCAmelCase__      :			List[str]   =	source.read()
               lowerCAmelCase__ ,   lowerCAmelCase__      :			Union[str, Any]   =	process_story(UpperCamelCase   )
         return document_name, story_lines, summary_lines






def 	lowercase_				(			__UpperCAmelCase				)						->    Union[str, Any]:
      lowerCAmelCase__      :			Tuple   =	list(filter(lambda __UpperCAmelCase				: len(__UpperCAmelCase				) != 0    ,		[line.strip() for line in raw_story.split("""\n"""				)]				)				)

      # for some unknown reason some lines miss a period, add it
      lowerCAmelCase__      :			List[str]   =	[_add_missing_period(__UpperCAmelCase				) for line in nonempty_lines]

      # gather article lines
      lowerCAmelCase__      :			Optional[int]   =	[]
      lowerCAmelCase__      :			Optional[int]   =	deque(__UpperCAmelCase				)
      while True:
            try:
                  lowerCAmelCase__      :			List[Any]   =	lines.popleft()
                  if element.startswith("""@highlight"""				):
                        break
                  story_lines.append(__UpperCAmelCase				)
            except IndexError:
                  # if "@highlight" is absent from the file we pop
                  # all elements until there is None, raising an exception.
                  return story_lines, []

    # gather summary lines
      lowerCAmelCase__      :			Any   =	list(filter(lambda __UpperCAmelCase				: not t.startswith("""@highlight"""				)    ,		__UpperCAmelCase				)				)

      return story_lines, summary_lines



def 	lowercase_				(			__UpperCAmelCase				)						->    Optional[int]:
      lowerCAmelCase__      :			List[str]   =	[""".""", """!""", """?""", """...""", """'""", """`""", """\"""", """\u2019""", """\u2019""", """)"""]
      if line.startswith("""@highlight"""				):
            return line
      if line[-1] in END_TOKENS:
            return line
      return line + "."



def 	lowercase_				(			__UpperCAmelCase    ,		__UpperCAmelCase    ,		__UpperCAmelCase				)						->    List[Any]:
      if len(__UpperCAmelCase				) > block_size:
            return sequence[:block_size]
      else:
            sequence.extend([pad_token_id] * (block_size - len(__UpperCAmelCase				))				)
            return sequence



def 	lowercase_				(			__UpperCAmelCase    ,		__UpperCAmelCase				)						->    Tuple:
      lowerCAmelCase__      :			List[str]   =	torch.ones_like(__UpperCAmelCase				)
      lowerCAmelCase__      :			List[str]   =	sequence == pad_token_id
      lowerCAmelCase__      :			str   =	0
      return mask



def 	lowercase_				(			__UpperCAmelCase    ,		__UpperCAmelCase    ,		__UpperCAmelCase				)						->    List[Any]:
      lowerCAmelCase__      :			Tuple   =	[tokenizer.encode(__UpperCAmelCase				) for line in story_lines]
      lowerCAmelCase__      :			List[str]   =	[token for sentence in story_lines_token_ids for token in sentence]
      lowerCAmelCase__      :			int   =	[tokenizer.encode(__UpperCAmelCase				) for line in summary_lines]
      lowerCAmelCase__      :			Union[str, Any]   =	[token for sentence in summary_lines_token_ids for token in sentence]

      return story_token_ids, summary_token_ids



def 	lowercase_				(			__UpperCAmelCase    ,		__UpperCAmelCase				)						->    List[str]:
      lowerCAmelCase__      :			Tuple   =	[]
      for sequence in batch:
            lowerCAmelCase__      :			Union[str, Any]   =	-1
            lowerCAmelCase__      :			List[str]   =	[]
            for s in sequence:
                  if s == separator_token_id:
                        sentence_num += 1
                  embeddings.append(sentence_num % 2				)
            batch_embeddings.append(__UpperCAmelCase				)
      return torch.tensor(__UpperCAmelCase				)





