# This code is a Qiskit project.## (C) Copyright IBM 2022.## This code is licensed under the Apache License, Version 2.0. You may# obtain a copy of this license in the LICENSE.txt file in the root directory# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.## Any modifications or derivative works of this code must retain this# copyright notice, and modified files need to carry a notice indicating# that they have been altered from the originals."""=====================================================Json utilities (:mod:`qiskit_serverless.utils.json`)=====================================================.. currentmodule:: qiskit_serverless.utils.jsonQiskit Serverless json utilities=================================.. autosummary:: :toctree: ../stubs/ JsonSerializable"""importjsonfromabcimportABC,abstractmethodfromjsonimportJSONEncoderfromtypingimportList,Optional,Type,Callable,Dict,Any,Unionimportrequestsfromqiskit_serverless.exceptionimportQiskitServerlessExceptionfromqiskit_serverless.utils.errorsimportformat_err_msg,ErrorCodes
[docs]classJsonSerializable(ABC):"""Classes that can be serialized as json."""@classmethod@abstractmethoddeffrom_dict(cls,dictionary:dict):"""Converts dict to object."""defto_dict(self)->dict:"""Converts class to dict."""result={}forkey,valinself.__dict__.items():ifkey.startswith("_"):continueelement=[]ifisinstance(val,list):foriteminval:ifisinstance(item,JsonSerializable):element.append(item.to_dict())else:element.append(item)elifisinstance(val,JsonSerializable):element=val.to_dict()# type: ignoreelse:element=valresult[key]=elementreturnresult
defis_jsonable(data,cls:Optional[Type[JSONEncoder]]=None):"""Check if data can be serialized to json."""try:json.dumps(data,cls=cls)returnTrueexcept(TypeError,OverflowError):returnFalsedefsafe_json_request_as_list(request:Callable,verbose:bool=False)->List[Any]:"""Returns parsed json data from request. Args: request: callable for request. verbose: post reason in error message Example: >>> safe_json_request(request=lambda: requests.get("https://ibm.com")) Returns: parsed json response as list structure """response=safe_json_request(request,verbose)ifisinstance(response,List):returnresponseraiseTypeError("JSON is not a List")defsafe_json_request_as_dict(request:Callable,verbose:bool=False)->Dict[str,Any]:"""Returns parsed json data from request. Args: request: callable for request. verbose: post reason in error message Example: >>> safe_json_request(request=lambda: requests.get("https://ibm.com")) Returns: parsed json response as dict structure """response=safe_json_request(request,verbose)ifisinstance(response,Dict):returnresponseraiseTypeError("JSON is not a Dict")defsafe_json_request(request:Callable,verbose:bool=False)->Union[Dict[str,Any],List[Any]]:"""Returns parsed json data from request. Args: request: callable for request. verbose: post reason in error message Example: >>> safe_json_request(request=lambda: requests.get("https://ibm.com")) Returns: parsed json response """error_message:Optional[str]=Nonetry:response=request()exceptrequests.exceptions.RequestExceptionasrequest_exception:error_message=format_err_msg(ErrorCodes.AUTH1001,str(request_exception.args)ifverboseelseNone,)response=Noneiferror_message:raiseQiskitServerlessException(error_message)ifresponseisnotNoneandnotresponse.ok:raiseQiskitServerlessException(format_err_msg(response.status_code,str(response.text)ifverboseelseNone,))decoding_error_message:Optional[str]=Nonetry:json_data=json.loads(response.text)exceptjson.JSONDecodeErrorasjson_error:decoding_error_message=format_err_msg(ErrorCodes.JSON1001,str(json_error.args)ifverboseelseNone,)json_data={}ifdecoding_error_message:raiseQiskitServerlessException(decoding_error_message)returnjson_data