useknockout 0.2.0__tar.gz → 0.4.0__tar.gz
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.
- {useknockout-0.2.0 → useknockout-0.4.0}/PKG-INFO +2 -1
- {useknockout-0.2.0 → useknockout-0.4.0}/README.md +1 -0
- {useknockout-0.2.0 → useknockout-0.4.0}/pyproject.toml +1 -1
- useknockout-0.4.0/src/useknockout/_version.py +1 -0
- {useknockout-0.2.0 → useknockout-0.4.0}/src/useknockout/async_client.py +22 -5
- {useknockout-0.2.0 → useknockout-0.4.0}/src/useknockout/client.py +30 -7
- useknockout-0.2.0/src/useknockout/_version.py +0 -1
- {useknockout-0.2.0 → useknockout-0.4.0}/.gitignore +0 -0
- {useknockout-0.2.0 → useknockout-0.4.0}/LICENSE +0 -0
- {useknockout-0.2.0 → useknockout-0.4.0}/src/useknockout/__init__.py +0 -0
- {useknockout-0.2.0 → useknockout-0.4.0}/src/useknockout/_helpers.py +0 -0
- {useknockout-0.2.0 → useknockout-0.4.0}/src/useknockout/errors.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: useknockout
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Python SDK for useknockout — state-of-the-art background removal API.
|
|
5
5
|
Project-URL: Homepage, https://useknockout.com
|
|
6
6
|
Project-URL: Documentation, https://github.com/useknockout/python
|
|
@@ -128,6 +128,7 @@ c.outline("photo.jpg", outline_color="#000000", outline_width=4)
|
|
|
128
128
|
|
|
129
129
|
# Presets
|
|
130
130
|
c.studio_shot("photo.jpg", aspect="1:1", shadow=True) # e-commerce
|
|
131
|
+
c.studio_shot("photo.jpg", transparent=True) # transparent bg (PNG)
|
|
131
132
|
c.headshot("photo.jpg", bg_color="#FFFFFF") # LinkedIn 4:5 portrait
|
|
132
133
|
c.headshot("photo.jpg", bg_blur=True, blur_radius=24) # blurred original bg
|
|
133
134
|
|
|
@@ -96,6 +96,7 @@ c.outline("photo.jpg", outline_color="#000000", outline_width=4)
|
|
|
96
96
|
|
|
97
97
|
# Presets
|
|
98
98
|
c.studio_shot("photo.jpg", aspect="1:1", shadow=True) # e-commerce
|
|
99
|
+
c.studio_shot("photo.jpg", transparent=True) # transparent bg (PNG)
|
|
99
100
|
c.headshot("photo.jpg", bg_color="#FFFFFF") # LinkedIn 4:5 portrait
|
|
100
101
|
c.headshot("photo.jpg", bg_blur=True, blur_radius=24) # blurred original bg
|
|
101
102
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.0"
|
|
@@ -65,9 +65,12 @@ class AsyncKnockout:
|
|
|
65
65
|
files=None,
|
|
66
66
|
data=None,
|
|
67
67
|
json=None,
|
|
68
|
+
params=None,
|
|
68
69
|
) -> bytes:
|
|
69
70
|
try:
|
|
70
|
-
r = await self._http.request(
|
|
71
|
+
r = await self._http.request(
|
|
72
|
+
method, path, files=files, data=data, json=json, params=params
|
|
73
|
+
)
|
|
71
74
|
except httpx.RequestError as e:
|
|
72
75
|
raise KnockoutError(f"network error: {e}", code="unknown") from e
|
|
73
76
|
if r.status_code >= 400:
|
|
@@ -82,9 +85,12 @@ class AsyncKnockout:
|
|
|
82
85
|
files=None,
|
|
83
86
|
data=None,
|
|
84
87
|
json=None,
|
|
88
|
+
params=None,
|
|
85
89
|
) -> Any:
|
|
86
90
|
try:
|
|
87
|
-
r = await self._http.request(
|
|
91
|
+
r = await self._http.request(
|
|
92
|
+
method, path, files=files, data=data, json=json, params=params
|
|
93
|
+
)
|
|
88
94
|
except httpx.RequestError as e:
|
|
89
95
|
raise KnockoutError(f"network error: {e}", code="unknown") from e
|
|
90
96
|
if r.status_code >= 400:
|
|
@@ -101,11 +107,12 @@ class AsyncKnockout:
|
|
|
101
107
|
return await self._request_json("GET", "/stats")
|
|
102
108
|
|
|
103
109
|
async def remove(self, file: FileInput, *, format: str = "png") -> bytes:
|
|
110
|
+
# /remove reads `format` as a QUERY param (bare default in the API).
|
|
104
111
|
return await self._request_bytes(
|
|
105
112
|
"POST",
|
|
106
113
|
"/remove",
|
|
107
114
|
files=_multipart_files(file),
|
|
108
|
-
|
|
115
|
+
params={"format": format},
|
|
109
116
|
)
|
|
110
117
|
|
|
111
118
|
async def remove_url(self, url: str, *, format: str = "png") -> bytes:
|
|
@@ -138,11 +145,12 @@ class AsyncKnockout:
|
|
|
138
145
|
) -> Dict[str, Any]:
|
|
139
146
|
if len(files) > 10:
|
|
140
147
|
raise ValueError("max 10 files per batch")
|
|
148
|
+
# /remove-batch reads `format` as a QUERY param (bare default in the API).
|
|
141
149
|
return await self._request_json(
|
|
142
150
|
"POST",
|
|
143
151
|
"/remove-batch",
|
|
144
152
|
files=_multipart_batch(files),
|
|
145
|
-
|
|
153
|
+
params={"format": format},
|
|
146
154
|
)
|
|
147
155
|
|
|
148
156
|
async def remove_batch_url(self, urls: List[str], *, format: str = "png") -> Dict[str, Any]:
|
|
@@ -250,6 +258,7 @@ class AsyncKnockout:
|
|
|
250
258
|
aspect: str = "1:1",
|
|
251
259
|
padding: int = 48,
|
|
252
260
|
shadow: bool = True,
|
|
261
|
+
transparent: bool = False,
|
|
253
262
|
format: str = "jpg",
|
|
254
263
|
) -> bytes:
|
|
255
264
|
return await self._request_bytes(
|
|
@@ -262,6 +271,7 @@ class AsyncKnockout:
|
|
|
262
271
|
"aspect": aspect,
|
|
263
272
|
"padding": padding,
|
|
264
273
|
"shadow": shadow,
|
|
274
|
+
"transparent": transparent,
|
|
265
275
|
"format": format,
|
|
266
276
|
}
|
|
267
277
|
),
|
|
@@ -355,13 +365,20 @@ class AsyncKnockout:
|
|
|
355
365
|
file: FileInput,
|
|
356
366
|
*,
|
|
357
367
|
only_center_face: bool = False,
|
|
368
|
+
bg_enhance: bool = False,
|
|
358
369
|
format: str = "png",
|
|
359
370
|
) -> bytes:
|
|
360
371
|
return await self._request_bytes(
|
|
361
372
|
"POST",
|
|
362
373
|
"/face-restore",
|
|
363
374
|
files=_multipart_files(file),
|
|
364
|
-
data=_form(
|
|
375
|
+
data=_form(
|
|
376
|
+
{
|
|
377
|
+
"only_center_face": only_center_face,
|
|
378
|
+
"bg_enhance": bg_enhance,
|
|
379
|
+
"format": format,
|
|
380
|
+
}
|
|
381
|
+
),
|
|
365
382
|
)
|
|
366
383
|
|
|
367
384
|
async def colorize(
|
|
@@ -75,9 +75,12 @@ class Knockout:
|
|
|
75
75
|
files=None,
|
|
76
76
|
data=None,
|
|
77
77
|
json=None,
|
|
78
|
+
params=None,
|
|
78
79
|
) -> bytes:
|
|
79
80
|
try:
|
|
80
|
-
r = self._http.request(
|
|
81
|
+
r = self._http.request(
|
|
82
|
+
method, path, files=files, data=data, json=json, params=params
|
|
83
|
+
)
|
|
81
84
|
except httpx.RequestError as e:
|
|
82
85
|
raise KnockoutError(f"network error: {e}", code="unknown") from e
|
|
83
86
|
if r.status_code >= 400:
|
|
@@ -92,9 +95,12 @@ class Knockout:
|
|
|
92
95
|
files=None,
|
|
93
96
|
data=None,
|
|
94
97
|
json=None,
|
|
98
|
+
params=None,
|
|
95
99
|
) -> Any:
|
|
96
100
|
try:
|
|
97
|
-
r = self._http.request(
|
|
101
|
+
r = self._http.request(
|
|
102
|
+
method, path, files=files, data=data, json=json, params=params
|
|
103
|
+
)
|
|
98
104
|
except httpx.RequestError as e:
|
|
99
105
|
raise KnockoutError(f"network error: {e}", code="unknown") from e
|
|
100
106
|
if r.status_code >= 400:
|
|
@@ -116,11 +122,13 @@ class Knockout:
|
|
|
116
122
|
|
|
117
123
|
def remove(self, file: FileInput, *, format: str = "png") -> bytes:
|
|
118
124
|
"""POST /remove — remove background, return transparent PNG/WebP bytes."""
|
|
125
|
+
# /remove reads `format` as a QUERY param (bare default in the API), unlike
|
|
126
|
+
# the Form()-based endpoints. Sending it in the body would be ignored.
|
|
119
127
|
return self._request_bytes(
|
|
120
128
|
"POST",
|
|
121
129
|
"/remove",
|
|
122
130
|
files=_multipart_files(file),
|
|
123
|
-
|
|
131
|
+
params={"format": format},
|
|
124
132
|
)
|
|
125
133
|
|
|
126
134
|
def remove_url(self, url: str, *, format: str = "png") -> bytes:
|
|
@@ -156,11 +164,12 @@ class Knockout:
|
|
|
156
164
|
"""POST /remove-batch — up to 10 multipart uploads in one call."""
|
|
157
165
|
if len(files) > 10:
|
|
158
166
|
raise ValueError("max 10 files per batch")
|
|
167
|
+
# /remove-batch reads `format` as a QUERY param (bare default in the API).
|
|
159
168
|
return self._request_json(
|
|
160
169
|
"POST",
|
|
161
170
|
"/remove-batch",
|
|
162
171
|
files=_multipart_batch(files),
|
|
163
|
-
|
|
172
|
+
params={"format": format},
|
|
164
173
|
)
|
|
165
174
|
|
|
166
175
|
def remove_batch_url(self, urls: List[str], *, format: str = "png") -> Dict[str, Any]:
|
|
@@ -274,9 +283,14 @@ class Knockout:
|
|
|
274
283
|
aspect: str = "1:1",
|
|
275
284
|
padding: int = 48,
|
|
276
285
|
shadow: bool = True,
|
|
286
|
+
transparent: bool = False,
|
|
277
287
|
format: str = "jpg",
|
|
278
288
|
) -> bytes:
|
|
279
|
-
"""POST /studio-shot — e-commerce preset (cutout + crop + center + shadow).
|
|
289
|
+
"""POST /studio-shot — e-commerce preset (cutout + crop + center + shadow).
|
|
290
|
+
|
|
291
|
+
Set ``transparent=True`` to keep a transparent background (bg_color and
|
|
292
|
+
shadow are ignored; output is PNG, jpg is coerced).
|
|
293
|
+
"""
|
|
280
294
|
return self._request_bytes(
|
|
281
295
|
"POST",
|
|
282
296
|
"/studio-shot",
|
|
@@ -287,6 +301,7 @@ class Knockout:
|
|
|
287
301
|
"aspect": aspect,
|
|
288
302
|
"padding": padding,
|
|
289
303
|
"shadow": shadow,
|
|
304
|
+
"transparent": transparent,
|
|
290
305
|
"format": format,
|
|
291
306
|
}
|
|
292
307
|
),
|
|
@@ -390,11 +405,13 @@ class Knockout:
|
|
|
390
405
|
file: FileInput,
|
|
391
406
|
*,
|
|
392
407
|
only_center_face: bool = False,
|
|
408
|
+
bg_enhance: bool = False,
|
|
393
409
|
format: str = "png",
|
|
394
410
|
) -> bytes:
|
|
395
411
|
"""POST /face-restore — GFPGAN v1.4 portrait restoration.
|
|
396
412
|
|
|
397
|
-
Fixes blurry / damaged / low-res faces
|
|
413
|
+
Fixes blurry / damaged / low-res faces. By default the background is
|
|
414
|
+
preserved as-is. ``bg_enhance=True`` also upscales the background 2x via
|
|
398
415
|
Real-ESRGAN. ``only_center_face=True`` restores just the most prominent
|
|
399
416
|
face (faster).
|
|
400
417
|
"""
|
|
@@ -402,7 +419,13 @@ class Knockout:
|
|
|
402
419
|
"POST",
|
|
403
420
|
"/face-restore",
|
|
404
421
|
files=_multipart_files(file),
|
|
405
|
-
data=_form(
|
|
422
|
+
data=_form(
|
|
423
|
+
{
|
|
424
|
+
"only_center_face": only_center_face,
|
|
425
|
+
"bg_enhance": bg_enhance,
|
|
426
|
+
"format": format,
|
|
427
|
+
}
|
|
428
|
+
),
|
|
406
429
|
)
|
|
407
430
|
|
|
408
431
|
def colorize(
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|