Skip to content

Commit

Permalink
Introduce SeldonNotImplementedError
Browse files Browse the repository at this point in the history
  • Loading branch information
dtaniwaki committed Sep 11, 2019
1 parent ac0ea51 commit 95124d8
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 98 deletions.
54 changes: 30 additions & 24 deletions python/seldon_core/seldon_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ def predict(
logger.warning("predict_grpc is deprecated. Please use predict_raw")
return user_model.predict_grpc(request)
else:
try:
return user_model.predict_raw(request)
except NotImplementedError:
pass
if hasattr(user_model, "predict_raw"):
try:
return user_model.predict_raw(request)
except SeldonNotImplementedError:
pass

if is_proto:
(features, meta, datadef, data_type) = extract_request_parts(request)
Expand Down Expand Up @@ -76,10 +77,11 @@ def send_feedback(user_model: Any, request: prediction_pb2.Feedback,
response_json = user_model.send_feedback_grpc(request)
return json_to_seldon_message(response_json)
else:
try:
return user_model.send_feedback_raw(request)
except NotImplementedError:
pass
if hasattr(user_model, "send_feedback_raw"):
try:
return user_model.send_feedback_raw(request)
except SeldonNotImplementedError:
pass

(datadef_request, features, truth, reward) = extract_feedback_request_parts(request)
routing = request.response.meta.routing.get(predictive_unit_id)
Expand Down Expand Up @@ -116,10 +118,11 @@ def transform_input(user_model: Any, request: prediction_pb2.SeldonMessage) -> p
logger.warning("transform_input_grpc is deprecated. Please use transform_input_raw")
return user_model.transform_input_grpc(request)
else:
try:
return user_model.transform_input_raw(request)
except NotImplementedError:
pass
if hasattr(user_model, "transform_input_raw"):
try:
return user_model.transform_input_raw(request)
except SeldonNotImplementedError:
pass

(features, meta, datadef, data_type) = extract_request_parts(request)
client_response = client_transform_input(user_model, features, datadef.names, meta=meta)
Expand Down Expand Up @@ -152,10 +155,11 @@ def transform_output(user_model: Any,
logger.warning("transform_input_grpc is deprecated. Please use transform_input_raw")
return user_model.transform_output_grpc(request)
else:
try:
return user_model.transform_output_raw(request)
except NotImplementedError:
pass
if hasattr(user_model, "transform_output_raw"):
try:
return user_model.transform_output_raw(request)
except SeldonNotImplementedError:
pass

(features, meta, datadef, data_type) = extract_request_parts(request)
client_response = client_transform_output(user_model, features, datadef.names, meta=meta)
Expand Down Expand Up @@ -184,10 +188,11 @@ def route(user_model: Any, request: prediction_pb2.SeldonMessage) -> prediction_
logger.warning("route_grpc is deprecated. Please use route_raw")
return user_model.route_grpc(request)
else:
try:
return user_model.route_raw(request)
except NotImplementedError:
pass
if hasattr(user_model, "route_raw"):
try:
return user_model.route_raw(request)
except SeldonNotImplementedError:
pass

(features, meta, datadef, _) = extract_request_parts(request)
client_response = client_route(user_model, features, datadef.names)
Expand Down Expand Up @@ -222,10 +227,11 @@ def aggregate(user_model: Any, request: prediction_pb2.SeldonMessageList) -> pre
logger.warning("aggregate_grpc is deprecated. Please use aggregate_raw")
return user_model.aggregate_grpc(request)
else:
try:
return user_model.aggregate_raw(request)
except NotImplementedError:
pass
if hasattr(user_model, "aggregate_raw"):
try:
return user_model.aggregate_raw(request)
except SeldonNotImplementedError:
pass

features_list = []
names_list = []
Expand Down
167 changes: 93 additions & 74 deletions python/seldon_core/user_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,67 +9,70 @@

logger = logging.getLogger(__name__)

class SeldonNotImplementedError(SeldonMicroserviceException):
status_code = 403

class SeldonComponent(object):

def __init__(self, **kwargs):
pass

def tags(self) -> Dict:
raise NotImplementedError
raise SeldonNotImplementedError("tags is not implemented")

def class_names(self) -> Iterable[str]:
raise NotImplementedError
raise SeldonNotImplementedError("class_names is not implemented")

def load(self):
pass

def predict(self, X: np.ndarray, names: Iterable[str], meta: Dict = None) -> Union[
np.ndarray, List, str, bytes]:
raise NotImplementedError
raise SeldonNotImplementedError("predict is not implemented")

def predict_raw(self, msg: prediction_pb2.SeldonMessage) -> prediction_pb2.SeldonMessage:
raise NotImplementedError
raise SeldonNotImplementedError("predict_raw is not implemented")

def send_feedback_raw(self, feedback: prediction_pb2.Feedback) -> prediction_pb2.SeldonMessage:
raise NotImplementedError
raise SeldonNotImplementedError("send_feedback_raw is not implemented")

def transform_input(self, X: np.ndarray, names: Iterable[str], meta: Dict = None) -> Union[
np.ndarray, List, str, bytes]:
raise NotImplementedError
raise SeldonNotImplementedError("transform is not implemented")

def transform_input_raw(self, msg: prediction_pb2.SeldonMessage) -> prediction_pb2.SeldonMessage:
raise NotImplementedError
raise SeldonNotImplementedError("transform_input_raw is not implemented")

def transform_output(self, X: np.ndarray, names: Iterable[str], meta: Dict = None) -> Union[
np.ndarray, List, str, bytes]:
raise NotImplementedError
raise SeldonNotImplementedError("transform_output is not implemented")

def transform_output_raw(self, msg: prediction_pb2.SeldonMessage) -> prediction_pb2.SeldonMessage:
raise NotImplementedError
raise SeldonNotImplementedError("transform_output_raw is not implemented")

def metrics(self) -> List[Dict]:
raise NotImplementedError
raise SeldonNotImplementedError("metrics is not implemented")

def feature_names(self) -> Iterable[str]:
raise NotImplementedError
raise SeldonNotImplementedError("feature_names is not implemented")

def send_feedback(self, features: Union[np.ndarray, str, bytes], feature_names: Iterable[str], reward: float,
truth: Union[np.ndarray, str, bytes], routing: Union[int, None]) -> Union[
np.ndarray, List, str, bytes, None]:
raise NotImplementedError
raise SeldonNotImplementedError("send_feedback is not implemented")

def route(self, features: Union[np.ndarray, str, bytes], feature_names: Iterable[str]) -> int:
raise NotImplementedError
raise SeldonNotImplementedError("route is not implemented")

def route_raw(self, msg: prediction_pb2.SeldonMessage) -> prediction_pb2.SeldonMessage:
raise NotImplementedError
raise SeldonNotImplementedError("route_raw is not implemented")

def aggregate(self, features_list: List[Union[np.ndarray, str, bytes]], feature_names_list: List) -> Union[
np.ndarray, List, str, bytes]:
raise NotImplementedError
raise SeldonNotImplementedError("aggregate is not implemented")

def aggregate_raw(self, msgs: prediction_pb2.SeldonMessageList) -> prediction_pb2.SeldonMessage:
raise NotImplementedError
raise SeldonNotImplementedError("aggregate_raw is not implemented")


def client_custom_tags(user_model: SeldonComponent) -> Dict:
Expand All @@ -85,11 +88,13 @@ def client_custom_tags(user_model: SeldonComponent) -> Dict:
Dictionary of key value pairs
"""
try:
return user_model.tags()
except NotImplementedError:
logger.info("custom_tags is not implemented")
return {}
if hasattr(user_model, "tags"):
try:
return user_model.tags()
except SeldonNotImplementedError:
pass
logger.info("custom_tags is not implemented")
return {}


def client_class_names(user_model: SeldonComponent, predictions: np.ndarray) -> Iterable[str]:
Expand All @@ -107,16 +112,18 @@ def client_class_names(user_model: SeldonComponent, predictions: np.ndarray) ->
Class names
"""
if len(predictions.shape) > 1:
try:
if hasattr(user_model, "class_names"):
if inspect.ismethod(getattr(user_model, 'class_names')):
return user_model.class_names()
try:
return user_model.class_names()
except SeldonNotImplementedError:
pass
else:
logger.info("class_names attribute is deprecated. Please define a class_names method")
return user_model.class_names
except NotImplementedError:
logger.info("class_names is not implemented")
n_targets = predictions.shape[1]
return ["t:{}".format(i) for i in range(n_targets)]
logger.info("class_names is not implemented")
n_targets = predictions.shape[1]
return ["t:{}".format(i) for i in range(n_targets)]
else:
return []

Expand All @@ -140,14 +147,16 @@ def client_predict(user_model: SeldonComponent, features: Union[np.ndarray, str,
-------
A prediction from the user model
"""
try:
if hasattr(user_model, "predict"):
try:
return user_model.predict(features, feature_names, **kwargs)
except TypeError:
return user_model.predict(features, feature_names)
except NotImplementedError:
logger.info("predict is not implemented")
return []
try:
return user_model.predict(features, feature_names, **kwargs)
except TypeError:
return user_model.predict(features, feature_names)
except SeldonNotImplementedError:
pass
logger.info("predict is not implemented")
return []


def client_transform_input(user_model: SeldonComponent, features: Union[np.ndarray, str, bytes],
Expand All @@ -171,14 +180,16 @@ def client_transform_input(user_model: SeldonComponent, features: Union[np.ndarr
Transformed data
"""
try:
if hasattr(user_model, "transform_input"):
try:
return user_model.transform_input(features, feature_names, **kwargs)
except TypeError:
return user_model.transform_input(features, feature_names)
except NotImplementedError:
logger.info("transform_input is not implemented")
return features
try:
return user_model.transform_input(features, feature_names, **kwargs)
except TypeError:
return user_model.transform_input(features, feature_names)
except SeldonNotImplementedError:
pass
logger.info("transform_input is not implemented")
return features


def client_transform_output(user_model: SeldonComponent, features: Union[np.ndarray, str, bytes],
Expand All @@ -201,14 +212,16 @@ def client_transform_output(user_model: SeldonComponent, features: Union[np.ndar
Transformed data
"""
try:
if hasattr(user_model, "transform_output"):
try:
return user_model.transform_output(features, feature_names, **kwargs)
except TypeError:
return user_model.transform_output(features, feature_names)
except NotImplementedError:
logger.info("transform_output is not implemented")
return features
try:
return user_model.transform_output(features, feature_names, **kwargs)
except TypeError:
return user_model.transform_output(features, feature_names)
except SeldonNotImplementedError:
pass
logger.info("transform_output is not implemented")
return features


def client_custom_metrics(user_model: SeldonComponent) -> List[Dict]:
Expand All @@ -225,16 +238,18 @@ def client_custom_metrics(user_model: SeldonComponent) -> List[Dict]:
A list of custom metrics
"""
try:
metrics = user_model.metrics()
if not validate_metrics(metrics):
j_str = json.dumps(metrics)
raise SeldonMicroserviceException(
"Bad metric created during request: " + j_str, reason="MICROSERVICE_BAD_METRIC")
return metrics
except NotImplementedError:
logger.info("custom_metrics is not implemented")
return []
if hasattr(user_model, "metrics"):
try:
metrics = user_model.metrics()
if not validate_metrics(metrics):
j_str = json.dumps(metrics)
raise SeldonMicroserviceException(
"Bad metric created during request: " + j_str, reason="MICROSERVICE_BAD_METRIC")
return metrics
except SeldonNotImplementedError:
pass
logger.info("custom_metrics is not implemented")
return []


def client_feature_names(user_model: SeldonComponent, original: Iterable[str]) -> Iterable[str]:
Expand All @@ -251,11 +266,13 @@ def client_feature_names(user_model: SeldonComponent, original: Iterable[str]) -
-------
A list if feature names
"""
try:
return user_model.feature_names()
except NotImplementedError:
logger.info("feature_names is not implemented")
return original
if hasattr(user_model, "feature_names"):
try:
return user_model.feature_names()
except SeldonNotImplementedError:
pass
logger.info("feature_names is not implemented")
return original


def client_send_feedback(user_model: SeldonComponent, features: Union[np.ndarray, str, bytes],
Expand Down Expand Up @@ -285,11 +302,13 @@ def client_send_feedback(user_model: SeldonComponent, features: Union[np.ndarray
Optional payload
"""
try:
return user_model.send_feedback(features, feature_names, reward, truth, routing=routing)
except NotImplementedError:
logger.info("send_feedback is not implemented")
return None
if hasattr(user_model, "send_feedback"):
try:
return user_model.send_feedback(features, feature_names, reward, truth, routing=routing)
except SeldonNotImplementedError:
pass
logger.info("send_feedback is not implemented")
return None


def client_route(user_model: SeldonComponent, features: Union[np.ndarray, str, bytes],
Expand All @@ -310,10 +329,10 @@ def client_route(user_model: SeldonComponent, features: Union[np.ndarray, str, b
-------
Routing index for one of children
"""
try:
if hasattr(user_model, "route"):
return user_model.route(features, feature_names)
except NotImplementedError:
raise SeldonMicroserviceException("Route not defined")
else:
raise SeldonNotImplementedError("Route not defined")


def client_aggregate(user_model: SeldonComponent, features_list: List[Union[np.ndarray, str, bytes]],
Expand All @@ -333,7 +352,7 @@ def client_aggregate(user_model: SeldonComponent, features_list: List[Union[np.n
-------
An aggregated payload
"""
try:
if hasattr(user_model, "aggregate"):
return user_model.aggregate(features_list, feature_names_list)
except NotImplementedError:
raise SeldonMicroserviceException("Aggregate not defined")
else:
raise SeldonNotImplementedError("Aggregate not defined")

0 comments on commit 95124d8

Please sign in to comment.