






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  							=					True
except (ImportError, AttributeError):
	lowercase  							=					object





	def 						__UpperCAmelCase			(     *a_							,     **a_):
								pass




	lowercase  							=					False


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





def 						__UpperCAmelCase			(     a_):
							snake_case_				=							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  UpperCamelCase_      (			A__				):



	'''simple docstring'''




	lowerCAmelCase													= 42






class  UpperCamelCase_      (			A__				):



	'''simple docstring'''




	lowerCAmelCase													= 42
	lowerCAmelCase													= 42






class  UpperCamelCase_      (			A__				):



	'''simple docstring'''




	lowerCAmelCase													= 42






class  UpperCamelCase_      (			A__				):



	'''simple docstring'''




	lowerCAmelCase													= 42






class  UpperCamelCase_      (			A__				):



	'''simple docstring'''




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




	def __init__(       self       ,			a       ,			a       ,			a       ,			a					)       ->    Any:
								snake_case_				=							pipeline

								snake_case_				=							host
								snake_case_				=							port
								snake_case_				=							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_				=							FastAPI(
															    routes=[
															        APIRoute(
															            '/'       ,			self.model_info       ,			response_model=lowerCAmelCase__       ,			response_class=lowerCAmelCase__       ,			methods=['GET']       ,			),
															        APIRoute(
															            '/tokenize'       ,			self.tokenize       ,			response_model=lowerCAmelCase__       ,			response_class=lowerCAmelCase__       ,			methods=['POST']       ,			),
															        APIRoute(
															            '/detokenize'       ,			self.detokenize       ,			response_model=lowerCAmelCase__       ,			response_class=lowerCAmelCase__       ,			methods=['POST']       ,			),
															        APIRoute(
															            '/forward'       ,			self.forward       ,			response_model=lowerCAmelCase__       ,			response_class=lowerCAmelCase__       ,			methods=['POST']       ,			),
															    ]       ,			timeout=6_00       ,			)




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




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




	def 							_UpperCamelCase			(       self       ,			a = Body(lowerCAmelCase__       ,			embed=lowerCAmelCase__					)       ,			a = Body(lowerCAmelCase__       ,			embed=lowerCAmelCase__					)					)       ->    Any:
								try:
															snake_case_				=							self._pipeline.tokenizer.tokenize(lowerCAmelCase__					)

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

								except Exception as e:
															raise HTTPException(status_code=5_00       ,			detail={'model': '', 'error': str(lowerCAmelCase__					)}					)




	def 							_UpperCamelCase			(       self       ,			a = Body(lowerCAmelCase__       ,			embed=lowerCAmelCase__					)       ,			a = Body(lowerCAmelCase__       ,			embed=lowerCAmelCase__					)       ,			a = Body(lowerCAmelCase__       ,			embed=lowerCAmelCase__					)       ,			)       ->    List[Any]:
								try:
															snake_case_				=							self._pipeline.tokenizer.decode(lowerCAmelCase__       ,			lowerCAmelCase__       ,			lowerCAmelCase__					)
															return ServeDeTokenizeResult(model=''       ,			text=lowerCAmelCase__					)
								except Exception as e:
															raise HTTPException(status_code=5_00       ,			detail={'model': '', 'error': str(lowerCAmelCase__					)}					)






	async def 							_UpperCamelCase			(       self       ,			a=Body(lowerCAmelCase__       ,			embed=lowerCAmelCase__					)					)       ->    Optional[int]:

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

								try:
															# Forward through the model
															snake_case_				=							self._pipeline(lowerCAmelCase__					)
															return ServeForwardResult(output=lowerCAmelCase__					)
								except Exception as e:
															raise HTTPException(5_00       ,			{'error': str(lowerCAmelCase__					)}					)









import math_equivalence  # From: git+https://github.com/hendrycks/math.git

import datasets


__lowerCAmelCase	: Optional[Any]  				='\\n@article{hendrycksmath2021,\n  title={Measuring Mathematical Problem Solving With the MATH Dataset},\n  author={Dan Hendrycks\n    and Collin Burns\n    and Saurav Kadavath\n    and Akul Arora\n    and Steven Basart\n    and Eric Tang\n    and Dawn Song\n    and Jacob Steinhardt},\n  journal={arXiv preprint arXiv:2103.03874},\n  year={2021}\n}\n'


__lowerCAmelCase	: Any  				='\\nThis metric is used to assess performance on the Mathematics Aptitude Test of Heuristics (MATH) dataset.\nIt first canonicalizes the inputs (e.g., converting "1/2" to "\\frac{1}{2}") and then computes accuracy.\n'


__lowerCAmelCase	: Optional[Any]  				=r'\nCalculates accuracy after canonicalizing inputs.\n\nArgs:\n    predictions: list of predictions to score. Each prediction\n        is a string that contains natural language and LaTex.\n    references: list of reference for each prediction. Each\n        reference is a string that contains natural language\n        and LaTex.\nReturns:\n    accuracy: accuracy after canonicalizing inputs\n        (e.g., converting "1/2" to "\\frac{1}{2}")\n\nExamples:\n    >>> metric = datasets.load_metric("competition_math")\n    >>> results = metric.compute(references=["\\frac{1}{2}"], predictions=["1/2"])\n    >>> print(results)\n    {\'accuracy\': 1.0}\n'
@datasets.utils.file_utils.add_end_docstrings(_DESCRIPTION						,			_KWARGS_DESCRIPTION       )
class        _lowercase      (			datasets.Metric       ):






				'''simple docstring'''



				def 		__magic_name__(       self			:Optional[Any]	)		->			List[str]:
										return datasets.MetricInfo(
										    description=_DESCRIPTION			,			citation=_CITATION			,			inputs_description=_KWARGS_DESCRIPTION			,			features=datasets.Features(
										        {
										            '''predictions''': datasets.Value('''string'''	),
										            '''references''': datasets.Value('''string'''	),
										        }	)			,			homepage='''https://github.com/hendrycks/math'''			,			codebase_urls=['''https://github.com/hendrycks/math''']			,			)



				def 		__magic_name__(       self			:Any			,			lowerCAmelCase__			:Optional[int]			,			lowerCAmelCase__			:Any	)		->			Optional[int]:
										__SCREAMING_SNAKE_CASE						:     Tuple					=		0.0
										for i, j in zip(lowerCAmelCase__			,			lowerCAmelCase__	):
																n_correct += 1.0 if math_equivalence.is_equiv(lowerCAmelCase__			,			lowerCAmelCase__	) else 0.0
										__SCREAMING_SNAKE_CASE						:     str					=		n_correct / len(lowerCAmelCase__	)
										return {
										    "accuracy": accuracy,
										}
