From e9ee7193a3aa2fca3507f26af8affb2e5adc7bcf Mon Sep 17 00:00:00 2001 From: Hugo Maingonnat Date: Wed, 25 Sep 2019 11:42:45 +0200 Subject: [PATCH 1/4] ServerError and ClientError to distinguish between 4xx and 5xx status code --- deepomatic/api/exceptions.py | 8 ++++++++ deepomatic/api/http_helper.py | 12 +++++++++--- tests/test_client.py | 4 ++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/deepomatic/api/exceptions.py b/deepomatic/api/exceptions.py index 7587ee9..126892d 100644 --- a/deepomatic/api/exceptions.py +++ b/deepomatic/api/exceptions.py @@ -68,6 +68,14 @@ def __str__(self): return "Bad status code %s with body %s" % (self.response.status_code, self.response.content) +class ClientError(BadStatus): + pass + + +class ServerError(BadStatus): + pass + + ############################################################################### class TaskError(DeepomaticException): diff --git a/deepomatic/api/http_helper.py b/deepomatic/api/http_helper.py index 3dadbd9..7ef2c5f 100644 --- a/deepomatic/api/http_helper.py +++ b/deepomatic/api/http_helper.py @@ -254,11 +254,17 @@ def make_request(self, func, resource, params=None, data=None, for file in opened_files: file.close() - if response.status_code == 204: # delete + status_code = response.status_code + if status_code == 204: # delete return None - if response.status_code < 200 or response.status_code >= 300: - raise BadStatus(response) + if status_code < 200 or status_code >= 300: + if status_code >= 400 and status_code < 500: + raise ClientError(response) + elif status_code >= 500 and status_code < 600: + raise ServerError(response) + else: + raise BadStatus(response) if stream: # we asked for a stream, we let the user download it as he wants or it will load everything in RAM diff --git a/tests/test_client.py b/tests/test_client.py index e58e24d..3afe8ab 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -14,7 +14,7 @@ import requests import six from deepomatic.api.client import Client -from deepomatic.api.exceptions import BadStatus, TaskTimeout, HTTPRetryError, TaskRetryError +from deepomatic.api.exceptions import ServerError, TaskTimeout, HTTPRetryError, TaskRetryError from deepomatic.api.http_retry import HTTPRetry from deepomatic.api.inputs import ImageInput from deepomatic.api.version import __title__, __version__ @@ -355,7 +355,7 @@ def test_no_retry_create_network(self): client = self.get_client_with_retry() # Creating network doesn't retry, we directly get a 502 t = time.time() - with pytest.raises(BadStatus) as exc: + with pytest.raises(ServerError) as exc: client.Network.create(name="My first network", framework='tensorflow-1.x', preprocessing=["useless"], From 63bd638e556ce439e2f71c32db2f1001da978774 Mon Sep 17 00:00:00 2001 From: Hugo Maingonnat Date: Wed, 25 Sep 2019 12:03:42 +0200 Subject: [PATCH 2/4] fix import --- deepomatic/api/http_helper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deepomatic/api/http_helper.py b/deepomatic/api/http_helper.py index 7ef2c5f..ac4ed86 100644 --- a/deepomatic/api/http_helper.py +++ b/deepomatic/api/http_helper.py @@ -29,7 +29,8 @@ import sys import requests -from deepomatic.api.exceptions import BadStatus, DeepomaticException +from deepomatic.api.exceptions import (BadStatus, ServerError, + ClientError, DeepomaticException) from deepomatic.api.http_retry import HTTPRetry from deepomatic.api.version import __title__, __version__ from requests.structures import CaseInsensitiveDict From 376fd20817f8ce1d20fddf450aa12f0374f8e157 Mon Sep 17 00:00:00 2001 From: Hugo Maingonnat Date: Wed, 25 Sep 2019 12:31:50 +0200 Subject: [PATCH 3/4] test ClientError --- tests/test_client.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_client.py b/tests/test_client.py index 3afe8ab..c46d265 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -299,6 +299,12 @@ def test_batch_wait(self, client): assert(tasks[pos].pk == success.pk) assert inference_schema(2, 0, 'golden retriever', 0.8) == success['data'] + def test_client_error(self): + spec = client.RecognitionSpec.retrieve('imagenet-inception-v3') + with pytest.raises(ClientError) as exc: + spec.inference(inputs=[ImageInput("")]) + assert 400 == exc.status_code + class TestClientRetry(object): DEFAULT_TIMEOUT = 2 From 07a41b4e1b8d76f469d0d86001374281d0680253 Mon Sep 17 00:00:00 2001 From: Hugo Maingonnat Date: Wed, 25 Sep 2019 14:09:21 +0200 Subject: [PATCH 4/4] Fixed test + doc --- deepomatic/api/exceptions.py | 11 +++++++++++ tests/test_client.py | 12 +++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/deepomatic/api/exceptions.py b/deepomatic/api/exceptions.py index 126892d..dc1ef71 100644 --- a/deepomatic/api/exceptions.py +++ b/deepomatic/api/exceptions.py @@ -50,6 +50,9 @@ def __init__(self): ############################################################################### class BadStatus(DeepomaticException): + """ + Thrown when HTTP response status_code < 200 or status_code >= 300. + """ def __init__(self, response): self.response = response @@ -69,10 +72,18 @@ def __str__(self): class ClientError(BadStatus): + """ + Thrown when HTTP response status_code is a 4xx. + The client sent a bad request. + """ pass class ServerError(BadStatus): + """ + Thrown when HTTP response status_code is a 5xx. + The request seems to be valid but the server couldn't handle it for some reason. + """ pass diff --git a/tests/test_client.py b/tests/test_client.py index c46d265..7931691 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -14,7 +14,7 @@ import requests import six from deepomatic.api.client import Client -from deepomatic.api.exceptions import ServerError, TaskTimeout, HTTPRetryError, TaskRetryError +from deepomatic.api.exceptions import ServerError, ClientError, TaskTimeout, HTTPRetryError, TaskRetryError from deepomatic.api.http_retry import HTTPRetry from deepomatic.api.inputs import ImageInput from deepomatic.api.version import __title__, __version__ @@ -299,11 +299,13 @@ def test_batch_wait(self, client): assert(tasks[pos].pk == success.pk) assert inference_schema(2, 0, 'golden retriever', 0.8) == success['data'] - def test_client_error(self): + def test_client_error(self, client): spec = client.RecognitionSpec.retrieve('imagenet-inception-v3') with pytest.raises(ClientError) as exc: - spec.inference(inputs=[ImageInput("")]) - assert 400 == exc.status_code + spec.inference(inputs=[]) + + assert 400 == exc.value.status_code + assert 'error' in exc.value.json() class TestClientRetry(object): @@ -366,7 +368,7 @@ def test_no_retry_create_network(self): framework='tensorflow-1.x', preprocessing=["useless"], files=["useless"]) - assert 502 == exc.status_code + assert 502 == exc.value.status_code assert time.time() - t < 0.3 def test_retry_task_with_http_errors(self):