





# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import re

from ..models.auto import AutoProcessor
from ..models.vision_encoder_decoder import VisionEncoderDecoderModel
from ..utils import is_vision_available
from .base import PipelineTool


if is_vision_available():
    from PIL import Image

class    lowerCAmelCase							(					__UpperCamelCase			):
 UpperCAmelCase__													=		'''naver-clova-ix/donut-base-finetuned-docvqa'''
 UpperCAmelCase__													=		(
     '''This is a tool that answers a question about an document (pdf). It takes an input named `document` which '''
     '''should be the document containing the information, as well as a `question` that is the question about the '''
     '''document. It returns a text that contains the answer to the question.'''
 )
 UpperCAmelCase__													=		'''document_qa'''
 UpperCAmelCase__													=		AutoProcessor
 UpperCAmelCase__													=		VisionEncoderDecoderModel

 UpperCAmelCase__													=		['''image''', '''text''']
 UpperCAmelCase__													=		['''text''']
 def __init__(      self  :      List[Any]			,     *UpperCAmelCase  :      Union[str, Any]			,     **UpperCAmelCase  :      List[str]	)			->	Union[str, Any]:


     if not is_vision_available():
         raise ValueError('Pillow must be installed to use the DocumentQuestionAnsweringTool.'	)

     super().__init__(*_snake_case			,     **_snake_case	)
 def      A_	(      self  :      Optional[Any]			,     UpperCAmelCase  :      "Image"			,     UpperCAmelCase  :      str	)			->	List[str]:
     lowerCamelCase__    :      Union[str, Any]					 =		'<s_docvqa><s_question>{user_input}</s_question><s_answer>'
     lowerCamelCase__    :      str					 =		task_prompt.replace('{user_input}'			,     _snake_case	)
     lowerCamelCase__    :      int					 =		self.pre_processor.tokenizer(
         _snake_case			,     add_special_tokens=_snake_case			,     return_tensors='pt'	).input_ids
     lowerCamelCase__    :      Dict					 =		self.pre_processor(_snake_case			,     return_tensors='pt'	).pixel_values

     return {"decoder_input_ids": decoder_input_ids, "pixel_values": pixel_values}
 def      A_	(      self  :      Optional[int]			,     UpperCAmelCase  :      List[str]	)			->	Tuple:
     return self.model.generate(
         inputs['pixel_values'].to(self.device	)			,     decoder_input_ids=inputs['decoder_input_ids'].to(self.device	)			,     max_length=self.model.decoder.config.max_position_embeddings			,     early_stopping=_snake_case			,     pad_token_id=self.pre_processor.tokenizer.pad_token_id			,     eos_token_id=self.pre_processor.tokenizer.eos_token_id			,     use_cache=_snake_case			,     num_beams=1			,     bad_words_ids=[[self.pre_processor.tokenizer.unk_token_id]]			,     return_dict_in_generate=_snake_case			,     ).sequences







 def      A_	(      self  :      Optional[Any]			,     UpperCAmelCase  :      Any	)			->	Optional[int]:
     lowerCamelCase__    :      int					 =		self.pre_processor.batch_decode(_snake_case	)[0]
     lowerCamelCase__    :      List[str]					 =		sequence.replace(self.pre_processor.tokenizer.eos_token			,     ''	)
     lowerCamelCase__    :      int					 =		sequence.replace(self.pre_processor.tokenizer.pad_token			,     ''	)
     lowerCamelCase__    :      List[Any]					 =		re.sub(R'<.*?>'			,     ''			,     _snake_case			,     count=1	).strip()  # remove first task start token
     lowerCamelCase__    :      Union[str, Any]					 =		self.pre_processor.tokenajson(_snake_case	)

     return sequence["answer"]











import warnings
from typing import List, Optional, Union

from ...image_utils import ImageInput
from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding, PaddingStrategy, PreTokenizedInput, TextInput, TruncationStrategy
from ...utils import TensorType







class __snake_case			(			a		):
   UpperCAmelCase__  :    Dict          =  ['''image_processor''', '''tokenizer''']
   UpperCAmelCase__  :    Dict          =  '''FlavaImageProcessor'''
   UpperCAmelCase__  :    Dict          =  ('''BertTokenizer''', '''BertTokenizerFast''')







   def __init__(      self		:						Union[str, Any]					,						_snake_case		:						List[str]=None					,						_snake_case		:						str=None					,						**_snake_case		:						int):

        """simple docstring"""


        UpperCAmelCase_          =							None
        if "feature_extractor" in kwargs:
             warnings.warn(
                 '''The `feature_extractor` argument is deprecated and will be removed in v5, use `image_processor`'''
                 ''' instead.'''					,						_snake_case					,						)
             UpperCAmelCase_          =							kwargs.pop('''feature_extractor''')

        UpperCAmelCase_          =							image_processor if image_processor is not None else feature_extractor
        if image_processor is None:
             raise ValueError('''You need to specify an `image_processor`.''')
        if tokenizer is None:
             raise ValueError('''You need to specify a `tokenizer`.''')

        super().__init__(_snake_case					,						_snake_case)
        UpperCAmelCase_          =							self.image_processor







   def __call__(      self		:						List[Any]					,						_snake_case		:						Optional[ImageInput] = None					,						_snake_case		:						Optional[Union[TextInput, PreTokenizedInput, List[TextInput], List[PreTokenizedInput]]] = None					,						_snake_case		:						bool = True					,						_snake_case		:						Union[bool, str, PaddingStrategy] = False					,						_snake_case		:						Union[bool, str, TruncationStrategy] = False					,						_snake_case		:						Optional[int] = None					,						_snake_case		:						int = 0					,						_snake_case		:						Optional[int] = None					,						_snake_case		:						Optional[bool] = None					,						_snake_case		:						Optional[bool] = None					,						_snake_case		:						Optional[bool] = None					,						_snake_case		:						Optional[bool] = None					,						_snake_case		:						bool = False					,						_snake_case		:						bool = False					,						_snake_case		:						bool = False					,						_snake_case		:						bool = False					,						_snake_case		:						bool = True					,						_snake_case		:						Optional[Union[str, TensorType]] = None					,						**_snake_case		:						Any					,						):

        """simple docstring"""


        if text is None and images is None:
             raise ValueError('''You have to specify either text or images. Both cannot be none.''')

        if text is not None:
             UpperCAmelCase_          =							self.tokenizer(
                 text=_snake_case					,						add_special_tokens=_snake_case					,						padding=_snake_case					,						truncation=_snake_case					,						max_length=_snake_case					,						stride=_snake_case					,						pad_to_multiple_of=_snake_case					,						return_token_type_ids=_snake_case					,						return_attention_mask=_snake_case					,						return_overflowing_tokens=_snake_case					,						return_special_tokens_mask=_snake_case					,						return_offsets_mapping=_snake_case					,						return_length=_snake_case					,						verbose=_snake_case					,						return_tensors=_snake_case					,						**_snake_case					,						)
        if images is not None:
             UpperCAmelCase_          =							self.image_processor(
                 _snake_case					,						return_image_mask=_snake_case					,						return_codebook_pixels=_snake_case					,						return_tensors=_snake_case					,						**_snake_case					,						)

        if text is not None and images is not None:
             encoding.update(_snake_case)
             return encoding
        elif text is not None:
             return encoding
        else:
             return BatchEncoding(data=dict(**_snake_case)					,						tensor_type=_snake_case)







   def lowerCamelCase						(      self		:						Any					,						*_snake_case		:						Optional[Any]					,						**_snake_case		:						int):

        """simple docstring"""


        return self.tokenizer.batch_decode(*_snake_case					,						**_snake_case)







   def lowerCamelCase						(      self		:						Optional[int]					,						*_snake_case		:						int					,						**_snake_case		:						Dict):

        """simple docstring"""


        return self.tokenizer.decode(*_snake_case					,						**_snake_case)







   @property
   def lowerCamelCase						(      self		:						str):

        """simple docstring"""


        UpperCAmelCase_          =							self.tokenizer.model_input_names
        UpperCAmelCase_          =							self.image_processor.model_input_names
        return list(dict.fromkeys(tokenizer_input_names + image_processor_input_names))







   @property
   def lowerCamelCase						(      self		:						str):

        """simple docstring"""


        warnings.warn(
            '''`feature_extractor_class` is deprecated and will be removed in v5. Use `image_processor_class` instead.'''					,						_snake_case					,						)
        return self.image_processor_class







   @property
   def lowerCamelCase						(      self		:						Any):

        """simple docstring"""


        warnings.warn(
            '''`feature_extractor` is deprecated and will be removed in v5. Use `image_processor` instead.'''					,						_snake_case					,						)
        return self.image_processor






