




'''simple docstring'''







from argparse import ArgumentParser, Namespace
from typing import Any, List, Optional

from ..pipelines import Pipeline, get_supported_tasks, pipeline
from ..utils import logging
from . import BaseTransformersCLICommand


try:
      from fastapi import Body, FastAPI, HTTPException
      from fastapi.routing import APIRoute
      from pydantic import BaseModel
      from starlette.responses import JSONResponse
      from uvicorn import run

      lowercase      :   Tuple      =       True
except (ImportError, AttributeError):
      lowercase      :   str      =       object



      def        lowerCamelCase__				(      *__lowercase     ,   **__lowercase				):
           pass







      lowercase      :   int      =       False


lowercase      :   int      =       logging.get_logger("""transformers-cli/serving""")



def        lowerCamelCase__				(      __lowercase				):
     snake_case			:      List[str]        =			pipeline(
         task=args.task     ,   model=args.model if args.model else None     ,   config=args.config     ,   tokenizer=args.tokenizer     ,   device=args.device     ,   )
     return ServeCommand(__lowercase     ,   args.host     ,   args.port     ,   args.workers				)







class 					_a (a__	):





     '''simple docstring'''



     lowerCAmelCase_  :     dict







class 					_a (a__	):





     '''simple docstring'''



     lowerCAmelCase_  :     List[str]
     lowerCAmelCase_  :     Optional[List[int]]







class 					_a (a__	):





     '''simple docstring'''



     lowerCAmelCase_  :     str







class 					_a (a__	):





     '''simple docstring'''



     lowerCAmelCase_  :     Any







class 					_a (a__	):





     '''simple docstring'''



     @staticmethod
     def 			snake_case_      (				__a							)      ->				Dict:
          snake_case			:      Dict        =			parser.add_parser(
              """serve"""							,help="""CLI tool to run inference requests through REST and GraphQL endpoints."""							)
          serve_parser.add_argument(
              """--task"""							,type=__a							,choices=get_supported_tasks()							,help="""The task to run the pipeline on"""							,)
          serve_parser.add_argument("""--host"""							,type=__a							,default="""localhost"""							,help="""Interface the server will listen on."""							)
          serve_parser.add_argument("""--port"""							,type=__a							,default=8_888							,help="""Port the serving will listen to."""							)
          serve_parser.add_argument("""--workers"""							,type=__a							,default=1							,help="""Number of http workers"""							)
          serve_parser.add_argument("""--model"""							,type=__a							,help="""Model's name or path to stored model."""							)
          serve_parser.add_argument("""--config"""							,type=__a							,help="""Model's config name or path to stored model."""							)
          serve_parser.add_argument("""--tokenizer"""							,type=__a							,help="""Tokenizer name to use."""							)
          serve_parser.add_argument(
              """--device"""							,type=__a							,default=-1							,help="""Indicate the device to run onto, -1 indicates CPU, >= 0 indicates GPU (default: -1)"""							,)
          serve_parser.set_defaults(func=__a							)







     def __init__(				self							,__a							,__a							,__a							,__a							)      ->				Union[str, Any]:
          snake_case			:      List[Any]        =			pipeline

          snake_case			:      Optional[Any]        =			host
          snake_case			:      Optional[Any]        =			port
          snake_case			:      Dict        =			workers

          if not _serve_dependencies_installed:
               raise RuntimeError(
                   """Using serve command requires FastAPI and uvicorn. """
                   """Please install transformers with [serving]: pip install \"transformers[serving]\"."""
                   """Or install FastAPI and uvicorn separately."""							)
          else:
               logger.info(F'''Serving model over {host}:{port}'''							)
               snake_case			:      List[Any]        =			FastAPI(
                   routes=[
                       APIRoute(
                           """/"""							,self.model_info							,response_model=__a							,response_class=__a							,methods=["""GET"""]							,),
                       APIRoute(
                           """/tokenize"""							,self.tokenize							,response_model=__a							,response_class=__a							,methods=["""POST"""]							,),
                       APIRoute(
                           """/detokenize"""							,self.detokenize							,response_model=__a							,response_class=__a							,methods=["""POST"""]							,),
                       APIRoute(
                           """/forward"""							,self.forward							,response_model=__a							,response_class=__a							,methods=["""POST"""]							,),
                   ]							,timeout=600							,)







     def 			snake_case_      (				self							)      ->				Optional[int]:
          run(self._app							,host=self.host							,port=self.port							,workers=self.workers							)







     def 			snake_case_      (				self							)      ->				List[Any]:
          return ServeModelInfoResult(infos=vars(self._pipeline.model.config							)							)







     def 			snake_case_      (				self							,__a = Body(__a							,embed=__a							)							,__a = Body(__a							,embed=__a							)							)      ->				Optional[int]:
          try:
               snake_case			:      Dict        =			self._pipeline.tokenizer.tokenize(__a							)

               if return_ids:
                    snake_case			:      List[str]        =			self._pipeline.tokenizer.convert_tokens_to_ids(__a							)
                    return ServeTokenizeResult(tokens=__a							,tokens_ids=__a							)
               else:
                    return ServeTokenizeResult(tokens=__a							)

          except Exception as e:
               raise HTTPException(status_code=500							,detail={"""model""": """""", """error""": str(__a							)}							)







     def 			snake_case_      (				self							,__a = Body(__a							,embed=__a							)							,__a = Body(__a							,embed=__a							)							,__a = Body(__a							,embed=__a							)							,)      ->				List[Any]:
          try:
               snake_case			:      Any        =			self._pipeline.tokenizer.decode(__a							,__a							,__a							)
               return ServeDeTokenizeResult(model=""""""							,text=__a							)
          except Exception as e:
               raise HTTPException(status_code=500							,detail={"""model""": """""", """error""": str(__a							)}							)







     async def 			snake_case_      (				self							,__a=Body(__a							,embed=__a							)							)      ->				Optional[int]:

          # Check we don't have empty string
          if len(__a							) == 0:
               return ServeForwardResult(output=[]							,attention=[]							)

          try:
               # Forward through the model
               snake_case			:      Tuple        =			self._pipeline(__a							)
               return ServeForwardResult(output=__a							)
          except Exception as e:
               raise HTTPException(500							,{"""error""": str(__a							)}							)









'''simple docstring'''







from typing import Dict, Iterable, Optional, Union

import numpy as np

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import normalize, rescale, resize, to_channel_dimension_format, to_pil_image
from ...image_utils import (
    IMAGENET_STANDARD_MEAN,
    IMAGENET_STANDARD_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    make_list_of_images,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, is_pytesseract_available, is_vision_available, logging, requires_backends


if is_vision_available():
      import PIL

# soft dependency
if is_pytesseract_available():
      import pytesseract

lowercase      :   Optional[Any]      =       logging.get_logger(__name__)



def        lowerCamelCase__				(      __lowercase     ,   __lowercase     ,   __lowercase				):
     return [
         int(1_000 * (box[0] / width)				),
         int(1_000 * (box[1] / height)				),
         int(1_000 * (box[2] / width)				),
         int(1_000 * (box[3] / height)				),
     ]



def        lowerCamelCase__				(      __lowercase     ,   __lowercase     ,   __lowercase				):
     snake_case			:      List[Any]        =			to_pil_image(__lowercase				)
     snake_case ,		snake_case			:      Union[str, Any]        =			pil_image.size
     snake_case			:      Optional[Any]        =			pytesseract.image_to_data(__lowercase     ,   lang=__lowercase     ,   output_type="""dict"""     ,   config=__lowercase				)
     snake_case ,		snake_case ,		snake_case ,		snake_case ,		snake_case			:      Dict        =			data["""text"""], data["""left"""], data["""top"""], data["""width"""], data["""height"""]

     # filter empty words and corresponding coordinates
     snake_case			:      Tuple        =			[idx for idx, word in enumerate(__lowercase				) if not word.strip()]
     snake_case			:      Tuple        =			[word for idx, word in enumerate(__lowercase				) if idx not in irrelevant_indices]
     snake_case			:      str        =			[coord for idx, coord in enumerate(__lowercase				) if idx not in irrelevant_indices]
     snake_case			:      Tuple        =			[coord for idx, coord in enumerate(__lowercase				) if idx not in irrelevant_indices]
     snake_case			:      Optional[Any]        =			[coord for idx, coord in enumerate(__lowercase				) if idx not in irrelevant_indices]
     snake_case			:      Optional[Any]        =			[coord for idx, coord in enumerate(__lowercase				) if idx not in irrelevant_indices]

     # turn coordinates into (left, top, left+width, top+height) format
     snake_case			:      Dict        =			[]
     for x, y, w, h in zip(__lowercase     ,   __lowercase     ,   __lowercase     ,   __lowercase				):
          snake_case			:      Tuple        =			[x, y, x + w, y + h]
          actual_boxes.append(__lowercase				)

     # finally, normalize the bounding boxes
     snake_case			:      str        =			[]
     for box in actual_boxes:
          normalized_boxes.append(normalize_box(__lowercase     ,   __lowercase     ,   __lowercase				)				)

     assert len(__lowercase				) == len(__lowercase				), "Not as many words as there are bounding boxes"

     return words, normalized_boxes







class 					_a (a__	):





     '''simple docstring'''



     lowerCAmelCase_  :     Dict          =					["""pixel_values"""]







     def __init__(				self							,__a = True							,__a = None							,__a = PILImageResampling.BILINEAR							,__a = True							,__a = 1 / 255							,__a = True							,__a = None							,__a = None							,__a = True							,__a = None							,__a = ""							,**__a							,)      ->				None:
          super().__init__(**__a							)
          snake_case			:      int        =			size if size is not None else {"""height""": 224, """width""": 224}
          snake_case			:      Union[str, Any]        =			get_size_dict(__a							)

          snake_case			:      List[str]        =			do_resize
          snake_case			:      Dict        =			size
          snake_case			:      Dict        =			resample
          snake_case			:      Union[str, Any]        =			do_rescale
          snake_case			:      Union[str, Any]        =			rescale_value
          snake_case			:      List[str]        =			do_normalize
          snake_case			:      int        =			image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN
          snake_case			:      int        =			image_std if image_std is not None else IMAGENET_STANDARD_STD
          snake_case			:      List[Any]        =			apply_ocr
          snake_case			:      Any        =			ocr_lang
          snake_case			:      Optional[int]        =			tesseract_config







     def 			snake_case_      (				self							,__a							,__a							,__a = PILImageResampling.BILINEAR							,__a = None							,**__a							,)      ->				np.ndarray:
          snake_case			:      List[str]        =			get_size_dict(__a							)
          if "height" not in size or "width" not in size:
               raise ValueError(F'''The size dictionary must contain the keys \'height\' and \'width\'. Got {size.keys()}'''							)
          snake_case			:      Tuple        =			(size["""height"""], size["""width"""])
          return resize(__a							,size=__a							,resample=__a							,data_format=__a							,**__a							)







     def 			snake_case_      (				self							,__a							,__a							,__a = None							,**__a							,)      ->				np.ndarray:
          return rescale(__a							,scale=__a							,data_format=__a							,**__a							)







     def 			snake_case_      (				self							,__a							,__a							,__a							,__a = None							,**__a							,)      ->				np.ndarray:
          return normalize(__a							,mean=__a							,std=__a							,data_format=__a							,**__a							)







     def 			snake_case_      (				self							,__a							,__a = None							,__a = None							,__a=None							,__a = None							,__a = None							,__a = None							,__a = None							,__a = None							,__a = None							,__a = None							,__a = None							,__a = None							,__a = ChannelDimension.FIRST							,**__a							,)      ->				PIL.Image.Image:
          snake_case			:      int        =			do_resize if do_resize is not None else self.do_resize
          snake_case			:      List[Any]        =			size if size is not None else self.size
          snake_case			:      Any        =			get_size_dict(__a							)
          snake_case			:      Any        =			resample if resample is not None else self.resample
          snake_case			:      str        =			do_rescale if do_rescale is not None else self.do_rescale
          snake_case			:      List[str]        =			rescale_factor if rescale_factor is not None else self.rescale_factor
          snake_case			:      Dict        =			do_normalize if do_normalize is not None else self.do_normalize
          snake_case			:      Optional[int]        =			image_mean if image_mean is not None else self.image_mean
          snake_case			:      Tuple        =			image_std if image_std is not None else self.image_std
          snake_case			:      List[str]        =			apply_ocr if apply_ocr is not None else self.apply_ocr
          snake_case			:      str        =			ocr_lang if ocr_lang is not None else self.ocr_lang
          snake_case			:      Dict        =			tesseract_config if tesseract_config is not None else self.tesseract_config

          snake_case			:      Any        =			make_list_of_images(__a							)

          if not valid_images(__a							):
               raise ValueError(
                   """Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, """
                   """torch.Tensor, tf.Tensor or jax.ndarray."""							)

          if do_resize and size is None:
               raise ValueError("""Size must be specified if do_resize is True."""							)

          if do_rescale and rescale_factor is None:
               raise ValueError("""Rescale factor must be specified if do_rescale is True."""							)

          if do_normalize and (image_mean is None or image_std is None):
               raise ValueError("""If do_normalize is True, image_mean and image_std must be specified."""							)

          # All transformations expect numpy arrays.
          snake_case			:      Union[str, Any]        =			[to_numpy_array(__a							) for image in images]

          # Tesseract OCR to get words + normalized bounding boxes
          if apply_ocr:
               requires_backends(self							,"""pytesseract"""							)
               snake_case			:      int        =			[]
               snake_case			:      Optional[Any]        =			[]
               for image in images:
                    snake_case ,		snake_case			:      Tuple        =			apply_tesseract(__a							,__a							,__a							)
                    words_batch.append(__a							)
                    boxes_batch.append(__a							)

          if do_resize:
               snake_case			:      Any        =			[self.resize(image=__a							,size=__a							,resample=__a							) for image in images]

          if do_rescale:
               snake_case			:      Tuple        =			[self.rescale(image=__a							,scale=__a							) for image in images]

          if do_normalize:
               snake_case			:      Optional[Any]        =			[self.normalize(image=__a							,mean=__a							,std=__a							) for image in images]

          snake_case			:      Dict        =			[to_channel_dimension_format(__a							,__a							) for image in images]

          snake_case			:      List[Any]        =			BatchFeature(data={"""pixel_values""": images}							,tensor_type=__a							)

          if apply_ocr:
               snake_case			:      Optional[Any]        =			words_batch
               snake_case			:      Optional[int]        =			boxes_batch
          return data



