Skip to content

Commit 667c8be

Browse files
committed
Initial port to CodeProject.AI
1 parent 7ebadfb commit 667c8be

File tree

10 files changed

+849
-858
lines changed

10 files changed

+849
-858
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,5 @@ dmypy.json
117117
.DS_Store
118118

119119
venv
120-
.vscode
120+
.vscode
121+
.vs

README.md

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,21 @@
11
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
22
[![PyPI Version](https://img.shields.io/pypi/v/deepstack-python.svg)](https://pypi.org/project/deepstack-python/)
33

4-
# deepstack-python
5-
Unofficial python API for [DeepStack](https://docs.deepstack.cc). Provides classes for making requests to the object detection & face detection/recognition endpoints. Also includes some helper functions for processing the results. See the Jupyter notebooks for usage.
4+
# codeproject-ai-api
5+
A simple Python SDK for working with [CodeProject.AI Server](https://codeproject.com/ai). This SDK provides classes for making requests to the object detection & face detection/recognition endpoints, as well as helper functions for processing the results. See the Jupyter notebooks for usage.
66

7-
Run Deepstack with all three endpoints active (CPU mode):
8-
```
9-
docker run \
10-
-e VISION-SCENE=True \
11-
-e VISION-DETECTION=True \
12-
-e VISION-FACE=True \
13-
-v localstorage:/datastore \
14-
-p 80:5000 \
15-
-e API-KEY="" \
16-
--name deepstack deepquestai/deepstack
17-
```
18-
Check deepstack is running using curl (from root of this repo):
19-
```
20-
curl -X POST -F image=@tests/images/test-image3.jpg 'http://localhost:5000/v1/vision/detection'
21-
```
22-
If all goes well you should see the following returned:
7+
This work is a direct port of Robin Cole's original [deepstack-python](https://github.com/robmarkcole/deepstack-python) project.
8+
9+
Run CodeProject.AI Server (CPU mode):
2310
```
24-
{"success":true,"predictions":[{"confidence":0.9998661,"label":"person","y_min":0,"x_min":258,"y_max":676,"x_max":485},{"confidence":0.9996547,"label":"person","y_min":0,"x_min":405,"y_max":652,"x_max":639},{"confidence":0.99745613,"label":"dog","y_min":311,"x_min":624,"y_max":591,"x_max":825}]}
11+
docker run --name CodeProject.AI-Server -d -p 32168:32168 ^
12+
--mount type=bind,source=C:\ProgramData\CodeProject\AI\docker\data,target=/etc/codeproject/ai ^
13+
--mount type=bind,source=C:\ProgramData\CodeProject\AI\docker\modules,target=/app/modules ^
14+
codeproject/ai-server
2515
```
16+
and ensure you have an ObjectDetection module and a Face Processing module installed.
17+
18+
Check CodeProject.AI Server is running by opening the dashboard at http://localhost:32168
2619

2720
## Development
2821
* Create venv -> `python3.7 -m venv venv`

codeprojectai/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Init file for CodeProject.AI SDK."""
Lines changed: 84 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Deepstack core.
2+
CodeProject.AI SDK core.
33
"""
44
import requests
55
from PIL import Image
@@ -8,28 +8,27 @@
88
from requests.models import Response
99

1010
## Const
11-
DEFAULT_API_KEY = ""
12-
DEFAULT_TIMEOUT = 10 # seconds
13-
DEFAULT_IP = "localhost"
14-
DEFAULT_PORT = 80
11+
DEFAULT_TIMEOUT = 10 # seconds
12+
DEFAULT_IP = "localhost"
13+
DEFAULT_PORT = 32168
1514
DEFAULT_MIN_CONFIDENCE = 0.45
1615

1716
## HTTP codes
1817
HTTP_OK = 200
1918
BAD_URL = 404
2019

2120
## API urls
22-
URL_BASE_VISION = "http://{ip}:{port}/v1/vision"
23-
URL_CUSTOM = "/custom/{custom_model}"
21+
URL_BASE_VISION = "http://{ip}:{port}/v1/vision"
22+
URL_CUSTOM = "/custom/{custom_model}"
2423
URL_OBJECT_DETECTION = "/detection"
25-
URL_FACE_DETECTION = "/face"
26-
URL_FACE_REGISTER = "/face/register"
27-
URL_FACE_RECOGNIZE = "/face/recognize"
28-
URL_FACE_LIST = "/face/list"
29-
URL_SCENE_RECOGNIZE = "/scene"
24+
URL_FACE_DETECTION = "/face"
25+
URL_FACE_REGISTER = "/face/register"
26+
URL_FACE_RECOGNIZE = "/face/recognize"
27+
URL_FACE_LIST = "/face/list"
28+
# URL_SCENE_RECOGNIZE = "/scene"
3029

3130

32-
class DeepstackException(Exception):
31+
class CodeProjectAIException(Exception):
3332
pass
3433

3534

@@ -98,18 +97,18 @@ def get_objects_summary(predictions: List[Dict]):
9897
def post_image(
9998
url: str, image_bytes: bytes, timeout: int, data: dict
10099
) -> requests.models.Response:
101-
"""Post an image to Deepstack. Only handles exceptions."""
100+
"""Post an image to CodeProject.AI Server. Only handles exceptions."""
102101
try:
103102
return requests.post(
104103
url, files={"image": image_bytes}, data=data, timeout=timeout
105104
)
106105
except requests.exceptions.Timeout:
107-
raise DeepstackException(
108-
f"Timeout connecting to Deepstack, the current timeout is {timeout} seconds, try increasing this value"
106+
raise CodeProjectAIException(
107+
f"Timeout connecting to CodeProject.AI Server, the current timeout is {timeout} seconds, try increasing this value"
109108
)
110109
except requests.exceptions.ConnectionError or requests.exceptions.MissingSchema as exc:
111-
raise DeepstackException(
112-
f"Deepstack connection error, check your IP and port: {exc}"
110+
raise CodeProjectAIException(
111+
f"CodeProject.AI Server connection error, check your IP and port: {exc}"
113112
)
114113

115114

@@ -128,10 +127,10 @@ def process_image(
128127
if response.status_code == HTTP_OK:
129128
return response.json()
130129
elif response.status_code == BAD_URL:
131-
raise DeepstackException(f"Bad url supplied, url {url} raised error {BAD_URL}")
130+
raise CodeProjectAIException(f"Bad url supplied, url {url} raised error {BAD_URL}")
132131
else:
133-
raise DeepstackException(
134-
f"Error from Deepstack request, status code: {response.status_code}"
132+
raise CodeProjectAIException(
133+
f"Error from CodeProject.AI Server request, status code: {response.status_code}"
135134
)
136135

137136

@@ -140,39 +139,37 @@ def get_stored_faces(url, api_key, timeout) -> List:
140139
try:
141140
data = requests.post(url, timeout=timeout, data={"api_key": api_key})
142141
except requests.exceptions.Timeout:
143-
raise DeepstackException(
144-
f"Timeout connecting to Deepstack, the current timeout is {timeout} seconds, try increasing this value"
142+
raise CodeProjectAIException(
143+
f"Timeout connecting to CodeProject.AI Server, the current timeout is {timeout} seconds, try increasing this value"
145144
)
146145
except requests.exceptions.ConnectionError or requests.exceptions.MissingSchema as exc:
147-
raise DeepstackException(
148-
f"Deepstack connection error, check your IP and port: {exc}"
146+
raise CodeProjectAIException(
147+
f"CodeProject.AI Server connection error, check your IP and port: {exc}"
149148
)
150149
return data.json()
151150

152151

153-
class DeepstackVision:
154-
"""Base class for Deepstack vision."""
152+
class CodeProjectAIVision:
153+
"""Base class for CodeProject.AI vision."""
155154

156155
def __init__(
157156
self,
158-
ip: str = DEFAULT_IP,
159-
port: int = DEFAULT_PORT,
160-
api_key: str = DEFAULT_API_KEY,
161-
timeout: int = DEFAULT_TIMEOUT,
157+
ip: str = DEFAULT_IP,
158+
port: int = DEFAULT_PORT,
159+
timeout: int = DEFAULT_TIMEOUT,
162160
min_confidence: float = DEFAULT_MIN_CONFIDENCE,
163-
url_detect: str = "",
164-
url_recognize: str = "",
165-
url_register: str = "",
166-
url_face_list: str = "",
161+
url_detect: str = "",
162+
url_recognize: str = "",
163+
url_register: str = "",
164+
url_face_list: str = "",
167165
):
168-
self._api_key = api_key
169-
self._timeout = timeout
166+
self._timeout = timeout
170167
self._min_confidence = min_confidence
171-
self._url_base = URL_BASE_VISION.format(ip=ip, port=port)
172-
self._url_detect = self._url_base + url_detect
173-
self._url_recognize = self._url_base + url_recognize
174-
self._url_register = self._url_base + url_register
175-
self._url_face_list = self._url_base + url_face_list
168+
self._url_base = URL_BASE_VISION.format(ip=ip, port=port)
169+
self._url_detect = self._url_base + url_detect
170+
self._url_recognize = self._url_base + url_recognize
171+
self._url_register = self._url_base + url_register
172+
self._url_face_list = self._url_base + url_face_list
176173

177174
def detect(self):
178175
"""Process image_bytes and detect."""
@@ -187,17 +184,16 @@ def register(self):
187184
raise NotImplementedError
188185

189186

190-
class DeepstackObject(DeepstackVision):
187+
class CodeProjectAIObject(CodeProjectAIVision):
191188
"""Work with objects"""
192189

193190
def __init__(
194191
self,
195-
ip: str = DEFAULT_IP,
196-
port: int = DEFAULT_PORT,
197-
api_key: str = DEFAULT_API_KEY,
198-
timeout: int = DEFAULT_TIMEOUT,
192+
ip: str = DEFAULT_IP,
193+
port: int = DEFAULT_PORT,
194+
timeout: int = DEFAULT_TIMEOUT,
199195
min_confidence: float = DEFAULT_MIN_CONFIDENCE,
200-
custom_model: str = "",
196+
custom_model: str = "",
201197
):
202198
if custom_model:
203199
url_detect = URL_CUSTOM.format(custom_model=custom_model)
@@ -206,7 +202,6 @@ def __init__(
206202
super().__init__(
207203
ip=ip,
208204
port=port,
209-
api_key=api_key,
210205
timeout=timeout,
211206
min_confidence=min_confidence,
212207
url_detect=url_detect,
@@ -215,17 +210,17 @@ def __init__(
215210
def detect(self, image_bytes: bytes):
216211
"""Process image_bytes and detect."""
217212
response = process_image(
218-
url=self._url_detect,
219-
image_bytes=image_bytes,
220-
api_key=self._api_key,
221-
min_confidence=self._min_confidence,
222-
timeout=self._timeout,
213+
url = self._url_detect,
214+
image_bytes = image_bytes,
215+
api_key = self._api_key,
216+
min_confidence = self._min_confidence,
217+
timeout = self._timeout,
223218
)
224219
return response["predictions"]
225220

226-
227-
class DeepstackScene(DeepstackVision):
228-
"""Work with scenes"""
221+
"""
222+
class CodeProjectAIScene(CodeProjectAIVision):
223+
# Work with scenes
229224
230225
def __init__(
231226
self,
@@ -245,7 +240,7 @@ def __init__(
245240
)
246241
247242
def recognize(self, image_bytes: bytes):
248-
"""Process image_bytes and detect."""
243+
#Process image_bytes and detect.
249244
response = process_image(
250245
url=self._url_recognize,
251246
image_bytes=image_bytes,
@@ -255,39 +250,37 @@ def recognize(self, image_bytes: bytes):
255250
)
256251
del response["success"]
257252
return response
253+
"""
258254

259-
260-
class DeepstackFace(DeepstackVision):
255+
class CodeProjectAIFace(CodeProjectAIVision):
261256
"""Work with objects"""
262257

263258
def __init__(
264259
self,
265-
ip: str = DEFAULT_IP,
266-
port: int = DEFAULT_PORT,
267-
api_key: str = DEFAULT_API_KEY,
268-
timeout: int = DEFAULT_TIMEOUT,
260+
ip: str = DEFAULT_IP,
261+
port: int = DEFAULT_PORT,
262+
timeout: int = DEFAULT_TIMEOUT,
269263
min_confidence: float = DEFAULT_MIN_CONFIDENCE,
270264
):
271265
super().__init__(
272-
ip=ip,
273-
port=port,
274-
api_key=api_key,
275-
timeout=timeout,
276-
min_confidence=min_confidence,
277-
url_detect=URL_FACE_DETECTION,
278-
url_register=URL_FACE_REGISTER,
279-
url_recognize=URL_FACE_RECOGNIZE,
280-
url_face_list=URL_FACE_LIST,
266+
ip = ip,
267+
port = port,
268+
timeout = timeout,
269+
min_confidence = min_confidence,
270+
url_detect = URL_FACE_DETECTION,
271+
url_register = URL_FACE_REGISTER,
272+
url_recognize = URL_FACE_RECOGNIZE,
273+
url_face_list = URL_FACE_LIST,
281274
)
282275

283276
def detect(self, image_bytes: bytes):
284277
"""Process image_bytes and detect."""
285278
response = process_image(
286-
url=self._url_detect,
287-
image_bytes=image_bytes,
288-
api_key=self._api_key,
289-
min_confidence=self._min_confidence,
290-
timeout=self._timeout,
279+
url = self._url_detect,
280+
image_bytes = image_bytes,
281+
api_key = self._api_key,
282+
min_confidence = self._min_confidence,
283+
timeout = self._timeout,
291284
)
292285
return response["predictions"]
293286

@@ -296,31 +289,31 @@ def register(self, name: str, image_bytes: bytes):
296289
Register a face name to a file.
297290
"""
298291
response = process_image(
299-
url=self._url_register,
300-
image_bytes=image_bytes,
301-
api_key=self._api_key,
302-
min_confidence=self._min_confidence,
303-
timeout=self._timeout,
304-
data={"userid": name},
292+
url = self._url_register,
293+
image_bytes = image_bytes,
294+
api_key = self._api_key,
295+
min_confidence = self._min_confidence,
296+
timeout = self._timeout,
297+
data = { "userid": name },
305298
)
306299

307300
if response["success"] == True:
308301
return response["message"]
309302

310303
elif response["success"] == False:
311304
error = response["error"]
312-
raise DeepstackException(
313-
f"Deepstack raised an error registering a face: {error}"
305+
raise CodeProjectAIException(
306+
f"CodeProject.AI Server raised an error registering a face: {error}"
314307
)
315308

316309
def recognize(self, image_bytes: bytes):
317310
"""Process image_bytes, performing recognition."""
318311
response = process_image(
319-
url=self._url_recognize,
320-
image_bytes=image_bytes,
321-
api_key=self._api_key,
322-
min_confidence=self._min_confidence,
323-
timeout=self._timeout,
312+
url = self._url_recognize,
313+
image_bytes = image_bytes,
314+
api_key = self._api_key,
315+
min_confidence = self._min_confidence,
316+
timeout = self._timeout,
324317
)
325318

326319
return response["predictions"]

deepstack/__init__.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

setup.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
from setuptools import setup, find_packages
22

3-
VERSION = "0.9"
3+
VERSION = "0.1"
44

55
REQUIRES = ["requests"]
66

77
setup(
8-
name="deepstack-python",
9-
version=VERSION,
10-
url="https://github.com/robmarkcole/deepstack-python",
11-
author="Robin Cole",
12-
author_email="robmarkcole@gmail.com",
13-
description="Unofficial python API for DeepStack",
14-
install_requires=REQUIRES,
15-
packages=find_packages(),
16-
license="Apache License, Version 2.0",
17-
python_requires=">=3.7",
18-
classifiers=[
8+
name = "codeproject-ai-api",
9+
version = VERSION,
10+
url = "https://github.com/codeproject/codeproject-ai-api",
11+
author = "CodeProject",
12+
author_email = "info@codeproject.com",
13+
description = "Provides a simple SDK for the CodeProject.AI Server API",
14+
install_requires = REQUIRES,
15+
packages = find_packages(),
16+
license = "Apache License, Version 2.0",
17+
python_requires = ">=3.7",
18+
classifiers = [
1919
"Intended Audience :: Developers",
2020
"Natural Language :: English",
2121
"Programming Language :: Python",

0 commit comments

Comments
 (0)