Skip to content

Commit 067adfa

Browse files
committed
Remove _call_method helper method and use a decorator
Rather than using a complicated way of calling the underlying model's methods (_call_method), lets call them directly, and then use a decorator that catchers the errors, raising exceptions accordingly.
1 parent 1f7f345 commit 067adfa

File tree

2 files changed

+43
-42
lines changed

2 files changed

+43
-42
lines changed

deepaas/model/v2/__init__.py

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,34 @@ def register_models():
6363
MODELS_LOADED = True
6464

6565

66+
def catch_error(f):
67+
"""Decorator to catch errors when executing the underlying methods."""
68+
69+
def wrap(*args, **kwargs):
70+
name = args[0].name
71+
try:
72+
return f(*args, **kwargs)
73+
except AttributeError:
74+
raise web.HTTPNotImplemented(
75+
reason=("Not implemented by underlying model (loaded '%s')" %
76+
name)
77+
)
78+
except NotImplementedError:
79+
raise web.HTTPNotImplemented(
80+
reason=("Model '%s' does not implement this functionality" %
81+
name)
82+
)
83+
except Exception as e:
84+
LOG.error("An exception has happened when calling '%s' method on "
85+
"'%s' model." % (f, name))
86+
LOG.exception(e)
87+
if isinstance(e, web.HTTPException):
88+
raise e
89+
else:
90+
raise web.HTTPInternalServerError(reason=e)
91+
return wrap
92+
93+
6694
class ModelWrapper(object):
6795
"""Class that will wrap the loaded models before exposing them.
6896
@@ -75,11 +103,11 @@ class ModelWrapper(object):
75103
:raises HTTPInternalServerError: in case that a model has defined
76104
a reponse schema that is nod JSON schema valid (DRAFT 4)
77105
"""
78-
def __init__(self, name, model):
106+
def __init__(self, name, model_obj):
79107
self.name = name
80-
self.model = model
108+
self.model_obj = model_obj
81109

82-
schema = getattr(self.model, "schema", None)
110+
schema = getattr(self.model_obj, "schema", None)
83111

84112
if isinstance(schema, dict):
85113
try:
@@ -139,29 +167,6 @@ def validate_response(self, response):
139167

140168
return True
141169

142-
def _call_method(self, method, *args, **kwargs):
143-
try:
144-
meth = getattr(self.model, method)
145-
return meth(*args, **kwargs)
146-
except AttributeError:
147-
raise web.HTTPNotImplemented(
148-
reason=("Not implemented by underlying model (loaded '%s')" %
149-
self.name)
150-
)
151-
except NotImplementedError:
152-
raise web.HTTPNotImplemented(
153-
reason=("Model '%s' does not implement this functionality" %
154-
self.name)
155-
)
156-
except Exception as e:
157-
LOG.error("An exception has happened when calling '%s' method on "
158-
"'%s' model." % (method, self.name))
159-
LOG.exception(e)
160-
if isinstance(e, web.HTTPException):
161-
raise e
162-
else:
163-
raise web.HTTPInternalServerError(reason=e)
164-
165170
def get_metadata(self):
166171
"""Obtain model's metadata.
167172
@@ -172,7 +177,7 @@ def get_metadata(self):
172177
:returns dict: dictionary containing model's metadata
173178
"""
174179
try:
175-
d = self.model.get_metadata()
180+
d = self.model_obj.get_metadata()
176181
except (NotImplementedError, AttributeError):
177182
d = {
178183
"id": "0",
@@ -182,14 +187,7 @@ def get_metadata(self):
182187
}
183188
return d
184189

185-
@property
186-
def response(self):
187-
"""Wrapped model's response schema.
188-
189-
Check :py:attr:`deepaas.v2.base.BaseModel.response` for more details.
190-
"""
191-
return getattr(self.model, "response", None)
192-
190+
@catch_error
193191
def predict(self, **kwargs):
194192
"""Perform a prediction on wrapped model's ``predict`` method.
195193
@@ -200,8 +198,9 @@ def predict(self, **kwargs):
200198
:raises HTTPException: If the call produces an
201199
error, already wrapped as a HTTPException
202200
"""
203-
return self._call_method("predict", **kwargs)
201+
return self.model_obj.predict(**kwargs)
204202

203+
@catch_error
205204
def train(self, *args, **kwargs):
206205
"""Perform a training on wrapped model's ``train`` method.
207206
@@ -212,8 +211,9 @@ def train(self, *args, **kwargs):
212211
:raises HTTPException: If the call produces an
213212
error, already wrapped as a HTTPException
214213
"""
215-
return self._call_method("train", *args, **kwargs)
214+
return self.model_obj.train(*args, **kwargs)
216215

216+
@catch_error
217217
def get_train_args(self):
218218
"""Add training arguments into the training parser.
219219
@@ -224,10 +224,11 @@ def get_train_args(self):
224224
``get_train_args`` we will try to load the arguments from there.
225225
"""
226226
try:
227-
return self._call_method("get_train_args")
228-
except web.HTTPNotImplemented:
227+
return self.model_obj.get_train_args()
228+
except (NotImplementedError, AttributeError):
229229
return {}
230230

231+
@catch_error
231232
def get_predict_args(self):
232233
"""Add predict arguments into the predict parser.
233234
@@ -238,6 +239,6 @@ def get_predict_args(self):
238239
``get_predict_args`` we will try to load the arguments from there.
239240
"""
240241
try:
241-
return self._call_method("get_predict_args")
242-
except web.HTTPNotImplemented:
242+
return self.model_obj.get_predict_args()
243+
except (NotImplementedError, AttributeError):
243244
return {}

deepaas/tests/test_v2_models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,4 @@ def test_loading_error(self, mock_loading):
182182
self.assertIn("deepaas-test", deepaas.model.v2.MODELS)
183183
m = deepaas.model.v2.MODELS.pop("deepaas-test")
184184
self.assertIsInstance(m, v2_model.ModelWrapper)
185-
self.assertIsInstance(m.model, v2_test.TestModel)
185+
self.assertIsInstance(m.model_obj, v2_test.TestModel)

0 commit comments

Comments
 (0)