



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

 SCREAMING_SNAKE_CASE__          =  True
except (ImportError, AttributeError):
 SCREAMING_SNAKE_CASE__          =  object




 def 							lowerCamelCase	(					*_snake_case	:    int  ,**_snake_case	:    Dict							):





     '''simple docstring'''


     pass



 SCREAMING_SNAKE_CASE__          =  False


SCREAMING_SNAKE_CASE__          =  logging.get_logger("transformers-cli/serving")




def 							lowerCamelCase	(					_snake_case	:    Namespace							):





    '''simple docstring'''


    lowercase__									=    pipeline(
        task=args.task  ,model=args.model if args.model else None  ,config=args.config  ,tokenizer=args.tokenizer  ,device=args.device  ,)
    return ServeCommand(_snake_case  ,args.host  ,args.port  ,args.workers							)


class 					snake_case			(UpperCamelCase ):
       lowerCAmelCase__	:dict





class 					snake_case			(UpperCamelCase ):
       lowerCAmelCase__	:List[str]
       lowerCAmelCase__	:Optional[List[int]]





class 					snake_case			(UpperCamelCase ):
       lowerCAmelCase__	:str





class 					snake_case			(UpperCamelCase ):
       lowerCAmelCase__	:Any





class 					snake_case			(UpperCamelCase ):



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



       def __init__(					self  ,UpperCAmelCase_  ,UpperCAmelCase_  ,UpperCAmelCase_  ,UpperCAmelCase_   )	->				Optional[int]:
           lowercase__									=    pipeline

           lowercase__									=    host
           lowercase__									=    port
           lowercase__									=    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}'''   )
               lowercase__									=    FastAPI(
                   routes=[
                       APIRoute(
                           "/"  ,self.model_info  ,response_model=UpperCAmelCase_  ,response_class=UpperCAmelCase_  ,methods=["GET"]  ,),
                       APIRoute(
                           "/tokenize"  ,self.tokenize  ,response_model=UpperCAmelCase_  ,response_class=UpperCAmelCase_  ,methods=["POST"]  ,),
                       APIRoute(
                           "/detokenize"  ,self.detokenize  ,response_model=UpperCAmelCase_  ,response_class=UpperCAmelCase_  ,methods=["POST"]  ,),
                       APIRoute(
                           "/forward"  ,self.forward  ,response_model=UpperCAmelCase_  ,response_class=UpperCAmelCase_  ,methods=["POST"]  ,),
                   ]  ,timeout=600  ,)



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



       def 				_a   (					self   )	->				Any:
           return ServeModelInfoResult(infos=vars(self._pipeline.model.config   )   )



       def 				_a   (					self  ,UpperCAmelCase_ = Body(UpperCAmelCase_  ,embed=UpperCAmelCase_   )  ,UpperCAmelCase_ = Body(UpperCAmelCase_  ,embed=UpperCAmelCase_   )   )	->				Union[str, Any]:
           try:
               lowercase__									=    self._pipeline.tokenizer.tokenize(UpperCAmelCase_   )

               if return_ids:
                   lowercase__									=    self._pipeline.tokenizer.convert_tokens_to_ids(UpperCAmelCase_   )
                   return ServeTokenizeResult(tokens=UpperCAmelCase_  ,tokens_ids=UpperCAmelCase_   )
               else:
                   return ServeTokenizeResult(tokens=UpperCAmelCase_   )

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



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







       async def 				_a   (					self  ,UpperCAmelCase_=Body(UpperCAmelCase_  ,embed=UpperCAmelCase_   )   )	->				Any:

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

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









'''simple docstring'''





import logging
import os
import threading
import time


try:
 import warnings
except ImportError:
 SCREAMING_SNAKE_CASE__          =  None

try:
 import msvcrt
except ImportError:
 SCREAMING_SNAKE_CASE__          =  None

try:
 import fcntl
except ImportError:
 SCREAMING_SNAKE_CASE__          =  None


# Backward compatibility
# ------------------------------------------------
try:
 TimeoutError
except NameError:
 SCREAMING_SNAKE_CASE__          =  OSError


# Data
# ------------------------------------------------
SCREAMING_SNAKE_CASE__          =  [
    "Timeout",
    "BaseFileLock",
    "WindowsFileLock",
    "UnixFileLock",
    "SoftFileLock",
    "FileLock",
]

SCREAMING_SNAKE_CASE__          =  "3.0.12"


SCREAMING_SNAKE_CASE__          =  None




def 							lowerCamelCase	(					):





    '''simple docstring'''


    global _logger
    lowercase__									=    _logger or logging.getLogger(__name__							)
    return _logger


class 					snake_case			(UpperCamelCase ):



       def __init__(					self  ,UpperCAmelCase_   )	->				int:
           lowercase__									=    lock_file
           return None







       def __str__(					self   )	->				Union[str, Any]:
           lowercase__									=    F'''The file lock \'{self.lock_file}\' could not be acquired.'''
           return temp





class 					snake_case			:



       def __init__(					self  ,UpperCAmelCase_   )	->				List[Any]:
           lowercase__									=    lock
           return None



       def __enter__(					self   )	->				Optional[int]:
           return self.lock







       def __exit__(					self  ,UpperCAmelCase_  ,UpperCAmelCase_  ,UpperCAmelCase_   )	->				int:
           self.lock.release()
           return None





class 					snake_case			:



       def __init__(					self  ,UpperCAmelCase_  ,UpperCAmelCase_=-1  ,UpperCAmelCase_=None   )	->				Tuple:
           lowercase__									=    max_filename_length if max_filename_length is not None else 255
           # Hash the filename if it's too long
           lowercase__									=    self.hash_filename_if_too_long(UpperCAmelCase_  ,UpperCAmelCase_   )
           # The path to the lock file.
           lowercase__									=    lock_file

           # The file descriptor for the *_lock_file* as it is returned by the
           # os.open() function.
           # This file lock is only NOT None, if the object currently holds the
           # lock.
           lowercase__									=    None

           # The default timeout value.
           lowercase__									=    timeout

           # We use this lock primarily for the lock counter.
           lowercase__									=    threading.Lock()

           # The lock counter is used for implementing the nested locking
           # mechanism. Whenever the lock is acquired, the counter is increased and
           # the lock is only released, when this value is 0 again.
           lowercase__									=    0
           return None



       @property
       def 				_a   (					self   )	->				List[str]:
           return self._lock_file



       @property
       def 				_a   (					self   )	->				Optional[int]:
           return self._timeout



       @timeout.setter
       def 				_a   (					self  ,UpperCAmelCase_   )	->				Optional[Any]:
           lowercase__									=    float(UpperCAmelCase_   )
           return None



       def 				_a   (					self   )	->				Optional[Any]:
           raise NotImplementedError()



       def 				_a   (					self   )	->				Optional[int]:
           raise NotImplementedError()



       @property
       def 				_a   (					self   )	->				Dict:
           return self._lock_file_fd is not None



       def 				_a   (					self  ,UpperCAmelCase_=None  ,UpperCAmelCase_=0.05   )	->				Optional[Any]:
           # Use the default timeout, if no timeout is provided.
           if timeout is None:
               lowercase__									=    self.timeout

           # Increment the number right at the beginning.
           # We can still undo it, if something fails.
           with self._thread_lock:
               self._lock_counter += 1

           lowercase__									=    id(self   )
           lowercase__									=    self._lock_file
           lowercase__									=    time.time()
           try:
               while True:
                   with self._thread_lock:
                       if not self.is_locked:
                           logger().debug(F'''Attempting to acquire lock {lock_id} on {lock_filename}'''   )
                           self._acquire()

                   if self.is_locked:
                       logger().debug(F'''Lock {lock_id} acquired on {lock_filename}'''   )
                       break
                   elif timeout >= 0 and time.time() - start_time > timeout:
                       logger().debug(F'''Timeout on acquiring lock {lock_id} on {lock_filename}'''   )
                       raise Timeout(self._lock_file   )
                   else:
                       logger().debug(
                           F'''Lock {lock_id} not acquired on {lock_filename}, waiting {poll_intervall} seconds ...'''   )
                       time.sleep(UpperCAmelCase_   )
           except:  # noqa
               # Something did go wrong, so decrement the counter.
               with self._thread_lock:
                   lowercase__									=    max(0  ,self._lock_counter - 1   )

               raise
           return _Acquire_ReturnProxy(lock=self   )



       def 				_a   (					self  ,UpperCAmelCase_=False   )	->				List[Any]:
           with self._thread_lock:
               if self.is_locked:
                   self._lock_counter -= 1

                   if self._lock_counter == 0 or force:
                       lowercase__									=    id(self   )
                       lowercase__									=    self._lock_file

                       logger().debug(F'''Attempting to release lock {lock_id} on {lock_filename}'''   )
                       self._release()
                       lowercase__									=    0
                       logger().debug(F'''Lock {lock_id} released on {lock_filename}'''   )

           return None



       def __enter__(					self   )	->				Dict:
           self.acquire()
           return self



       def __exit__(					self  ,UpperCAmelCase_  ,UpperCAmelCase_  ,UpperCAmelCase_   )	->				int:
           self.release()
           return None



       def __del__(					self   )	->				Union[str, Any]:
           self.release(force=UpperCAmelCase_   )
           return None







       def 				_a   (					self  ,UpperCAmelCase_  ,UpperCAmelCase_   )	->				str:
           lowercase__									=    os.path.basename(UpperCAmelCase_   )
           if len(UpperCAmelCase_   ) > max_length and max_length > 0:
               lowercase__									=    os.path.dirname(UpperCAmelCase_   )
               lowercase__									=    str(hash(UpperCAmelCase_   )   )
               lowercase__									=    filename[: max_length - len(UpperCAmelCase_   ) - 8] + "..." + hashed_filename + ".lock"
               return os.path.join(UpperCAmelCase_  ,UpperCAmelCase_   )
           else:
               return path





class 					snake_case			(UpperCamelCase ):



       def __init__(					self  ,UpperCAmelCase_  ,UpperCAmelCase_=-1  ,UpperCAmelCase_=None   )	->				Dict:
           from .file_utils import relative_to_absolute_path

           super().__init__(UpperCAmelCase_  ,timeout=UpperCAmelCase_  ,max_filename_length=UpperCAmelCase_   )
           lowercase__									=    "\\\\?\\" + relative_to_absolute_path(self.lock_file   )



       def 				_a   (					self   )	->				List[str]:
           lowercase__									=    os.O_RDWR | os.O_CREAT | os.O_TRUNC

           try:
               lowercase__									=    os.open(self._lock_file  ,UpperCAmelCase_   )
           except OSError:
               pass
           else:
               try:
                   msvcrt.locking(UpperCAmelCase_  ,msvcrt.LK_NBLCK  ,1   )
               except OSError:
                   os.close(UpperCAmelCase_   )
               else:
                   lowercase__									=    fd
           return None







       def 				_a   (					self   )	->				Any:
           lowercase__									=    self._lock_file_fd
           lowercase__									=    None
           msvcrt.locking(UpperCAmelCase_  ,msvcrt.LK_UNLCK  ,1   )
           os.close(UpperCAmelCase_   )

           try:
               os.remove(self._lock_file   )
           # Probably another instance of the application
           # that acquired the file lock.
           except OSError:
               pass
           return None





class 					snake_case			(UpperCamelCase ):



       def __init__(					self  ,UpperCAmelCase_  ,UpperCAmelCase_=-1  ,UpperCAmelCase_=None   )	->				int:
           lowercase__									=    os.statvfs(os.path.dirname(UpperCAmelCase_   )   ).f_namemax
           super().__init__(UpperCAmelCase_  ,timeout=UpperCAmelCase_  ,max_filename_length=UpperCAmelCase_   )



       def 				_a   (					self   )	->				List[str]:
           lowercase__									=    os.O_RDWR | os.O_CREAT | os.O_TRUNC
           lowercase__									=    os.open(self._lock_file  ,UpperCAmelCase_   )

           try:
               fcntl.flock(UpperCAmelCase_  ,fcntl.LOCK_EX | fcntl.LOCK_NB   )
           except OSError:
               os.close(UpperCAmelCase_   )
           else:
               lowercase__									=    fd
           return None







       def 				_a   (					self   )	->				int:
           # Do not remove the lockfile:
           #
           #   https://github.com/benediktschmitt/py-filelock/issues/31
           #   https://stackoverflow.com/questions/17708885/flock-removing-locked-file-without-race-condition
           lowercase__									=    self._lock_file_fd
           lowercase__									=    None
           fcntl.flock(UpperCAmelCase_  ,fcntl.LOCK_UN   )
           os.close(UpperCAmelCase_   )
           return None





class 					snake_case			(UpperCamelCase ):



       def 				_a   (					self   )	->				Optional[Any]:
           lowercase__									=    os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_TRUNC
           try:
               lowercase__									=    os.open(self._lock_file  ,UpperCAmelCase_   )
           except OSError:
               pass
           else:
               lowercase__									=    fd
           return None







       def 				_a   (					self   )	->				Tuple:
           os.close(self._lock_file_fd   )
           lowercase__									=    None

           try:
               os.remove(self._lock_file   )
           # The file is already deleted and that's what we want.
           except OSError:
               pass
           return None





SCREAMING_SNAKE_CASE__          =  None

if msvcrt:
 SCREAMING_SNAKE_CASE__          =  WindowsFileLock
elif fcntl:
 SCREAMING_SNAKE_CASE__          =  UnixFileLock
else:
 SCREAMING_SNAKE_CASE__          =  SoftFileLock

 if warnings is not None:
  warnings.warn("only soft file lock is available")




