wallaroo.inference_result
1import datetime 2import pprint 3from typing import Any, Dict, List, Optional, Tuple, Union 4 5import gql # type: ignore 6import numpy 7 8from .inference_decode import decode_inference_result, to_nd_array_list 9from .object import InferenceError 10 11 12class InferenceResult(object): 13 def __init__(self, gql_client: Optional[gql.Client], data: Dict[str, Any]) -> None: 14 """Initializes an InferenceResult. 15 16 :param gql.Client gql_client: GQL client that this can pass to created objects. 17 :param Dict[str, Any] data: Response parsed from JSON inference result body. 18 """ 19 if "error" in data: 20 raise InferenceError(data) 21 22 self._model = (data["model_name"], data["model_version"]) 23 self._input_data = data["original_data"] 24 # Assumes that timestamp comes back in integer milliseconds since epoch 25 self._timestamp = datetime.datetime.fromtimestamp(data["time"] / 1000) 26 # Assumes that elapsed time comes back in integer nanoseconds 27 self._time_elapsed = datetime.timedelta(microseconds=data["elapsed"] / 1000) 28 29 # TODO: we may want to match on key types and special case them, but 30 # this handles all types in a reasonable fashion (i.e. exactly the 31 # same) 32 self._data: List[numpy.ndarray] = to_nd_array_list( 33 decode_inference_result(data) 34 ) 35 if "shadow_data" in data: 36 self._shadow_data: Union[Dict[str, numpy.ndarray], None] = { 37 shadow_model: sd for shadow_model, sd in data["shadow_data"].items() 38 } 39 else: 40 self._shadow_data = None 41 self.raw = data 42 43 def data(self) -> List[numpy.ndarray]: 44 """Returns the inference result data.""" 45 return self._data 46 47 def model(self) -> Tuple[str, str]: 48 """Returns the model this inference was generated by.""" 49 # Model is currently passed back as model class + model name, which will 50 # necessitate passing the client through the deployment to here in order 51 # to call `model_by_name`. Better is to pass the DB surrogate key, which 52 # we can construct the object off of. 53 # 54 # For now, just return the two names, and the caller can use a client to 55 # turn this back into a Model if they wish. 56 return self._model 57 58 def time_elapsed(self) -> datetime.timedelta: 59 """Returns the length of time required for inference.""" 60 return self._time_elapsed 61 62 def timestamp(self) -> datetime.datetime: 63 """Returns the time at which this inference occurred.""" 64 return self._timestamp 65 66 def input_data(self) -> Dict[str, Any]: 67 """Returns the input data for this inference result.""" 68 return self._input_data 69 70 def __repr__(self) -> str: 71 return f"InferenceResult({pprint.pformat(self.raw)})" 72 73 def __str__(self) -> str: 74 return repr(self) 75 76 def shadow_data(self) -> Union[Dict[str, numpy.ndarray], None]: 77 return self._shadow_data
class
InferenceResult:
13class InferenceResult(object): 14 def __init__(self, gql_client: Optional[gql.Client], data: Dict[str, Any]) -> None: 15 """Initializes an InferenceResult. 16 17 :param gql.Client gql_client: GQL client that this can pass to created objects. 18 :param Dict[str, Any] data: Response parsed from JSON inference result body. 19 """ 20 if "error" in data: 21 raise InferenceError(data) 22 23 self._model = (data["model_name"], data["model_version"]) 24 self._input_data = data["original_data"] 25 # Assumes that timestamp comes back in integer milliseconds since epoch 26 self._timestamp = datetime.datetime.fromtimestamp(data["time"] / 1000) 27 # Assumes that elapsed time comes back in integer nanoseconds 28 self._time_elapsed = datetime.timedelta(microseconds=data["elapsed"] / 1000) 29 30 # TODO: we may want to match on key types and special case them, but 31 # this handles all types in a reasonable fashion (i.e. exactly the 32 # same) 33 self._data: List[numpy.ndarray] = to_nd_array_list( 34 decode_inference_result(data) 35 ) 36 if "shadow_data" in data: 37 self._shadow_data: Union[Dict[str, numpy.ndarray], None] = { 38 shadow_model: sd for shadow_model, sd in data["shadow_data"].items() 39 } 40 else: 41 self._shadow_data = None 42 self.raw = data 43 44 def data(self) -> List[numpy.ndarray]: 45 """Returns the inference result data.""" 46 return self._data 47 48 def model(self) -> Tuple[str, str]: 49 """Returns the model this inference was generated by.""" 50 # Model is currently passed back as model class + model name, which will 51 # necessitate passing the client through the deployment to here in order 52 # to call `model_by_name`. Better is to pass the DB surrogate key, which 53 # we can construct the object off of. 54 # 55 # For now, just return the two names, and the caller can use a client to 56 # turn this back into a Model if they wish. 57 return self._model 58 59 def time_elapsed(self) -> datetime.timedelta: 60 """Returns the length of time required for inference.""" 61 return self._time_elapsed 62 63 def timestamp(self) -> datetime.datetime: 64 """Returns the time at which this inference occurred.""" 65 return self._timestamp 66 67 def input_data(self) -> Dict[str, Any]: 68 """Returns the input data for this inference result.""" 69 return self._input_data 70 71 def __repr__(self) -> str: 72 return f"InferenceResult({pprint.pformat(self.raw)})" 73 74 def __str__(self) -> str: 75 return repr(self) 76 77 def shadow_data(self) -> Union[Dict[str, numpy.ndarray], None]: 78 return self._shadow_data
InferenceResult(gql_client: Optional[gql.client.Client], data: Dict[str, Any])
14 def __init__(self, gql_client: Optional[gql.Client], data: Dict[str, Any]) -> None: 15 """Initializes an InferenceResult. 16 17 :param gql.Client gql_client: GQL client that this can pass to created objects. 18 :param Dict[str, Any] data: Response parsed from JSON inference result body. 19 """ 20 if "error" in data: 21 raise InferenceError(data) 22 23 self._model = (data["model_name"], data["model_version"]) 24 self._input_data = data["original_data"] 25 # Assumes that timestamp comes back in integer milliseconds since epoch 26 self._timestamp = datetime.datetime.fromtimestamp(data["time"] / 1000) 27 # Assumes that elapsed time comes back in integer nanoseconds 28 self._time_elapsed = datetime.timedelta(microseconds=data["elapsed"] / 1000) 29 30 # TODO: we may want to match on key types and special case them, but 31 # this handles all types in a reasonable fashion (i.e. exactly the 32 # same) 33 self._data: List[numpy.ndarray] = to_nd_array_list( 34 decode_inference_result(data) 35 ) 36 if "shadow_data" in data: 37 self._shadow_data: Union[Dict[str, numpy.ndarray], None] = { 38 shadow_model: sd for shadow_model, sd in data["shadow_data"].items() 39 } 40 else: 41 self._shadow_data = None 42 self.raw = data
Initializes an InferenceResult.
Parameters
- gql.Client gql_client: GQL client that this can pass to created objects.
- Dict[str, Any] data: Response parsed from JSON inference result body.
def
data(self) -> List[numpy.ndarray]:
44 def data(self) -> List[numpy.ndarray]: 45 """Returns the inference result data.""" 46 return self._data
Returns the inference result data.
def
model(self) -> Tuple[str, str]:
48 def model(self) -> Tuple[str, str]: 49 """Returns the model this inference was generated by.""" 50 # Model is currently passed back as model class + model name, which will 51 # necessitate passing the client through the deployment to here in order 52 # to call `model_by_name`. Better is to pass the DB surrogate key, which 53 # we can construct the object off of. 54 # 55 # For now, just return the two names, and the caller can use a client to 56 # turn this back into a Model if they wish. 57 return self._model
Returns the model this inference was generated by.
def
time_elapsed(self) -> datetime.timedelta:
59 def time_elapsed(self) -> datetime.timedelta: 60 """Returns the length of time required for inference.""" 61 return self._time_elapsed
Returns the length of time required for inference.
def
timestamp(self) -> datetime.datetime:
63 def timestamp(self) -> datetime.datetime: 64 """Returns the time at which this inference occurred.""" 65 return self._timestamp
Returns the time at which this inference occurred.