"""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    __snake_case       :



       @staticmethod
       def   lowerCamelCase_   (						*lowercase    ,			**lowercase)	->			List[str]:





         '''simple docstring'''





         pass







 def 						__a   (	_SCREAMING_SNAKE_CASE   )	->List[str]:
   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.
lowercase__					       =	(
    'https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png'
)




@is_pipeline_test
@require_torch
@require_vision
class    __snake_case       (     unittest.TestCase				):
      a__        =		MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING



      @require_pytesseract
      @require_vision
      def   lowerCamelCase_   (						self    ,			lowercase    ,			lowercase    ,			lowercase)	->			Tuple:





        '''simple docstring'''





        a__:     Optional[Any]										=	pipeline(
            'document-question-answering'    ,			model=lowercase    ,			tokenizer=lowercase    ,			image_processor=lowercase)

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



      def   lowerCamelCase_   (						self    ,			lowercase    ,			lowercase)	->			Dict:





        '''simple docstring'''





        a__:     str										=	dqa_pipeline(lowercase    ,			top_k=2)
        self.assertEqual(
            lowercase    ,			[
                [
                    {'score': ANY(lowercase), 'answer': ANY(lowercase), 'start': ANY(lowercase), 'end': ANY(lowercase)},
                    {'score': ANY(lowercase), 'answer': ANY(lowercase), 'start': ANY(lowercase), 'end': ANY(lowercase)},
                ]
            ]
            * 3    ,			)



      @require_torch
      @require_detectrona
      @require_pytesseract
      def   lowerCamelCase_   (						self)	->			Tuple:





        '''simple docstring'''





        a__:     List[Any]										=	pipeline('document-question-answering'    ,			model='hf-internal-testing/tiny-random-layoutlmv2')
        a__:     Optional[Any]										=	INVOICE_URL
        a__:     List[Any]										=	'How many cats are there?'

        a__:     Optional[int]										=	[
            {'score': 0.0001, 'answer': 'oy 2312/2019', 'start': 38, 'end': 39},
            {'score': 0.0001, 'answer': 'oy 2312/2019 DUE', 'start': 38, 'end': 40},
        ]
        a__:     str										=	dqa_pipeline(image=lowercase    ,			question=lowercase    ,			top_k=2)
        self.assertEqual(nested_simplify(lowercase    ,			decimals=4)    ,			lowercase)

        a__:     int										=	dqa_pipeline({'image': image, 'question': question}    ,			top_k=2)
        self.assertEqual(nested_simplify(lowercase    ,			decimals=4)    ,			lowercase)

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

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



      @slow
      @require_torch
      @require_detectrona
      @require_pytesseract
      def   lowerCamelCase_   (						self)	->			str:





        '''simple docstring'''





        a__:     Optional[int]										=	pipeline(
            'document-question-answering'    ,			model='tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa'    ,			revision='9977165'    ,			)
        a__:     Union[str, Any]										=	INVOICE_URL
        a__:     str										=	'What is the invoice number?'

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

        a__:     Optional[Any]										=	dqa_pipeline({'image': image, 'question': question}    ,			top_k=2)
        self.assertEqual(
            nested_simplify(lowercase    ,			decimals=4)    ,			[
                {'score': 0.9944, 'answer': 'us-001', 'start': 16, 'end': 16},
                {'score': 0.0009, 'answer': 'us-001', 'start': 16, 'end': 16},
            ]    ,			)

        a__:     Optional[int]										=	dqa_pipeline(
            [{'image': image, 'question': question}, {'image': image, 'question': question}]    ,			top_k=2)
        self.assertEqual(
            nested_simplify(lowercase    ,			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)	->			Optional[Any]:





        '''simple docstring'''





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

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

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

        a__:     List[Any]										=	dqa_pipeline(
            [{'image': image, 'question': question}, {'image': image, 'question': question}]    ,			top_k=2)
        self.assertEqual(
            nested_simplify(lowercase    ,			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)	->			Tuple:





        '''simple docstring'''





        a__:     List[Any]										=	AutoTokenizer.from_pretrained(
            'impira/layoutlm-document-qa'    ,			revision='3dc6de3'    ,			add_prefix_space=lowercase)
        a__:     Tuple										=	pipeline(
            'document-question-answering'    ,			model='impira/layoutlm-document-qa'    ,			tokenizer=lowercase    ,			revision='3dc6de3'    ,			)
        a__:     Optional[Any]										=	INVOICE_URL
        a__:     Tuple										=	'What is the invoice number?'

        a__:     List[Any]										=	dqa_pipeline(image=lowercase    ,			question=lowercase    ,			top_k=2)
        self.assertEqual(
            nested_simplify(lowercase    ,			decimals=4)    ,			[
                {'score': 0.4251, 'answer': 'us-001', 'start': 16, 'end': 16},
                {'score': 0.0819, 'answer': '1110212019', 'start': 23, 'end': 23},
            ]    ,			)

        a__:     Optional[int]										=	dqa_pipeline({'image': image, 'question': question}    ,			top_k=2)
        self.assertEqual(
            nested_simplify(lowercase    ,			decimals=4)    ,			[
                {'score': 0.4251, 'answer': 'us-001', 'start': 16, 'end': 16},
                {'score': 0.0819, 'answer': '1110212019', 'start': 23, 'end': 23},
            ]    ,			)

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

        a__:     List[Any]										=	list(zip(*apply_tesseract(load_image(lowercase)    ,			lowercase    ,			'')))

        # This model should also work if `image` is set to None
        a__:     Optional[Any]										=	dqa_pipeline({'image': None, 'word_boxes': word_boxes, 'question': question}    ,			top_k=2)
        self.assertEqual(
            nested_simplify(lowercase    ,			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)	->			Tuple:





        '''simple docstring'''





        a__:     Union[str, Any]										=	AutoTokenizer.from_pretrained(
            'impira/layoutlm-document-qa'    ,			revision='3dc6de3'    ,			add_prefix_space=lowercase)
        a__:     Optional[Any]										=	pipeline(
            'document-question-answering'    ,			model='impira/layoutlm-document-qa'    ,			tokenizer=lowercase    ,			revision='3dc6de3'    ,			max_seq_len=50    ,			)
        a__:     Any										=	INVOICE_URL
        a__:     Tuple										=	'What is the invoice number?'

        a__:     Any										=	dqa_pipeline(image=lowercase    ,			question=lowercase    ,			top_k=2)
        self.assertEqual(
            nested_simplify(lowercase    ,			decimals=4)    ,			[
                {'score': 0.9999, 'answer': 'us-001', 'start': 16, 'end': 16},
                {'score': 0.9998, 'answer': 'us-001', 'start': 16, 'end': 16},
            ]    ,			)

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

        a__:     Optional[int]										=	list(zip(*apply_tesseract(load_image(lowercase)    ,			lowercase    ,			'')))

        # This model should also work if `image` is set to None
        a__:     Union[str, Any]										=	dqa_pipeline({'image': None, 'word_boxes': word_boxes, 'question': question}    ,			top_k=2)
        self.assertEqual(
            nested_simplify(lowercase    ,			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)	->			Optional[int]:





        '''simple docstring'''





        a__:     Optional[Any]										=	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'    ,			)

        a__:     List[Any]										=	INVOICE_URL
        a__:     Any										=	'What is the invoice number?'
        a__:     Dict										=	dqa_pipeline(image=lowercase    ,			question=lowercase    ,			top_k=2)
        self.assertEqual(nested_simplify(lowercase    ,			decimals=4)    ,			[{'answer': 'us-001'}])



      @require_tf
      @unittest.skip('Document question answering not implemented in TF')
      def   lowerCamelCase_   (						self)	->			List[str]:





        '''simple docstring'''





        pass








"""simple docstring"""






import os
from typing import List, Optional, Union

from ...image_processing_utils import BatchFeature
from ...image_utils import ImageInput
from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import PaddingStrategy, PreTokenizedInput, TextInput, TruncationStrategy
from ...utils import TensorType
from ..auto import AutoTokenizer






class lowerCAmelCase__	(     lowercase						):






			'''simple docstring'''



			lowerCamelCase__      =			["""image_processor""", """tokenizer"""]
			lowerCamelCase__      =			"""BlipImageProcessor"""
			lowerCamelCase__      =			"""AutoTokenizer"""
			def __init__(  self  ,      lowercase  ,      lowercase  ,      lowercase  ):
							super().__init__(lowercase  ,      lowercase  )

							# add QFormer tokenizer
							_lowerCamelCase     :			int    =    qformer_tokenizer
			def __call__(  self  ,      lowercase = None  ,      lowercase = None  ,      lowercase = True  ,      lowercase = False  ,      lowercase = None  ,      lowercase = None  ,      lowercase = 0  ,      lowercase = None  ,      lowercase = None  ,      lowercase = False  ,      lowercase = False  ,      lowercase = False  ,      lowercase = False  ,      lowercase = False  ,      lowercase = True  ,      lowercase = None  ,      **lowercase  ,      ):
							if images is None and text is None:
											raise ValueError('You have to specify at least images or text.'  )

							_lowerCamelCase     :			int    =    BatchFeature()

							if text is not None:
											_lowerCamelCase     :			List[str]    =    self.tokenizer(
											    text=lowercase  ,      add_special_tokens=lowercase  ,      padding=lowercase  ,      truncation=lowercase  ,      max_length=lowercase  ,      stride=lowercase  ,      pad_to_multiple_of=lowercase  ,      return_attention_mask=lowercase  ,      return_overflowing_tokens=lowercase  ,      return_special_tokens_mask=lowercase  ,      return_offsets_mapping=lowercase  ,      return_token_type_ids=lowercase  ,      return_length=lowercase  ,      verbose=lowercase  ,      return_tensors=lowercase  ,      **lowercase  ,      )
											encoding.update(lowercase  )
											_lowerCamelCase     :			List[str]    =    self.qformer_tokenizer(
											    text=lowercase  ,      add_special_tokens=lowercase  ,      padding=lowercase  ,      truncation=lowercase  ,      max_length=lowercase  ,      stride=lowercase  ,      pad_to_multiple_of=lowercase  ,      return_attention_mask=lowercase  ,      return_overflowing_tokens=lowercase  ,      return_special_tokens_mask=lowercase  ,      return_offsets_mapping=lowercase  ,      return_token_type_ids=lowercase  ,      return_length=lowercase  ,      verbose=lowercase  ,      return_tensors=lowercase  ,      **lowercase  ,      )
											_lowerCamelCase     :			List[Any]    =    qformer_text_encoding.pop('input_ids'  )
											_lowerCamelCase     :			Tuple    =    qformer_text_encoding.pop('attention_mask'  )

							if images is not None:
											_lowerCamelCase     :			int    =    self.image_processor(lowercase  ,      return_tensors=lowercase  )
											encoding.update(lowercase  )

							return encoding
			def 					A_    (  self  ,      *lowercase  ,      **lowercase  ):
							return self.tokenizer.batch_decode(*lowercase  ,      **lowercase  )
			def 					A_    (  self  ,      *lowercase  ,      **lowercase  ):
							return self.tokenizer.decode(*lowercase  ,      **lowercase  )
			@property
			# Copied from transformers.models.blip.processing_blip.BlipProcessor.model_input_names
			def 					A_    (  self  ):
							_lowerCamelCase     :			Union[str, Any]    =    self.tokenizer.model_input_names
							_lowerCamelCase     :			Any    =    self.image_processor.model_input_names
							return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names  )  )
			def 					A_    (  self  ,      lowercase  ,      **lowercase  ):
							if os.path.isfile(lowercase  ):
											raise ValueError(F'''Provided path ({save_directory}) should be a directory, not a file'''  )
							os.makedirs(lowercase  ,      exist_ok=lowercase  )
							_lowerCamelCase     :			Optional[Any]    =    os.path.join(lowercase  ,      'qformer_tokenizer'  )
							self.qformer_tokenizer.save_pretrained(lowercase  )
							return super().save_pretrained(lowercase  ,      **lowercase  )






			@classmethod
			def 					A_    (  cls  ,      lowercase  ,      **lowercase  ):
							_lowerCamelCase     :			Union[str, Any]    =    AutoTokenizer.from_pretrained(lowercase  ,      subfolder='qformer_tokenizer'  )
							_lowerCamelCase     :			Dict    =    cls._get_arguments_from_pretrained(lowercase  ,      **lowercase  )
							args.append(lowercase  )
							return cls(*lowercase  )