8
8
## Const
9
9
DEFAULT_API_KEY = ""
10
10
DEFAULT_TIMEOUT = 10 # seconds
11
+ DEFAULT_IP = "localhost"
12
+ DEFAULT_PORT = 80
11
13
12
14
## HTTP codes
13
15
HTTP_OK = 200
14
16
BAD_URL = 404
15
17
16
18
## API urls
17
- URL_CUSTOM = "http://{ip}:{port}/v1/vision/custom/{custom_model}"
18
- URL_OBJECT_DETECTION = "http://{ip}:{port}/v1/vision/detection"
19
- URL_FACE_DETECTION = "http://{ip}:{port}/v1/vision/face"
20
- URL_FACE_REGISTER = "http://{ip}:{port}/v1/vision/face/register"
21
- URL_FACE_RECOGNIZE = "http://{ip}:{port}/v1/vision/face/recognize"
22
- URL_SCENE_DETECTION = "http://{ip}:{port}/v1/vision/scene"
19
+ URL_BASE_VISION = "http://{ip}:{port}/v1/vision"
20
+ URL_CUSTOM = "/custom/{custom_model}"
21
+ URL_OBJECT_DETECTION = "/detection"
22
+ URL_FACE_DETECTION = "/face"
23
+ URL_FACE_REGISTER = "/face/register"
24
+ URL_FACE_RECOGNIZE = "/face/recognize"
25
+ URL_SCENE_DETECTION = "/scene"
26
+
27
+
28
+ class DeepstackException (Exception ):
29
+ pass
23
30
24
31
25
32
def format_confidence (confidence : Union [str , float ]) -> float :
26
- """Takes a confidence from the API like
33
+ """
34
+ Takes a confidence from the API like
27
35
0.55623 and returns 55.6 (%).
28
36
"""
29
37
DECIMALS = 1
30
38
return round (float (confidence ) * 100 , DECIMALS )
31
39
32
40
33
- def get_confidences_above_threshold (confidences : List [float ], confidence_threshold : float ) -> List [float ]:
41
+ def get_confidences_above_threshold (
42
+ confidences : List [float ], confidence_threshold : float
43
+ ) -> List [float ]:
34
44
"""Takes a list of confidences and returns those above a confidence_threshold."""
35
45
return [val for val in confidences if val >= confidence_threshold ]
36
46
@@ -58,11 +68,15 @@ def get_objects(predictions: List[Dict]) -> List[str]:
58
68
return sorted (list (set (labels )))
59
69
60
70
61
- def get_object_confidences (predictions : List [Dict ], target_object : str ):
71
+ def get_object_confidences (predictions : List [Dict ], target_object : str ) -> List [ float ] :
62
72
"""
63
73
Return the list of confidences of instances of target label.
64
74
"""
65
- confidences = [pred ["confidence" ] for pred in predictions if pred ["label" ] == target_object ]
75
+ confidences = [
76
+ float (pred ["confidence" ])
77
+ for pred in predictions
78
+ if pred ["label" ] == target_object
79
+ ]
66
80
return confidences
67
81
68
82
@@ -71,56 +85,66 @@ def get_objects_summary(predictions: List[Dict]):
71
85
Get a summary of the objects detected.
72
86
"""
73
87
objects = get_objects (predictions )
74
- return {target_object : len (get_object_confidences (predictions , target_object )) for target_object in objects }
88
+ return {
89
+ target_object : len (get_object_confidences (predictions , target_object ))
90
+ for target_object in objects
91
+ }
75
92
76
93
77
- def post_image (url : str , image_bytes : bytes , api_key : str , timeout : int , data : dict = {}):
78
- """Post an image to Deepstack."""
94
+ def post_image (
95
+ url : str , image_bytes : bytes , api_key : str , timeout : int , data : dict = {}
96
+ ):
97
+ """Post an image to Deepstack. Only handles excpetions."""
79
98
try :
80
99
data ["api_key" ] = api_key # Insert the api_key
81
- response = requests .post (url , files = {"image" : image_bytes }, data = data , timeout = timeout )
82
- if response .status_code == HTTP_OK :
83
- return response
84
- elif response .status_code == BAD_URL :
85
- raise DeepstackException (f"Bad url supplied, url { url } raised error { BAD_URL } " )
86
- else :
87
- raise DeepstackException (f"Error from Deepstack request, status code: { response .status_code } " )
100
+ return requests .post (
101
+ url , files = {"image" : image_bytes }, data = data , timeout = timeout
102
+ )
88
103
except requests .exceptions .Timeout :
89
- raise DeepstackException (f"Timeout connecting to Deepstack, current timeout is { timeout } seconds" )
104
+ raise DeepstackException (
105
+ f"Timeout connecting to Deepstack, current timeout is { timeout } seconds"
106
+ )
90
107
except requests .exceptions .ConnectionError as exc :
91
108
raise DeepstackException (f"Connection error: { exc } " )
92
109
93
110
94
- class DeepstackException (Exception ):
95
- pass
111
+ def process_image (url : str , image_bytes : bytes , api_key : str , timeout : int ):
112
+ """Process image_bytes and detect. Handles common status codes"""
113
+ response = post_image (url , image_bytes , api_key , timeout )
114
+ if response .status_code == HTTP_OK :
115
+ return response .json ()
116
+ elif response .status_code == BAD_URL :
117
+ raise DeepstackException (f"Bad url supplied, url { url } raised error { BAD_URL } " )
118
+ else :
119
+ raise DeepstackException (
120
+ f"Error from Deepstack request, status code: { response .status_code } "
121
+ )
96
122
97
123
98
- class Deepstack ( object ) :
99
- """Base class for deepstack ."""
124
+ class DeepstackVision :
125
+ """Base class for Deepstack vision ."""
100
126
101
127
def __init__ (
102
128
self ,
103
- api_key : str = "" ,
129
+ ip : str = DEFAULT_IP ,
130
+ port : int = DEFAULT_PORT ,
131
+ api_key : str = DEFAULT_API_KEY ,
104
132
timeout : int = DEFAULT_TIMEOUT ,
105
- url_detect : str = None ,
106
- url_recognize : str = None ,
107
- url_register : str = None ,
133
+ url_detect : str = "" ,
134
+ url_recognize : str = "" ,
135
+ url_register : str = "" ,
108
136
):
109
137
110
- self ._url_detect = url_detect
111
- self ._url_recognize = url_recognize
112
- self ._url_register = url_register
138
+ self ._url_base = URL_BASE_VISION .format (ip = ip , port = port )
139
+ self ._url_detect = self ._url_base + url_detect
140
+ self ._url_recognize = self ._url_base + url_recognize
141
+ self ._url_register = self ._url_base + url_register
113
142
self ._api_key = api_key
114
143
self ._timeout = timeout
115
- self ._response = None
116
144
117
- def detect (self , image_bytes : bytes ):
145
+ def detect (self ):
118
146
"""Process image_bytes and detect."""
119
- self ._response = None
120
- self ._response = post_image (self ._url_detect , image_bytes , self ._api_key , self ._timeout ).json ()
121
- if not self ._response ["success" ]:
122
- error = self ._response ["error" ]
123
- raise DeepstackException (f"Error from Deepstack: { error } " )
147
+ raise NotImplementedError
124
148
125
149
def recognize (self ):
126
150
"""Process image_bytes and recognize."""
@@ -130,59 +154,68 @@ def register(self):
130
154
"""Perform a registration."""
131
155
raise NotImplementedError
132
156
133
- @property
134
- def predictions (self ):
135
- """Return the predictions."""
136
- raise NotImplementedError
137
157
138
-
139
- class DeepstackObject (Deepstack ):
158
+ class DeepstackObject (DeepstackVision ):
140
159
"""Work with objects"""
141
160
142
161
def __init__ (
143
162
self ,
144
- ip : str ,
145
- port : str ,
163
+ ip : str = DEFAULT_IP ,
164
+ port : int = DEFAULT_PORT ,
146
165
api_key : str = DEFAULT_API_KEY ,
147
166
timeout : int = DEFAULT_TIMEOUT ,
148
167
custom_model : str = None ,
149
168
):
150
169
if not custom_model :
151
170
super ().__init__ (
152
- api_key , timeout , url_detect = URL_OBJECT_DETECTION . format ( ip = ip , port = port ) ,
171
+ ip , port , api_key , timeout , url_detect = URL_OBJECT_DETECTION ,
153
172
)
154
173
else :
155
174
super ().__init__ (
156
- api_key , timeout , url_detect = URL_CUSTOM .format (ip = ip , port = port , custom_model = custom_model ),
175
+ ip ,
176
+ port ,
177
+ api_key ,
178
+ timeout ,
179
+ url_detect = URL_CUSTOM .format (custom_model = custom_model ),
157
180
)
158
181
159
- @property
160
- def predictions (self ):
161
- """Return the predictions."""
162
- return self ._response ["predictions" ]
182
+ def detect (self , image_bytes : bytes ):
183
+ """Process image_bytes and detect."""
184
+ response_json = process_image (
185
+ self ._url_detect , image_bytes , self ._api_key , self ._timeout
186
+ )
187
+ return response_json ["predictions" ]
163
188
164
189
165
- class DeepstackScene (Deepstack ):
190
+ class DeepstackScene (DeepstackVision ):
166
191
"""Work with scenes"""
167
192
168
193
def __init__ (
169
- self , ip : str , port : str , api_key : str = DEFAULT_API_KEY , timeout : int = DEFAULT_TIMEOUT ,
194
+ self ,
195
+ ip : str ,
196
+ port : str ,
197
+ api_key : str = DEFAULT_API_KEY ,
198
+ timeout : int = DEFAULT_TIMEOUT ,
170
199
):
171
200
super ().__init__ (
172
- api_key , timeout , url_detect = URL_SCENE_DETECTION . format ( ip = self . _ip , port = self . _port ) ,
201
+ api_key , timeout , url_detect = URL_SCENE_DETECTION ,
173
202
)
174
203
175
- @ property
176
- def predictions ( self ):
177
- """Return the predictions."""
178
- return self . _response
204
+ def detect ( self , image_bytes : bytes ):
205
+ """Process image_bytes and detect."""
206
+ response_json = process_image ( self , image_bytes , self . _api_key , self . _timeout )
207
+ return response_json
179
208
180
209
181
- class DeepstackFace (Deepstack ):
210
+ class DeepstackFace (DeepstackVision ):
182
211
"""Work with objects"""
183
212
184
213
def __init__ (
185
- self , ip : str , port : str , api_key : str = DEFAULT_API_KEY , timeout : int = DEFAULT_TIMEOUT ,
214
+ self ,
215
+ ip : str ,
216
+ port : str ,
217
+ api_key : str = DEFAULT_API_KEY ,
218
+ timeout : int = DEFAULT_TIMEOUT ,
186
219
):
187
220
super ().__init__ (
188
221
api_key ,
@@ -192,10 +225,10 @@ def __init__(
192
225
url_recognize = URL_FACE_RECOGNIZE .format (ip = self ._ip , port = self ._port ),
193
226
)
194
227
195
- @ property
196
- def predictions ( self ):
197
- """Return the classifier attributes."""
198
- return self . _response [ "predictions" ]
228
+ def detect ( self , image_bytes : bytes ):
229
+ """Process image_bytes and detect."""
230
+ response_json = process_image ( self , image_bytes , self . _api_key , self . _timeout )
231
+ return response_json
199
232
200
233
def register (self , name : str , image_bytes : bytes ):
201
234
"""
@@ -220,7 +253,9 @@ def register(self, name: str, image_bytes: bytes):
220
253
def recognize (self , image_bytes : bytes ):
221
254
"""Process image_bytes, performing recognition."""
222
255
223
- response = post_image (self ._url_recognize , image_bytes , self ._api_key , self ._timeout )
256
+ response = post_image (
257
+ self ._url_recognize , image_bytes , self ._api_key , self ._timeout
258
+ )
224
259
225
260
self ._response = response .json ()
226
261
if not self ._response ["success" ]:
0 commit comments