





'''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     lowercase_			:




   """simple docstring"""




   @staticmethod
   def       SCREAMING_SNAKE_CASE   (   *lowercase__     :  Dict      ,**lowercase__     :  List[Any]    ):
    pass


 def 	_A  (					A__   ):






  """simple docstring"""



  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.
lowerCAmelCase__      		=			(
    'https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png'
)






@is_pipeline_test
@require_torch
@require_vision
class     lowercase_			(unittest.TestCase   ):




  """simple docstring"""




  SCREAMING_SNAKE_CASE					:						int           =    MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING






  @require_pytesseract
  @require_vision
  def       SCREAMING_SNAKE_CASE   (   self     :  str      ,lowercase__     :  Union[str, Any]      ,lowercase__     :  Tuple      ,lowercase__     :  Dict    ):
   __lowercase													=				pipeline(
       '''document-question-answering'''      ,model=UpperCamelCase__      ,tokenizer=UpperCamelCase__      ,image_processor=UpperCamelCase__    )

   __lowercase													=				INVOICE_URL
   __lowercase													=				list(zip(*apply_tesseract(load_image(UpperCamelCase__    )      ,UpperCamelCase__      ,''''''    )    )    )
   __lowercase													=				'''What is the placebo?'''
   __lowercase													=				[
       {
           '''image''': load_image(UpperCamelCase__    ),
           '''question''': question,
       },
       {
           '''image''': image,
           '''question''': question,
       },
       {
           '''image''': image,
           '''question''': question,
           '''word_boxes''': word_boxes,
       },
   ]
   return dqa_pipeline, examples






  def       SCREAMING_SNAKE_CASE   (   self     :  List[str]      ,lowercase__     :  int      ,lowercase__     :  List[Any]    ):
   __lowercase													=				dqa_pipeline(UpperCamelCase__      ,top_k=2    )
   self.assertEqual(
       UpperCamelCase__      ,[
           [
               {'''score''': ANY(UpperCamelCase__    ), '''answer''': ANY(UpperCamelCase__    ), '''start''': ANY(UpperCamelCase__    ), '''end''': ANY(UpperCamelCase__    )},
               {'''score''': ANY(UpperCamelCase__    ), '''answer''': ANY(UpperCamelCase__    ), '''start''': ANY(UpperCamelCase__    ), '''end''': ANY(UpperCamelCase__    )},
           ]
       ]
       * 3      ,)






  @require_torch
  @require_detectrona
  @require_pytesseract
  def       SCREAMING_SNAKE_CASE   (   self     :  str    ):
   __lowercase													=				pipeline('''document-question-answering'''      ,model='''hf-internal-testing/tiny-random-layoutlmv2'''    )
   __lowercase													=				INVOICE_URL
   __lowercase													=				'''How many cats are there?'''

   __lowercase													=				[
       {'''score''': 0.0_0_0_1, '''answer''': '''oy 2312/2019''', '''start''': 3_8, '''end''': 3_9},
       {'''score''': 0.0_0_0_1, '''answer''': '''oy 2312/2019 DUE''', '''start''': 3_8, '''end''': 4_0},
   ]
   __lowercase													=				dqa_pipeline(image=UpperCamelCase__      ,question=UpperCamelCase__      ,top_k=2    )
   self.assertEqual(nested_simplify(UpperCamelCase__      ,decimals=4    )      ,UpperCamelCase__    )

   __lowercase													=				dqa_pipeline({'''image''': image, '''question''': question}      ,top_k=2    )
   self.assertEqual(nested_simplify(UpperCamelCase__      ,decimals=4    )      ,UpperCamelCase__    )

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

   # We can optionnally pass directly the words and bounding boxes
   __lowercase													=				'''./tests/fixtures/tests_samples/COCO/000000039769.png'''
   __lowercase													=				[]
   __lowercase													=				[]
   __lowercase													=				dqa_pipeline(image=UpperCamelCase__      ,question=UpperCamelCase__      ,words=UpperCamelCase__      ,boxes=UpperCamelCase__      ,top_k=2    )
   self.assertEqual(UpperCamelCase__      ,[]    )






  @slow
  @require_torch
  @require_detectrona
  @require_pytesseract
  def       SCREAMING_SNAKE_CASE   (   self     :  List[str]    ):
   __lowercase													=				pipeline(
       '''document-question-answering'''      ,model='''tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa'''      ,revision='''9977165'''      ,)
   __lowercase													=				INVOICE_URL
   __lowercase													=				'''What is the invoice number?'''

   __lowercase													=				dqa_pipeline(image=UpperCamelCase__      ,question=UpperCamelCase__      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           {'''score''': 0.9_9_4_4, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           {'''score''': 0.0_0_0_9, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
       ]      ,)

   __lowercase													=				dqa_pipeline({'''image''': image, '''question''': question}      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           {'''score''': 0.9_9_4_4, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           {'''score''': 0.0_0_0_9, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
       ]      ,)

   __lowercase													=				dqa_pipeline(
       [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}]      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           [
               {'''score''': 0.9_9_4_4, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
               {'''score''': 0.0_0_0_9, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           ],
       ]
       * 2      ,)






  @slow
  @require_torch
  @require_detectrona
  @require_pytesseract
  def       SCREAMING_SNAKE_CASE   (   self     :  str    ):
   __lowercase													=				pipeline(
       '''document-question-answering'''      ,model='''tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa'''      ,revision='''9977165'''      ,max_seq_len=5_0      ,)
   __lowercase													=				INVOICE_URL
   __lowercase													=				'''What is the invoice number?'''

   __lowercase													=				dqa_pipeline(image=UpperCamelCase__      ,question=UpperCamelCase__      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           {'''score''': 0.9_9_7_4, '''answer''': '''1110212019''', '''start''': 2_3, '''end''': 2_3},
           {'''score''': 0.9_9_4_8, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
       ]      ,)

   __lowercase													=				dqa_pipeline({'''image''': image, '''question''': question}      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           {'''score''': 0.9_9_7_4, '''answer''': '''1110212019''', '''start''': 2_3, '''end''': 2_3},
           {'''score''': 0.9_9_4_8, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
       ]      ,)

   __lowercase													=				dqa_pipeline(
       [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}]      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           [
               {'''score''': 0.9_9_7_4, '''answer''': '''1110212019''', '''start''': 2_3, '''end''': 2_3},
               {'''score''': 0.9_9_4_8, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           ]
       ]
       * 2      ,)






  @slow
  @require_torch
  @require_pytesseract
  @require_vision
  def       SCREAMING_SNAKE_CASE   (   self     :  Optional[Any]    ):
   __lowercase													=				AutoTokenizer.from_pretrained(
       '''impira/layoutlm-document-qa'''      ,revision='''3dc6de3'''      ,add_prefix_space=UpperCamelCase__    )
   __lowercase													=				pipeline(
       '''document-question-answering'''      ,model='''impira/layoutlm-document-qa'''      ,tokenizer=UpperCamelCase__      ,revision='''3dc6de3'''      ,)
   __lowercase													=				INVOICE_URL
   __lowercase													=				'''What is the invoice number?'''

   __lowercase													=				dqa_pipeline(image=UpperCamelCase__      ,question=UpperCamelCase__      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           {'''score''': 0.4_2_5_1, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           {'''score''': 0.0_8_1_9, '''answer''': '''1110212019''', '''start''': 2_3, '''end''': 2_3},
       ]      ,)

   __lowercase													=				dqa_pipeline({'''image''': image, '''question''': question}      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           {'''score''': 0.4_2_5_1, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           {'''score''': 0.0_8_1_9, '''answer''': '''1110212019''', '''start''': 2_3, '''end''': 2_3},
       ]      ,)

   __lowercase													=				dqa_pipeline(
       [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}]      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           [
               {'''score''': 0.4_2_5_1, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
               {'''score''': 0.0_8_1_9, '''answer''': '''1110212019''', '''start''': 2_3, '''end''': 2_3},
           ]
       ]
       * 2      ,)

   __lowercase													=				list(zip(*apply_tesseract(load_image(UpperCamelCase__    )      ,UpperCamelCase__      ,''''''    )    )    )

   # This model should also work if `image` is set to None
   __lowercase													=				dqa_pipeline({'''image''': None, '''word_boxes''': word_boxes, '''question''': question}      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           {'''score''': 0.4_2_5_1, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           {'''score''': 0.0_8_1_9, '''answer''': '''1110212019''', '''start''': 2_3, '''end''': 2_3},
       ]      ,)






  @slow
  @require_torch
  @require_pytesseract
  @require_vision
  def       SCREAMING_SNAKE_CASE   (   self     :  Optional[Any]    ):
   __lowercase													=				AutoTokenizer.from_pretrained(
       '''impira/layoutlm-document-qa'''      ,revision='''3dc6de3'''      ,add_prefix_space=UpperCamelCase__    )
   __lowercase													=				pipeline(
       '''document-question-answering'''      ,model='''impira/layoutlm-document-qa'''      ,tokenizer=UpperCamelCase__      ,revision='''3dc6de3'''      ,max_seq_len=5_0      ,)
   __lowercase													=				INVOICE_URL
   __lowercase													=				'''What is the invoice number?'''

   __lowercase													=				dqa_pipeline(image=UpperCamelCase__      ,question=UpperCamelCase__      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           {'''score''': 0.9_9_9_9, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           {'''score''': 0.9_9_9_8, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
       ]      ,)

   __lowercase													=				dqa_pipeline(
       [{'''image''': image, '''question''': question}, {'''image''': image, '''question''': question}]      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           [
               {'''score''': 0.9_9_9_9, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
               {'''score''': 0.9_9_9_8, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           ]
       ]
       * 2      ,)

   __lowercase													=				list(zip(*apply_tesseract(load_image(UpperCamelCase__    )      ,UpperCamelCase__      ,''''''    )    )    )

   # This model should also work if `image` is set to None
   __lowercase													=				dqa_pipeline({'''image''': None, '''word_boxes''': word_boxes, '''question''': question}      ,top_k=2    )
   self.assertEqual(
       nested_simplify(UpperCamelCase__      ,decimals=4    )      ,[
           {'''score''': 0.9_9_9_9, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
           {'''score''': 0.9_9_9_8, '''answer''': '''us-001''', '''start''': 1_6, '''end''': 1_6},
       ]      ,)






  @slow
  @require_torch
  def       SCREAMING_SNAKE_CASE   (   self     :  List[Any]    ):
   __lowercase													=				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'''      ,)

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






  @require_tf
  @unittest.skip('''Document question answering not implemented in TF'''    )
  def       SCREAMING_SNAKE_CASE   (   self     :  int    ):
   pass




'''simple docstring'''






import os
from shutil import copyfile
from typing import List, Optional, Tuple

import sentencepiece as spm

from ...tokenization_utils import PreTrainedTokenizer
from ...utils import logging


lowerCAmelCase__      		=			logging.get_logger(__name__)

lowerCAmelCase__      		=			{'''vocab_file''': '''sentencepiece.model'''}

lowerCAmelCase__      		=			{
    '''vocab_file''': {
        '''google/rembert''': '''https://huggingface.co/google/rembert/resolve/main/sentencepiece.model''',
    },
}

lowerCAmelCase__      		=			{
    '''google/rembert''': 256,
}






class     lowercase_			(lowerCamelCase__   ):




  """simple docstring"""




  SCREAMING_SNAKE_CASE					:						Tuple           =    VOCAB_FILES_NAMES
  SCREAMING_SNAKE_CASE					:						Optional[int]           =    PRETRAINED_VOCAB_FILES_MAP
  SCREAMING_SNAKE_CASE					:						Union[str, Any]           =    PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES






  def __init__(   self     :  str      ,lowercase__     :  Optional[Any]      ,lowercase__     :  List[str]=False      ,lowercase__     :  Dict=True      ,lowercase__     :  List[str]=True      ,lowercase__     :  Dict="[CLS]"      ,lowercase__     :  Union[str, Any]="[SEP]"      ,lowercase__     :  List[str]="[UNK]"      ,lowercase__     :  int="[SEP]"      ,lowercase__     :  List[str]="[PAD]"      ,lowercase__     :  Optional[int]="[CLS]"      ,lowercase__     :  List[Any]="[MASK]"      ,**lowercase__     :  int      ,):
   super().__init__(
       do_lower_case=lowercase__      ,remove_space=lowercase__      ,keep_accents=lowercase__      ,bos_token=lowercase__      ,eos_token=lowercase__      ,unk_token=lowercase__      ,sep_token=lowercase__      ,pad_token=lowercase__      ,cls_token=lowercase__      ,mask_token=lowercase__      ,**lowercase__      ,)

   __lowercase													=				do_lower_case
   __lowercase													=				remove_space
   __lowercase													=				keep_accents
   __lowercase													=				vocab_file

   __lowercase													=				spm.SentencePieceProcessor()
   self.sp_model.Load(lowercase__    )






  @property
  def       SCREAMING_SNAKE_CASE   (   self     :  str    ):
   return len(self.sp_model    )






  def       SCREAMING_SNAKE_CASE   (   self     :  str    ):
   __lowercase													=				{self.convert_ids_to_tokens(lowercase__    ): i for i in range(self.vocab_size    )}
   vocab.update(self.added_tokens_encoder    )
   return vocab






  def __getstate__(   self     :  List[Any]    ):
   __lowercase													=				self.__dict__.copy()
   __lowercase													=				None
   return state






  def __setstate__(   self     :  str      ,lowercase__     :  Optional[int]    ):
   __lowercase													=				d
   __lowercase													=				spm.SentencePieceProcessor()
   self.sp_model.Load(self.vocab_file    )






  def       SCREAMING_SNAKE_CASE   (   self     :  List[str]      ,lowercase__     :  List[str]      ,lowercase__     :  List[Any]=False    ):
   __lowercase													=				self.sp_model.EncodeAsPieces(lowercase__    )
   return pieces






  def       SCREAMING_SNAKE_CASE   (   self     :  Tuple      ,lowercase__     :  List[Any]    ):
   return self.sp_model.PieceToId(lowercase__    )






  def       SCREAMING_SNAKE_CASE   (   self     :  Tuple      ,lowercase__     :  str    ):
   return self.sp_model.IdToPiece(lowercase__    )






  def       SCREAMING_SNAKE_CASE   (   self     :  Any      ,lowercase__     :  Tuple    ):
   __lowercase													=				self.sp_model.decode_pieces(lowercase__    )
   return out_string






  def       SCREAMING_SNAKE_CASE   (   self     :  Optional[int]      ,lowercase__     :  List[int]      ,lowercase__     :  Optional[List[int]] = None    ):
   __lowercase													=				[self.sep_token_id]
   __lowercase													=				[self.cls_token_id]
   if token_ids_a is None:
    return cls + token_ids_a + sep
   return cls + token_ids_a + sep + token_ids_a + sep






  def       SCREAMING_SNAKE_CASE   (   self     :  List[Any]      ,lowercase__     :  List[int]      ,lowercase__     :  Optional[List[int]] = None      ,lowercase__     :  bool = False    ):

   if already_has_special_tokens:
    if token_ids_a is not None:
     raise ValueError(
         '''You should not supply a second sequence if the provided sequence of '''
         '''ids is already formatted with special tokens for the model.'''    )
    return [1 if x in [self.sep_token_id, self.cls_token_id] else 0 for x in token_ids_a]

   if token_ids_a is not None:
    return [1] + ([0] * len(lowercase__    )) + [1] + ([0] * len(lowercase__    )) + [1]
   return [1] + ([0] * len(lowercase__    )) + [1]






  def       SCREAMING_SNAKE_CASE   (   self     :  Dict      ,lowercase__     :  List[int]      ,lowercase__     :  Optional[List[int]] = None    ):
   __lowercase													=				[self.sep_token_id]
   __lowercase													=				[self.cls_token_id]

   if token_ids_a is None:
    return len(cls + token_ids_a + sep    ) * [0]
   return len(cls + token_ids_a + sep    ) * [0] + len(token_ids_a + sep    ) * [1]






  def       SCREAMING_SNAKE_CASE   (   self     :  Optional[int]      ,lowercase__     :  str      ,lowercase__     :  Optional[str] = None    ):
   if not os.path.isdir(lowercase__    ):
    logger.error('''Vocabulary path ({}) should be a directory'''.format(lowercase__    )    )
    return
   __lowercase													=				os.path.join(
       lowercase__      ,(filename_prefix + '''-''' if filename_prefix else '''''') + VOCAB_FILES_NAMES['''vocab_file''']    )

   if os.path.abspath(self.vocab_file    ) != os.path.abspath(lowercase__    ):
    copyfile(self.vocab_file      ,lowercase__    )

   return (out_vocab_file,)

