




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






						'''simple docstring'''



						@staticmethod
						def 					A_    (  *lowercase  ,      **lowercase  ):
										pass







			def      _snake_case			(				lowercase__		):
							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 lowerCAmelCase__	(     unittest.TestCase						):






			'''simple docstring'''



			lowerCamelCase__      =			MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING
			@require_pytesseract
			@require_vision
			def 					A_    (  self  ,      lowercase  ,      lowercase  ,      lowercase  ):
							_lowerCamelCase     :			Optional[Any]    =    pipeline(
							    'document-question-answering'  ,      model=lowercase  ,      tokenizer=lowercase  ,      image_processor=lowercase  )

							_lowerCamelCase     :			Dict    =    INVOICE_URL
							_lowerCamelCase     :			List[str]    =    list(zip(*apply_tesseract(load_image(lowercase  )  ,      lowercase  ,      ''  )  )  )
							_lowerCamelCase     :			Optional[Any]    =    'What is the placebo?'
							_lowerCamelCase     :			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 					A_    (  self  ,      lowercase  ,      lowercase  ):
							_lowerCamelCase     :			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 					A_    (  self  ):
							_lowerCamelCase     :			List[Any]    =    pipeline('document-question-answering'  ,      model='hf-internal-testing/tiny-random-layoutlmv2'  )
							_lowerCamelCase     :			Optional[Any]    =    INVOICE_URL
							_lowerCamelCase     :			List[Any]    =    'How many cats are there?'

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

							_lowerCamelCase     :			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
							_lowerCamelCase     :			List[str]    =    './tests/fixtures/tests_samples/COCO/000000039769.png'
							_lowerCamelCase     :			List[str]    =    dqa_pipeline(image=lowercase  ,      question=lowercase  ,      top_k=2  )
							self.assertEqual(lowercase  ,      []  )

							# We can optionnally pass directly the words and bounding boxes
							_lowerCamelCase     :			Optional[Any]    =    './tests/fixtures/tests_samples/COCO/000000039769.png'
							_lowerCamelCase     :			Dict    =    []
							_lowerCamelCase     :			int    =    []
							_lowerCamelCase     :			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 					A_    (  self  ):
							_lowerCamelCase     :			Optional[int]    =    pipeline(
							    'document-question-answering'  ,      model='tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa'  ,      revision='9977165'  ,      )
							_lowerCamelCase     :			Union[str, Any]    =    INVOICE_URL
							_lowerCamelCase     :			str    =    'What is the invoice number?'

							_lowerCamelCase     :			Dict    =    dqa_pipeline(image=lowercase  ,      question=lowercase  ,      top_k=2  )
							self.assertEqual(
							    nested_simplify(lowercase  ,      decimals=4  )  ,      [
							        {'score': 0.99_44, 'answer': 'us-001', 'start': 16, 'end': 16},
							        {'score': 0.00_09, 'answer': 'us-001', 'start': 16, 'end': 16},
							    ]  ,      )

							_lowerCamelCase     :			Optional[Any]    =    dqa_pipeline({'image': image, 'question': question}  ,      top_k=2  )
							self.assertEqual(
							    nested_simplify(lowercase  ,      decimals=4  )  ,      [
							        {'score': 0.99_44, 'answer': 'us-001', 'start': 16, 'end': 16},
							        {'score': 0.00_09, '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(lowercase  ,      decimals=4  )  ,      [
							        [
							            {'score': 0.99_44, 'answer': 'us-001', 'start': 16, 'end': 16},
							            {'score': 0.00_09, 'answer': 'us-001', 'start': 16, 'end': 16},
							        ],
							    ]
							    * 2  ,      )
			@slow
			@require_torch
			@require_detectrona
			@require_pytesseract
			def 					A_    (  self  ):
							_lowerCamelCase     :			Optional[Any]    =    pipeline(
							    'document-question-answering'  ,      model='tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa'  ,      revision='9977165'  ,      max_seq_len=50  ,      )
							_lowerCamelCase     :			Optional[int]    =    INVOICE_URL
							_lowerCamelCase     :			List[Any]    =    'What is the invoice number?'

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

							_lowerCamelCase     :			Dict    =    dqa_pipeline({'image': image, 'question': question}  ,      top_k=2  )
							self.assertEqual(
							    nested_simplify(lowercase  ,      decimals=4  )  ,      [
							        {'score': 0.99_74, 'answer': '1110212019', 'start': 23, 'end': 23},
							        {'score': 0.99_48, '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(lowercase  ,      decimals=4  )  ,      [
							        [
							            {'score': 0.99_74, 'answer': '1110212019', 'start': 23, 'end': 23},
							            {'score': 0.99_48, 'answer': 'us-001', 'start': 16, 'end': 16},
							        ]
							    ]
							    * 2  ,      )
			@slow
			@require_torch
			@require_pytesseract
			@require_vision
			def 					A_    (  self  ):
							_lowerCamelCase     :			List[Any]    =    AutoTokenizer.from_pretrained(
							    'impira/layoutlm-document-qa'  ,      revision='3dc6de3'  ,      add_prefix_space=lowercase  )
							_lowerCamelCase     :			Tuple    =    pipeline(
							    'document-question-answering'  ,      model='impira/layoutlm-document-qa'  ,      tokenizer=lowercase  ,      revision='3dc6de3'  ,      )
							_lowerCamelCase     :			Optional[Any]    =    INVOICE_URL
							_lowerCamelCase     :			Tuple    =    'What is the invoice number?'

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

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

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

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

							# This model should also work if `image` is set to None
							_lowerCamelCase     :			Optional[Any]    =    dqa_pipeline({'image': None, 'word_boxes': word_boxes, 'question': question}  ,      top_k=2  )
							self.assertEqual(
							    nested_simplify(lowercase  ,      decimals=4  )  ,      [
							        {'score': 0.42_51, 'answer': 'us-001', 'start': 16, 'end': 16},
							        {'score': 0.08_19, 'answer': '1110212019', 'start': 23, 'end': 23},
							    ]  ,      )
			@slow
			@require_torch
			@require_pytesseract
			@require_vision
			def 					A_    (  self  ):
							_lowerCamelCase     :			Union[str, Any]    =    AutoTokenizer.from_pretrained(
							    'impira/layoutlm-document-qa'  ,      revision='3dc6de3'  ,      add_prefix_space=lowercase  )
							_lowerCamelCase     :			Optional[Any]    =    pipeline(
							    'document-question-answering'  ,      model='impira/layoutlm-document-qa'  ,      tokenizer=lowercase  ,      revision='3dc6de3'  ,      max_seq_len=50  ,      )
							_lowerCamelCase     :			Any    =    INVOICE_URL
							_lowerCamelCase     :			Tuple    =    'What is the invoice number?'

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

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

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

							# This model should also work if `image` is set to None
							_lowerCamelCase     :			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.99_99, 'answer': 'us-001', 'start': 16, 'end': 16},
							        {'score': 0.99_98, 'answer': 'us-001', 'start': 16, 'end': 16},
							    ]  ,      )
			@slow
			@require_torch
			def 					A_    (  self  ):
							_lowerCamelCase     :			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'  ,      )

							_lowerCamelCase     :			List[Any]    =    INVOICE_URL
							_lowerCamelCase     :			Any    =    'What is the invoice number?'
							_lowerCamelCase     :			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 					A_    (  self  ):
							pass





"""simple docstring"""






# Lint as: python3
import os
import re
import urllib.parse
from pathlib import Path
from typing import Callable, List, Optional, Union
from zipfile import ZipFile

from ..utils.file_utils import cached_path, hf_github_url
from ..utils.logging import get_logger
from ..utils.version import Version


lowercase__     						=						get_logger(__name__)






class lowerCAmelCase__	:






			'''simple docstring'''



			lowerCamelCase__      =			"""dummy_data"""
			lowerCamelCase__      =			"""datasets"""
			lowerCamelCase__      =			False
			def __init__(  self  ,      lowercase  ,      lowercase  ,      lowercase  ,      lowercase = None  ,      lowercase = False  ,      lowercase = True  ,      lowercase = None  ,      ):
							_lowerCamelCase     :			Optional[Any]    =    0
							_lowerCamelCase     :			Dict    =    dataset_name
							_lowerCamelCase     :			Union[str, Any]    =    cache_dir
							_lowerCamelCase     :			Dict    =    use_local_dummy_data
							_lowerCamelCase     :			Tuple    =    config
							# download_callbacks take a single url as input
							_lowerCamelCase     :			List[Callable]    =    download_callbacks or []
							# if False, it doesn't load existing files and it returns the paths of the dummy files relative
							# to the dummy_data zip file root
							_lowerCamelCase     :			Any    =    load_existing_dummy_data

							# TODO(PVP, QL) might need to make this more general
							_lowerCamelCase     :			str    =    str(lowercase  )
							# to be downloaded
							_lowerCamelCase     :			Union[str, Any]    =    None
							_lowerCamelCase     :			int    =    None
			@property
			def 					A_    (  self  ):
							if self._dummy_file is None:
											_lowerCamelCase     :			Tuple    =    self.download_dummy_data()
							return self._dummy_file
			@property
			def 					A_    (  self  ):
							if self.config is not None:
											# structure is dummy / config_name / version_name
											return os.path.join('dummy'  ,      self.config.name  ,      self.version_name  )
							# structure is dummy / version_name
							return os.path.join('dummy'  ,      self.version_name  )
			@property
			def 					A_    (  self  ):
							return os.path.join(self.dummy_data_folder  ,      'dummy_data.zip'  )
			def 					A_    (  self  ):
							_lowerCamelCase     :			List[str]    =    (
							    self.local_path_to_dummy_data if self.use_local_dummy_data is True else self.github_path_to_dummy_data
							)

							_lowerCamelCase     :			int    =    cached_path(
							    lowercase  ,      cache_dir=self.cache_dir  ,      extract_compressed_file=lowercase  ,      force_extract=lowercase  )

							return os.path.join(lowercase  ,      self.dummy_file_name  )
			@property
			def 					A_    (  self  ):
							return os.path.join(self.datasets_scripts_dir  ,      self.dataset_name  ,      self.dummy_zip_file  )
			@property
			def 					A_    (  self  ):
							if self._bucket_url is None:
											_lowerCamelCase     :			List[Any]    =    hf_github_url(self.dataset_name  ,      self.dummy_zip_file.replace(os.sep  ,      '/'  )  )
							return self._bucket_url
			@property
			def 					A_    (  self  ):
							# return full path if its a dir
							if os.path.isdir(self.dummy_file  ):
											return self.dummy_file
							# else cut off path to file -> example `xsum`.
							return "/".join(self.dummy_file.replace(os.sep  ,      '/'  ).split('/'  )[:-1]  )
			def 					A_    (  self  ,      lowercase  ,      *lowercase  ):
							if self.load_existing_dummy_data:
											# dummy data is downloaded and tested
											_lowerCamelCase     :			Union[str, Any]    =    self.dummy_file
							else:
											# dummy data cannot be downloaded and only the path to dummy file is returned
											_lowerCamelCase     :			Union[str, Any]    =    self.dummy_file_name

							# special case when data_url is a dict
							if isinstance(lowercase  ,      lowercase  ):
											return self.create_dummy_data_dict(lowercase  ,      lowercase  )
							elif isinstance(lowercase  ,      (list, tuple)  ):
											return self.create_dummy_data_list(lowercase  ,      lowercase  )
							else:
											return self.create_dummy_data_single(lowercase  ,      lowercase  )
			def 					A_    (  self  ,      lowercase  ,      *lowercase  ):
							return self.download_and_extract(lowercase  )
			def 					A_    (  self  ,      lowercase  ,      lowercase  ):
							return self.download_and_extract(lowercase  )
			def 					A_    (  self  ,      lowercase  ,      *lowercase  ,      **lowercase  ):
							return path
			def 					A_    (  self  ):
							return {}
			def 					A_    (  self  ,      lowercase  ,      lowercase  ):
							_lowerCamelCase     :			Optional[int]    =    {}
							for key, single_urls in data_url.items():
											for download_callback in self.download_callbacks:
															if isinstance(lowercase  ,      lowercase  ):
																			for single_url in single_urls:
																							download_callback(lowercase  )
															else:
																			_lowerCamelCase     :			List[Any]    =    single_urls
																			download_callback(lowercase  )
            # we force the name of each key to be the last file / folder name of the url path
            # if the url has arguments, we need to encode them with urllib.parse.quote_plus
											if isinstance(lowercase  ,      lowercase  ):
															_lowerCamelCase     :			List[Any]    =    [os.path.join(lowercase  ,      urllib.parse.quote_plus(Path(lowercase  ).name  )  ) for x in single_urls]
											else:
															_lowerCamelCase     :			Optional[int]    =    single_urls
															_lowerCamelCase     :			List[Any]    =    os.path.join(lowercase  ,      urllib.parse.quote_plus(Path(lowercase  ).name  )  )
											_lowerCamelCase     :			int    =    value

							# make sure that values are unique
							if all(isinstance(lowercase  ,      lowercase  ) for i in dummy_data_dict.values()  ) and len(set(dummy_data_dict.values()  )  ) < len(
							    dummy_data_dict.values()  ):
											# append key to value to make its name unique
											_lowerCamelCase     :			List[Any]    =    {key: value + key for key, value in dummy_data_dict.items()}

							return dummy_data_dict
			def 					A_    (  self  ,      lowercase  ,      lowercase  ):
							_lowerCamelCase     :			Optional[Any]    =    []
							# trick: if there are many shards named like `data.txt-000001-of-00300`, only use the first one
							_lowerCamelCase     :			List[str]    =    all(bool(re.findall('[0-9]{3,}-of-[0-9]{3,}'  ,      lowercase  )  ) for url in data_url  )
							_lowerCamelCase     :			int    =    all(
							    url.startswith('https://ftp.ncbi.nlm.nih.gov/pubmed/baseline/pubmed'  ) for url in data_url  )
							if data_url and (is_tf_records or is_pubmed_records):
											_lowerCamelCase     :			List[str]    =    [data_url[0]] * len(lowercase  )
							for single_url in data_url:
											for download_callback in self.download_callbacks:
															download_callback(lowercase  )
											# we force the name of each key to be the last file / folder name of the url path
											# if the url has arguments, we need to encode them with urllib.parse.quote_plus
											_lowerCamelCase     :			str    =    os.path.join(lowercase  ,      urllib.parse.quote_plus(single_url.split('/'  )[-1]  )  )
											dummy_data_list.append(lowercase  )
							return dummy_data_list
			def 					A_    (  self  ,      lowercase  ,      lowercase  ):
							for download_callback in self.download_callbacks:
											download_callback(lowercase  )
							# we force the name of each key to be the last file / folder name of the url path
							# if the url has arguments, we need to encode them with urllib.parse.quote_plus
							_lowerCamelCase     :			Tuple    =    os.path.join(lowercase  ,      urllib.parse.quote_plus(data_url.split('/'  )[-1]  )  )
							if os.path.exists(lowercase  ) or not self.load_existing_dummy_data:
											return value
							else:
											# Backward compatibility, maybe deprecate at one point.
											# For many datasets with single url calls to dl_manager.download_and_extract,
											# the dummy_data.zip file is actually the zipped downloaded file
											# while now we expected the dummy_data.zip file to be a directory containing
											# the downloaded file.
											return path_to_dummy_data
			def 					A_    (  self  ):
							pass
			def 					A_    (  self  ):
							pass
			def 					A_    (  self  ,      lowercase  ):
							def _iter_archive_members(lowercase  ):
											# this preserves the order of the members inside the ZIP archive
											_lowerCamelCase     :			str    =    Path(self.dummy_file  ).parent
											_lowerCamelCase     :			Union[str, Any]    =    path.relative_to(lowercase  )
											with ZipFile(self.local_path_to_dummy_data  ) as zip_file:
															_lowerCamelCase     :			List[str]    =    zip_file.namelist()
											for member in members:
															if member.startswith(relative_path.as_posix()  ):
																			yield dummy_parent_path.joinpath(lowercase  )

							_lowerCamelCase     :			Optional[int]    =    Path(lowercase  )
							_lowerCamelCase     :			Dict    =    _iter_archive_members(lowercase  ) if self.use_local_dummy_data else path.rglob('*'  )
							for file_path in file_paths:
											if file_path.is_file() and not file_path.name.startswith(('.', '__')  ):
															yield file_path.relative_to(lowercase  ).as_posix(), file_path.open('rb'  )






			def 					A_    (  self  ,      lowercase  ):
							if not isinstance(lowercase  ,      lowercase  ):
											_lowerCamelCase     :			List[str]    =    [paths]
							for path in paths:
											if os.path.isfile(lowercase  ):
															if os.path.basename(lowercase  ).startswith(('.', '__')  ):
																			return
															yield path
											else:
															for dirpath, dirnames, filenames in os.walk(lowercase  ):
																			if os.path.basename(lowercase  ).startswith(('.', '__')  ):
																							continue
																			dirnames.sort()
																			for filename in sorted(lowercase  ):
																							if filename.startswith(('.', '__')  ):
																											continue
																							yield os.path.join(lowercase  ,      lowercase  )