synapsai-python 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- synapsai/__init__.py +16 -0
- synapsai/client.py +628 -0
- synapsai/exceptions.py +64 -0
- synapsai/logging.py +70 -0
- synapsai/processing.py +100 -0
- synapsai/resources/__init__.py +59 -0
- synapsai/resources/audio.py +495 -0
- synapsai/resources/chat.py +199 -0
- synapsai/resources/classifications.py +454 -0
- synapsai/resources/completions.py +162 -0
- synapsai/resources/embeddings.py +207 -0
- synapsai/resources/feature_extraction.py +80 -0
- synapsai/resources/fill_mask.py +88 -0
- synapsai/resources/images.py +560 -0
- synapsai/resources/models.py +80 -0
- synapsai/resources/question_answering.py +257 -0
- synapsai/resources/rerank.py +90 -0
- synapsai/resources/videos.py +303 -0
- synapsai/types/__init__.py +144 -0
- synapsai/types/audio.py +177 -0
- synapsai/types/classifications.py +228 -0
- synapsai/types/common.py +56 -0
- synapsai/types/completion.py +244 -0
- synapsai/types/embeddings.py +68 -0
- synapsai/types/feature_extraction.py +31 -0
- synapsai/types/fill_mask.py +38 -0
- synapsai/types/images.py +172 -0
- synapsai/types/models.py +28 -0
- synapsai/types/question_answering.py +127 -0
- synapsai/types/rerank.py +40 -0
- synapsai/types/videos.py +92 -0
- synapsai/utils.py +32 -0
- synapsai_python-0.1.0.dist-info/METADATA +312 -0
- synapsai_python-0.1.0.dist-info/RECORD +37 -0
- synapsai_python-0.1.0.dist-info/WHEEL +5 -0
- synapsai_python-0.1.0.dist-info/licenses/LICENSE +201 -0
- synapsai_python-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
# Copyright 2026 SynapsAI Technologies Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
Images resource handlers
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from typing import TYPE_CHECKING, Optional, Dict
|
|
20
|
+
|
|
21
|
+
from ..types.images import (
|
|
22
|
+
ImageGenerateRequest,
|
|
23
|
+
ImageGenerateResponse,
|
|
24
|
+
ImageEditRequest,
|
|
25
|
+
ImageEditResponse,
|
|
26
|
+
ImageAnalysisRequest,
|
|
27
|
+
ImageAnalysisResponse,
|
|
28
|
+
ImageSource,
|
|
29
|
+
DepthEstimationRequest,
|
|
30
|
+
DepthEstimationResponse,
|
|
31
|
+
ObjectDetectionRequest,
|
|
32
|
+
ObjectDetectionResponse,
|
|
33
|
+
ImageFeatureExtractionRequest,
|
|
34
|
+
ImageFeatureExtractionResponse,
|
|
35
|
+
MaskGenerationRequest,
|
|
36
|
+
MaskGenerationResponse,
|
|
37
|
+
)
|
|
38
|
+
from ..exceptions import APIError
|
|
39
|
+
from ..processing import process_image_input
|
|
40
|
+
|
|
41
|
+
if TYPE_CHECKING:
|
|
42
|
+
from ..client import SynapsAI, AsyncSynapsAI
|
|
43
|
+
|
|
44
|
+
class ImagesResource:
|
|
45
|
+
"""Images resource handler"""
|
|
46
|
+
|
|
47
|
+
def __init__(self, client: "SynapsAI"):
|
|
48
|
+
self._client = client
|
|
49
|
+
|
|
50
|
+
def generate(
|
|
51
|
+
self,
|
|
52
|
+
model: str,
|
|
53
|
+
prompt: str,
|
|
54
|
+
n: int = 1,
|
|
55
|
+
response_format: str = "url",
|
|
56
|
+
size: str = "1024x1024",
|
|
57
|
+
num_inference_steps: int = 25,
|
|
58
|
+
guidance_scale: float = 7.5,
|
|
59
|
+
**kwargs
|
|
60
|
+
) -> ImageGenerateResponse:
|
|
61
|
+
"""Generate images from text prompts"""
|
|
62
|
+
|
|
63
|
+
# Build request
|
|
64
|
+
request_data = self._client._build_request(
|
|
65
|
+
model=model,
|
|
66
|
+
prompt=prompt,
|
|
67
|
+
n=n,
|
|
68
|
+
response_format=response_format,
|
|
69
|
+
size=size,
|
|
70
|
+
num_inference_steps=num_inference_steps,
|
|
71
|
+
guidance_scale=guidance_scale,
|
|
72
|
+
**kwargs
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Make request
|
|
76
|
+
endpoint = "images/generations"
|
|
77
|
+
|
|
78
|
+
response = self._client._post(endpoint, json_data=request_data)
|
|
79
|
+
response_data = response.json()
|
|
80
|
+
return ImageGenerateResponse.model_validate(response_data)
|
|
81
|
+
|
|
82
|
+
def edit(
|
|
83
|
+
self,
|
|
84
|
+
image: ImageSource,
|
|
85
|
+
model: str,
|
|
86
|
+
prompt: str,
|
|
87
|
+
mask: Optional[ImageSource] = None,
|
|
88
|
+
n: int = 1,
|
|
89
|
+
size: str = "1024x1024",
|
|
90
|
+
response_format: str = "url",
|
|
91
|
+
num_inference_steps: int = 25,
|
|
92
|
+
guidance_scale: float = 7.5,
|
|
93
|
+
**kwargs
|
|
94
|
+
) -> ImageEditResponse:
|
|
95
|
+
"""Edit images with prompts"""
|
|
96
|
+
|
|
97
|
+
# Handle image input (file path, bytes, or base64)
|
|
98
|
+
image_data = process_image_input(image)
|
|
99
|
+
mask_data = process_image_input(mask) if mask else None
|
|
100
|
+
|
|
101
|
+
# Build request
|
|
102
|
+
request_data = self._client._build_request(
|
|
103
|
+
model=model,
|
|
104
|
+
image=image_data,
|
|
105
|
+
mask=mask_data,
|
|
106
|
+
prompt=prompt,
|
|
107
|
+
n=n,
|
|
108
|
+
size=size,
|
|
109
|
+
response_format=response_format,
|
|
110
|
+
num_inference_steps=num_inference_steps,
|
|
111
|
+
guidance_scale=guidance_scale,
|
|
112
|
+
**kwargs
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# Make request
|
|
116
|
+
endpoint = "images/edits"
|
|
117
|
+
|
|
118
|
+
response = self._client._post(endpoint, json_data=request_data)
|
|
119
|
+
response_data = response.json()
|
|
120
|
+
return ImageEditResponse.model_validate(response_data)
|
|
121
|
+
|
|
122
|
+
def to_text(
|
|
123
|
+
self,
|
|
124
|
+
model: str,
|
|
125
|
+
inputs: ImageSource,
|
|
126
|
+
prompt: Optional[str] = None,
|
|
127
|
+
max_new_tokens: int = 300,
|
|
128
|
+
generate_kwargs: Optional[Dict] = None,
|
|
129
|
+
**kwargs
|
|
130
|
+
) -> ImageAnalysisResponse:
|
|
131
|
+
"""Analyze images and extract information"""
|
|
132
|
+
|
|
133
|
+
# Handle image input
|
|
134
|
+
image_data = process_image_input(inputs)
|
|
135
|
+
|
|
136
|
+
# Build request
|
|
137
|
+
request_data = self._client._build_request(
|
|
138
|
+
model=model,
|
|
139
|
+
inputs=image_data,
|
|
140
|
+
prompt=prompt,
|
|
141
|
+
max_new_tokens=max_new_tokens,
|
|
142
|
+
generate_kwargs=generate_kwargs,
|
|
143
|
+
**kwargs
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Make request
|
|
147
|
+
endpoint = "images/to-text"
|
|
148
|
+
|
|
149
|
+
response = self._client._post(endpoint, json_data=request_data)
|
|
150
|
+
response_data = response.json()
|
|
151
|
+
return ImageAnalysisResponse.model_validate(response_data)
|
|
152
|
+
|
|
153
|
+
def feature_extraction(
|
|
154
|
+
self,
|
|
155
|
+
model: str,
|
|
156
|
+
inputs: ImageSource,
|
|
157
|
+
**kwargs
|
|
158
|
+
) -> ImageFeatureExtractionResponse:
|
|
159
|
+
"""Extract features from images"""
|
|
160
|
+
|
|
161
|
+
# Handle image input
|
|
162
|
+
image_data = process_image_input(inputs)
|
|
163
|
+
|
|
164
|
+
# Build request
|
|
165
|
+
request_data = self._client._build_request(
|
|
166
|
+
model=model,
|
|
167
|
+
inputs=image_data,
|
|
168
|
+
**kwargs
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
# Make request
|
|
172
|
+
endpoint = "images/feature-extraction"
|
|
173
|
+
|
|
174
|
+
response = self._client._post(endpoint, json_data=request_data)
|
|
175
|
+
response_data = response.json()
|
|
176
|
+
return ImageFeatureExtractionResponse.model_validate(response_data)
|
|
177
|
+
|
|
178
|
+
def segmentation(
|
|
179
|
+
self,
|
|
180
|
+
model: str,
|
|
181
|
+
inputs: ImageSource,
|
|
182
|
+
subtask: str = 'panoptic',
|
|
183
|
+
threshold: float = 0.9,
|
|
184
|
+
mask_threshold: float = 0.5,
|
|
185
|
+
overlap_mask_area_threshold: float = 0.5,
|
|
186
|
+
**kwargs
|
|
187
|
+
) -> ImageAnalysisResponse:
|
|
188
|
+
"""Analyze images and extract information."""
|
|
189
|
+
|
|
190
|
+
# Handle image input
|
|
191
|
+
image_data = process_image_input(inputs)
|
|
192
|
+
|
|
193
|
+
# Build request
|
|
194
|
+
request_data = self._client._build_request(
|
|
195
|
+
model=model,
|
|
196
|
+
inputs=image_data,
|
|
197
|
+
subtask=subtask,
|
|
198
|
+
threshold=threshold,
|
|
199
|
+
mask_threshold=mask_threshold,
|
|
200
|
+
overlap_mask_area_threshold=overlap_mask_area_threshold,
|
|
201
|
+
**kwargs
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# Make request
|
|
205
|
+
endpoint = "images/segmentation"
|
|
206
|
+
|
|
207
|
+
response = self._client._post(endpoint, json_data=request_data)
|
|
208
|
+
response_data = response.json()
|
|
209
|
+
return ImageAnalysisResponse.model_validate(response_data)
|
|
210
|
+
|
|
211
|
+
def depth_estimation(
|
|
212
|
+
self,
|
|
213
|
+
model: str,
|
|
214
|
+
inputs: ImageSource,
|
|
215
|
+
parameters: Optional[Dict] = None,
|
|
216
|
+
**kwargs
|
|
217
|
+
) -> DepthEstimationResponse:
|
|
218
|
+
"""Analyze images and extract information."""
|
|
219
|
+
|
|
220
|
+
# Handle image input
|
|
221
|
+
image_data = process_image_input(inputs)
|
|
222
|
+
|
|
223
|
+
# Build request
|
|
224
|
+
request_data = self._client._build_request(
|
|
225
|
+
model=model,
|
|
226
|
+
inputs=image_data,
|
|
227
|
+
parameters=parameters,
|
|
228
|
+
**kwargs
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# Make request
|
|
232
|
+
endpoint = "images/depth-estimation"
|
|
233
|
+
|
|
234
|
+
response = self._client._post(endpoint, json_data=request_data)
|
|
235
|
+
response_data = response.json()
|
|
236
|
+
return DepthEstimationResponse.model_validate(response_data)
|
|
237
|
+
|
|
238
|
+
def object_detection(
|
|
239
|
+
self,
|
|
240
|
+
model: str,
|
|
241
|
+
inputs: ImageSource,
|
|
242
|
+
threshold: float = 0.5,
|
|
243
|
+
**kwargs
|
|
244
|
+
) -> ObjectDetectionResponse:
|
|
245
|
+
"""Analyze images and extract information."""
|
|
246
|
+
|
|
247
|
+
# Handle image input
|
|
248
|
+
image_data = process_image_input(inputs)
|
|
249
|
+
|
|
250
|
+
# Build request
|
|
251
|
+
request_data = self._client._build_request(
|
|
252
|
+
model=model,
|
|
253
|
+
inputs=image_data,
|
|
254
|
+
threshold=threshold,
|
|
255
|
+
**kwargs
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
# Make request
|
|
259
|
+
endpoint = "images/object-detection"
|
|
260
|
+
|
|
261
|
+
response = self._client._post(endpoint, json_data=request_data)
|
|
262
|
+
response_data = response.json()
|
|
263
|
+
return ObjectDetectionResponse.model_validate(response_data)
|
|
264
|
+
|
|
265
|
+
def mask_generation(
|
|
266
|
+
self,
|
|
267
|
+
model: str,
|
|
268
|
+
image: ImageSource,
|
|
269
|
+
mask_threshold: float = 0.0,
|
|
270
|
+
pred_iou_thresh: float = 0.88,
|
|
271
|
+
stability_score_thresh: float = 0.95,
|
|
272
|
+
stability_score_offset: int = 1,
|
|
273
|
+
crops_nms_thresh: float = 0.7,
|
|
274
|
+
crops_n_layers: int = 0,
|
|
275
|
+
crop_overlap_ratio: float = 0.3413,
|
|
276
|
+
crop_n_points_downscale_factor: int = 1,
|
|
277
|
+
**kwargs
|
|
278
|
+
) -> MaskGenerationResponse:
|
|
279
|
+
"""Generate masks from images"""
|
|
280
|
+
|
|
281
|
+
image_data = process_image_input(image)
|
|
282
|
+
|
|
283
|
+
request_data = self._client._build_request(
|
|
284
|
+
model=model,
|
|
285
|
+
image=image_data,
|
|
286
|
+
mask_threshold=mask_threshold,
|
|
287
|
+
pred_iou_thresh=pred_iou_thresh,
|
|
288
|
+
stability_score_thresh=stability_score_thresh,
|
|
289
|
+
stability_score_offset=stability_score_offset,
|
|
290
|
+
crops_nms_thresh=crops_nms_thresh,
|
|
291
|
+
crops_n_layers=crops_n_layers,
|
|
292
|
+
crop_overlap_ratio=crop_overlap_ratio,
|
|
293
|
+
crop_n_points_downscale_factor=crop_n_points_downscale_factor,
|
|
294
|
+
**kwargs
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
endpoint = "images/mask-generation"
|
|
298
|
+
|
|
299
|
+
response = self._client._post(endpoint, json_data=request_data)
|
|
300
|
+
response_data = response.json()
|
|
301
|
+
return MaskGenerationResponse.model_validate(response_data)
|
|
302
|
+
|
|
303
|
+
class AsyncImagesResource:
|
|
304
|
+
"""Async images resource handler"""
|
|
305
|
+
|
|
306
|
+
def __init__(self, client: "AsyncSynapsAI"):
|
|
307
|
+
self._client = client
|
|
308
|
+
|
|
309
|
+
async def generate(
|
|
310
|
+
self,
|
|
311
|
+
model: str,
|
|
312
|
+
prompt: str,
|
|
313
|
+
n: int = 1,
|
|
314
|
+
response_format: str = "url",
|
|
315
|
+
size: str = "1024x1024",
|
|
316
|
+
num_inference_steps: int = 25,
|
|
317
|
+
guidance_scale: float = 7.5,
|
|
318
|
+
**kwargs
|
|
319
|
+
) -> ImageGenerateResponse:
|
|
320
|
+
"""Generate images from text prompts asynchronously"""
|
|
321
|
+
|
|
322
|
+
# Build request
|
|
323
|
+
request_data = self._client._build_request(
|
|
324
|
+
model=model,
|
|
325
|
+
prompt=prompt,
|
|
326
|
+
n=n,
|
|
327
|
+
response_format=response_format,
|
|
328
|
+
size=size,
|
|
329
|
+
num_inference_steps=num_inference_steps,
|
|
330
|
+
guidance_scale=guidance_scale,
|
|
331
|
+
**kwargs
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
# Make request
|
|
335
|
+
endpoint = "images/generations"
|
|
336
|
+
|
|
337
|
+
response = await self._client._post(endpoint, json_data=request_data)
|
|
338
|
+
response_data = response.json()
|
|
339
|
+
return ImageGenerateResponse.model_validate(response_data)
|
|
340
|
+
|
|
341
|
+
async def edit(
|
|
342
|
+
self,
|
|
343
|
+
image: ImageSource,
|
|
344
|
+
model: str,
|
|
345
|
+
prompt: str,
|
|
346
|
+
mask: Optional[ImageSource] = None,
|
|
347
|
+
n: int = 1,
|
|
348
|
+
size: str = "1024x1024",
|
|
349
|
+
response_format: str = "url",
|
|
350
|
+
num_inference_steps: int = 25,
|
|
351
|
+
guidance_scale: float = 7.5,
|
|
352
|
+
**kwargs
|
|
353
|
+
) -> ImageEditResponse:
|
|
354
|
+
"""Edit images with prompts asynchronously"""
|
|
355
|
+
|
|
356
|
+
# Handle image input
|
|
357
|
+
image_data = process_image_input(image)
|
|
358
|
+
mask_data = process_image_input(mask) if mask else None
|
|
359
|
+
|
|
360
|
+
# Build request
|
|
361
|
+
request_data = self._client._build_request(
|
|
362
|
+
model=model,
|
|
363
|
+
image=image_data,
|
|
364
|
+
mask=mask_data,
|
|
365
|
+
prompt=prompt,
|
|
366
|
+
n=n,
|
|
367
|
+
size=size,
|
|
368
|
+
response_format=response_format,
|
|
369
|
+
num_inference_steps=num_inference_steps,
|
|
370
|
+
guidance_scale=guidance_scale,
|
|
371
|
+
**kwargs
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
# Make request
|
|
375
|
+
endpoint = "images/edits"
|
|
376
|
+
|
|
377
|
+
response = await self._client._post(endpoint, json_data=request_data)
|
|
378
|
+
response_data = response.json()
|
|
379
|
+
return ImageEditResponse.model_validate(response_data)
|
|
380
|
+
|
|
381
|
+
async def to_text(
|
|
382
|
+
self,
|
|
383
|
+
inputs: ImageSource,
|
|
384
|
+
model: str,
|
|
385
|
+
prompt: Optional[str] = None,
|
|
386
|
+
max_new_tokens: int = 300,
|
|
387
|
+
generate_kwargs: Optional[Dict] = None,
|
|
388
|
+
**kwargs
|
|
389
|
+
) -> ImageAnalysisResponse:
|
|
390
|
+
"""Analyze images and extract information asynchronously (custom endpoint)"""
|
|
391
|
+
|
|
392
|
+
# Handle image input
|
|
393
|
+
inputs_data = process_image_input(inputs)
|
|
394
|
+
|
|
395
|
+
# Build request
|
|
396
|
+
request_data = self._client._build_request(
|
|
397
|
+
model=model,
|
|
398
|
+
inputs=inputs_data,
|
|
399
|
+
prompt=prompt,
|
|
400
|
+
max_new_tokens=max_new_tokens,
|
|
401
|
+
generate_kwargs=generate_kwargs,
|
|
402
|
+
**kwargs
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
# Make request
|
|
406
|
+
endpoint = "/images/to-text"
|
|
407
|
+
|
|
408
|
+
response = await self._client._post(endpoint, json_data=request_data)
|
|
409
|
+
response_data = response.json()
|
|
410
|
+
return ImageAnalysisResponse.model_validate(response_data)
|
|
411
|
+
|
|
412
|
+
async def feature_extraction(
|
|
413
|
+
self,
|
|
414
|
+
model: str,
|
|
415
|
+
inputs: ImageSource,
|
|
416
|
+
**kwargs
|
|
417
|
+
) -> ImageFeatureExtractionResponse:
|
|
418
|
+
"""Extract features from images"""
|
|
419
|
+
|
|
420
|
+
# Handle image input
|
|
421
|
+
image_data = process_image_input(inputs)
|
|
422
|
+
|
|
423
|
+
# Build request
|
|
424
|
+
request_data = self._client._build_request(
|
|
425
|
+
model=model,
|
|
426
|
+
inputs=image_data,
|
|
427
|
+
**kwargs
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
# Make request
|
|
431
|
+
endpoint = "images/feature-extraction"
|
|
432
|
+
|
|
433
|
+
response = await self._client._post(endpoint, json_data=request_data)
|
|
434
|
+
response_data = response.json()
|
|
435
|
+
return ImageFeatureExtractionResponse.model_validate(response_data)
|
|
436
|
+
|
|
437
|
+
async def segmentation(
|
|
438
|
+
self,
|
|
439
|
+
model: str,
|
|
440
|
+
inputs: ImageSource,
|
|
441
|
+
subtask: str = 'panoptic',
|
|
442
|
+
threshold: float = 0.9,
|
|
443
|
+
mask_threshold: float = 0.5,
|
|
444
|
+
overlap_mask_area_threshold: float = 0.5,
|
|
445
|
+
**kwargs
|
|
446
|
+
) -> ImageAnalysisResponse:
|
|
447
|
+
"""Analyze images and extract information."""
|
|
448
|
+
|
|
449
|
+
# Handle image input
|
|
450
|
+
image_data = process_image_input(inputs)
|
|
451
|
+
|
|
452
|
+
# Build request
|
|
453
|
+
request_data = self._client._build_request(
|
|
454
|
+
model=model,
|
|
455
|
+
inputs=image_data,
|
|
456
|
+
subtask=subtask,
|
|
457
|
+
threshold=threshold,
|
|
458
|
+
mask_threshold=mask_threshold,
|
|
459
|
+
overlap_mask_area_threshold=overlap_mask_area_threshold,
|
|
460
|
+
**kwargs
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
# Make request
|
|
464
|
+
endpoint = "images/segmentation"
|
|
465
|
+
|
|
466
|
+
response = await self._client._post(endpoint, json_data=request_data)
|
|
467
|
+
response_data = response.json()
|
|
468
|
+
return ImageAnalysisResponse.model_validate(response_data)
|
|
469
|
+
|
|
470
|
+
async def depth_estimation(
|
|
471
|
+
self,
|
|
472
|
+
model: str,
|
|
473
|
+
inputs: ImageSource,
|
|
474
|
+
parameters: Optional[Dict] = None,
|
|
475
|
+
**kwargs
|
|
476
|
+
) -> DepthEstimationResponse:
|
|
477
|
+
"""Analyze images and extract information."""
|
|
478
|
+
|
|
479
|
+
# Handle image input
|
|
480
|
+
image_data = process_image_input(inputs)
|
|
481
|
+
|
|
482
|
+
# Build request
|
|
483
|
+
request_data = self._client._build_request(
|
|
484
|
+
model=model,
|
|
485
|
+
inputs=image_data,
|
|
486
|
+
parameters=parameters,
|
|
487
|
+
**kwargs
|
|
488
|
+
)
|
|
489
|
+
|
|
490
|
+
# Make request
|
|
491
|
+
endpoint = "images/depth-estimation"
|
|
492
|
+
|
|
493
|
+
response = await self._client._post(endpoint, json_data=request_data)
|
|
494
|
+
response_data = response.json()
|
|
495
|
+
return DepthEstimationResponse.model_validate(response_data)
|
|
496
|
+
|
|
497
|
+
async def object_detection(
|
|
498
|
+
self,
|
|
499
|
+
model: str,
|
|
500
|
+
inputs: ImageSource,
|
|
501
|
+
threshold: float = 0.5,
|
|
502
|
+
**kwargs
|
|
503
|
+
) -> ObjectDetectionResponse:
|
|
504
|
+
"""Analyze images and extract information."""
|
|
505
|
+
|
|
506
|
+
# Handle image input
|
|
507
|
+
image_data = process_image_input(inputs)
|
|
508
|
+
|
|
509
|
+
# Build request
|
|
510
|
+
request_data = self._client._build_request(
|
|
511
|
+
model=model,
|
|
512
|
+
inputs=image_data,
|
|
513
|
+
threshold=threshold,
|
|
514
|
+
**kwargs
|
|
515
|
+
)
|
|
516
|
+
|
|
517
|
+
# Make request
|
|
518
|
+
endpoint = "images/object-detection"
|
|
519
|
+
|
|
520
|
+
response = await self._client._post(endpoint, json_data=request_data)
|
|
521
|
+
response_data = response.json()
|
|
522
|
+
return ObjectDetectionResponse.model_validate(response_data)
|
|
523
|
+
|
|
524
|
+
async def mask_generation(
|
|
525
|
+
self,
|
|
526
|
+
model: str,
|
|
527
|
+
image: ImageSource,
|
|
528
|
+
mask_threshold: float = 0.0,
|
|
529
|
+
pred_iou_thresh: float = 0.88,
|
|
530
|
+
stability_score_thresh: float = 0.95,
|
|
531
|
+
stability_score_offset: int = 1,
|
|
532
|
+
crops_nms_thresh: float = 0.7,
|
|
533
|
+
crops_n_layers: int = 0,
|
|
534
|
+
crop_overlap_ratio: float = 0.3413,
|
|
535
|
+
crop_n_points_downscale_factor: int = 1,
|
|
536
|
+
**kwargs
|
|
537
|
+
) -> MaskGenerationResponse:
|
|
538
|
+
"""Generate masks from images"""
|
|
539
|
+
|
|
540
|
+
image_data = process_image_input(image)
|
|
541
|
+
|
|
542
|
+
request_data = self._client._build_request(
|
|
543
|
+
model=model,
|
|
544
|
+
image=image_data,
|
|
545
|
+
mask_threshold=mask_threshold,
|
|
546
|
+
pred_iou_thresh=pred_iou_thresh,
|
|
547
|
+
stability_score_thresh=stability_score_thresh,
|
|
548
|
+
stability_score_offset=stability_score_offset,
|
|
549
|
+
crops_nms_thresh=crops_nms_thresh,
|
|
550
|
+
crops_n_layers=crops_n_layers,
|
|
551
|
+
crop_overlap_ratio=crop_overlap_ratio,
|
|
552
|
+
crop_n_points_downscale_factor=crop_n_points_downscale_factor,
|
|
553
|
+
**kwargs
|
|
554
|
+
)
|
|
555
|
+
|
|
556
|
+
endpoint = "images/mask-generation"
|
|
557
|
+
|
|
558
|
+
response = await self._client._post(endpoint, json_data=request_data)
|
|
559
|
+
response_data = response.json()
|
|
560
|
+
return MaskGenerationResponse.model_validate(response_data)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Copyright 2026 SynapsAI Technologies Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
Models resource handlers
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from typing import TYPE_CHECKING
|
|
20
|
+
|
|
21
|
+
from ..types.models import (
|
|
22
|
+
Model, Models
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from ..client import SynapsAI, AsyncSynapsAI
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ModelsResource:
|
|
30
|
+
"""Models resource handler"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, client: "SynapsAI"):
|
|
33
|
+
self._client = client
|
|
34
|
+
|
|
35
|
+
def list(self) -> Models:
|
|
36
|
+
"""Get available models."""
|
|
37
|
+
|
|
38
|
+
# Make request
|
|
39
|
+
endpoint = "models"
|
|
40
|
+
|
|
41
|
+
response = self._client._get(endpoint)
|
|
42
|
+
response_data = response.json()
|
|
43
|
+
return Models.model_validate(response_data)
|
|
44
|
+
|
|
45
|
+
def retrieve(self, model: str) -> Model:
|
|
46
|
+
"""Retrieve a model."""
|
|
47
|
+
|
|
48
|
+
# Make request
|
|
49
|
+
endpoint = f"models/{model}"
|
|
50
|
+
|
|
51
|
+
response = self._client._get(endpoint)
|
|
52
|
+
response_data = response.json()
|
|
53
|
+
return Model.model_validate(response_data)
|
|
54
|
+
|
|
55
|
+
class AsyncModelsResource:
|
|
56
|
+
"""Async images resource handler"""
|
|
57
|
+
|
|
58
|
+
def __init__(self, client: "AsyncSynapsAI"):
|
|
59
|
+
self._client = client
|
|
60
|
+
|
|
61
|
+
async def list(self) -> Models:
|
|
62
|
+
"""Get available models."""
|
|
63
|
+
|
|
64
|
+
# Make request
|
|
65
|
+
endpoint = "models"
|
|
66
|
+
|
|
67
|
+
response = await self._client._get(endpoint)
|
|
68
|
+
response_data = response.json()
|
|
69
|
+
return Models.model_validate(response_data)
|
|
70
|
+
|
|
71
|
+
async def retrieve(self, model: str) -> Model:
|
|
72
|
+
"""Retrieve a model."""
|
|
73
|
+
|
|
74
|
+
# Make request
|
|
75
|
+
endpoint = f"models/{model}"
|
|
76
|
+
|
|
77
|
+
response = await self._client._get(endpoint)
|
|
78
|
+
response_data = response.json()
|
|
79
|
+
return Model.model_validate(response_data)
|
|
80
|
+
|