Skip to content

Commit

Permalink
Merge pull request #270 from uploadcare/feature/260-aws_rekognition_m…
Browse files Browse the repository at this point in the history
…oderation

 AWS Rekognition Moderation and bugfixes for addons, closes #260
  • Loading branch information
evgkirov authored Nov 10, 2023
2 parents b6c127e + d54bff0 commit 4cad73a
Show file tree
Hide file tree
Showing 15 changed files with 556 additions and 20 deletions.
13 changes: 13 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ The format is based on [Keep a
Changelog](https://keepachangelog.com/en/1.0.0/), and this project
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [4.2.0](https://github.com/uploadcare/pyuploadcare/compare/v4.1.3...v4.2.0) - unreleased

### Added

- For `AddonsAPI` / `AddonLabels`:
- Added support for [Unsafe content detection](https://uploadcare.com/docs/unsafe-content/) addon (`AddonLabels.AWS_MODERATION_LABELS`).

### Fixed

- For `AddonsAPI` / `AddonExecutionParams`:
- Fixed the issue where calling `execute` and `status` with `AddonLabels`'s attributes (such as `AddonLabels.REMOVE_BG`) for `addon_name` would result in a _404 Not Found_ error.
- Fixed `ValidationError` when constructing `AddonClamAVExecutionParams` or `AddonRemoveBGExecutionParams` with omitted optional parameters.

## [4.1.3](https://github.com/uploadcare/pyuploadcare/compare/v4.1.2...v4.1.3) - 2023-10-05

### Added
Expand Down
11 changes: 8 additions & 3 deletions docs/core_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -216,18 +216,23 @@ To execute addon call an API `execute` method with the file and parameters::
target_file = uploadcare.file("59fccca5-3af7-462f-905b-ed7de83b9762")
# params - from previous step
remove_bg_result = uploadcare.addons_api.execute(
target_file,
target_file.uuid,
AddonLabels.REMOVE_BG,
remove_bg_params,
)

aws_recognition_result = uploadcare.addons_api.execute(
target_file,
target_file.uuid,
AddonLabels.AWS_LABEL_RECOGNITION,
)

aws_moderation_result = uploadcare.addons_api.execute(
target_file.uuid,
AddonLabels.AWS_MODERATION_LABELS,
)

clamav_result = uploadcare.addons_api.execute(
target_file,
target_file.uuid,
AddonLabels.CLAM_AV,
clamav_params,
)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pyuploadcare"
version = "4.1.3"
version = "4.2.0"
description = "Python library for Uploadcare.com"
authors = ["Uploadcare Inc <[email protected]>"]
readme = "README.md"
Expand Down
2 changes: 1 addition & 1 deletion pyuploadcare/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# isort: skip_file
__version__ = "4.1.2"
__version__ = "4.2.0"

from pyuploadcare.resources.file import File # noqa: F401
from pyuploadcare.resources.file_group import FileGroup # noqa: F401
Expand Down
24 changes: 13 additions & 11 deletions pyuploadcare/api/addon_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

class AddonLabels(str, Enum):
AWS_LABEL_RECOGNITION = "aws_rekognition_detect_labels"
AWS_MODERATION_LABELS = "aws_rekognition_detect_moderation_labels"
CLAM_AV = "uc_clamav_virus_scan"
REMOVE_BG = "remove_bg"

Expand Down Expand Up @@ -38,22 +39,22 @@ class AddonClamAVExecutionRequestData(AddonExecutionGeneralRequestData):


class AddonRemoveBGExecutionParams(AddonExecutionParams):
crop: bool = Field(
False, description="Whether to crop off all empty regions"
crop: Optional[bool] = Field(
None, description="Whether to crop off all empty regions"
)
crop_margin: str = Field(
"0",
crop_margin: Optional[str] = Field(
None,
description="Adds a margin around the cropped subject, e.g 30px or 30%",
)
scale: Optional[str] = Field(
None,
description="Scales the subject relative to the total image size, e.g 80%",
)
add_shadow: Optional[bool] = Field(
False, description="Whether to add an artificial shadow to the result"
None, description="Whether to add an artificial shadow to the result"
)
type_level: Optional[str] = Field(
"none",
None,
description="""Enum: "none" "1" "2" "latest"
"none" = No classification (foreground_type won't bet set in the application data)
"1" = Use coarse classification classes: [person, product, animal, car, other]
Expand All @@ -63,15 +64,16 @@ class AddonRemoveBGExecutionParams(AddonExecutionParams):
""",
)
type: Optional[str] = Field(
description="""Foreground type. Enum: "auto" "person" "product" "car"""
None,
description="""Foreground type. Enum: "auto" "person" "product" "car""",
)
semitransparency: Optional[bool] = Field(
True,
None,
description="Whether to have semi-transparent regions in the result",
)
channels: Optional[str] = Field("rgba", description="Enum: 'rgba' 'alpha'")
channels: Optional[str] = Field(None, description="Enum: 'rgba' 'alpha'")
roi: Optional[str] = Field(
...,
None,
description="""
Region of interest:
Only contents of this rectangular region can be detected as foreground.
Expand All @@ -83,7 +85,7 @@ class AddonRemoveBGExecutionParams(AddonExecutionParams):
""",
)
position: Optional[str] = Field(
...,
None,
description="""
Positions the subject within the image canvas.
Can be
Expand Down
13 changes: 10 additions & 3 deletions pyuploadcare/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,11 @@ def _get_request_data(
file_uuid: Union[UUID, str],
params: Optional[AddonExecutionParams] = None,
) -> dict:
cleaned_params = {}
if params:
cleaned_params = params.dict(exclude_unset=True, exclude_none=True)
execution_request_data = self.request_type.parse_obj(
dict(target=str(file_uuid), params=params)
dict(target=str(file_uuid), params=cleaned_params)
)
return execution_request_data.dict(
exclude_unset=True, exclude_none=True
Expand All @@ -520,9 +523,11 @@ def _get_request_data(
def execute(
self,
file_uuid: Union[UUID, str],
addon_name: AddonLabels,
addon_name: Union[AddonLabels, str],
params: Optional[AddonExecutionParams] = None,
) -> responses.AddonExecuteResponse:
if isinstance(addon_name, AddonLabels):
addon_name = addon_name.value
suffix = f"{addon_name}/execute"
url = self._build_url(suffix=suffix)
response_class = self._get_response_class("execute")
Expand All @@ -532,8 +537,10 @@ def execute(
return cast(responses.AddonExecuteResponse, response)

def status(
self, request_id: Union[UUID, str], addon_name: AddonLabels
self, request_id: Union[UUID, str], addon_name: Union[AddonLabels, str]
) -> responses.AddonResponse:
if isinstance(addon_name, AddonLabels):
addon_name = addon_name.value
suffix = f"{addon_name}/execute/status"
query = dict(request_id=str(request_id))
url = self._build_url(suffix=suffix, query_parameters=query)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
interactions:
- request:
body: '{"target": "485f5c0e-3567-46b1-a5c9-96a8ffc45713"}'
headers:
accept:
- '*/*'
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '50'
content-type:
- application/json
host:
- api.uploadcare.com
user-agent:
- PyUploadcare/4.1.2/5d5bb5639e3f2df33674 (CPython/3.11.5)
method: POST
uri: https://api.uploadcare.com/addons/aws_rekognition_detect_labels/execute/
response:
content: '{"request_id": "6e8424be-749a-4eee-bc1e-05393a7b6938"}'
headers:
Access-Control-Allow-Origin:
- https://uploadcare.com
Allow:
- OPTIONS, POST
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 09 Nov 2023 17:03:43 GMT
Server:
- nginx
Transfer-Encoding:
- chunked
Vary:
- Accept-Encoding
- Accept
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Robots-Tag:
- noindex, nofollow, nosnippet, noarchive
X-Uploadcare-Request-Id:
- 6e8424be-749a-4eee-bc1e-05393a7b6938
X-XSS-Protection:
- 1; mode=block
http_version: HTTP/1.1
status_code: 200
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
interactions:
- request:
body: ''
headers:
accept:
- '*/*'
accept-encoding:
- gzip, deflate
connection:
- keep-alive
host:
- api.uploadcare.com
user-agent:
- PyUploadcare/4.1.2/5d5bb5639e3f2df33674 (CPython/3.11.5)
method: GET
uri: https://api.uploadcare.com/addons/aws_rekognition_detect_labels/execute/status/?request_id=6e8424be-749a-4eee-bc1e-05393a7b6938
response:
content: '{"status": "done"}'
headers:
Access-Control-Allow-Origin:
- https://uploadcare.com
Allow:
- GET, HEAD, OPTIONS
Connection:
- keep-alive
Content-Length:
- '18'
Content-Type:
- application/json
Date:
- Thu, 09 Nov 2023 17:05:14 GMT
Server:
- nginx
Vary:
- Accept
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Robots-Tag:
- noindex, nofollow, nosnippet, noarchive
X-Uploadcare-Request-Id:
- 568d9e58-c2a6-4a87-a589-6e62c93fb3d8
X-XSS-Protection:
- 1; mode=block
http_version: HTTP/1.1
status_code: 200
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
interactions:
- request:
body: '{"target": "485f5c0e-3567-46b1-a5c9-96a8ffc45713"}'
headers:
accept:
- '*/*'
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '50'
content-type:
- application/json
host:
- api.uploadcare.com
user-agent:
- PyUploadcare/4.1.2/5d5bb5639e3f2df33674 (CPython/3.11.5)
method: POST
uri: https://api.uploadcare.com/addons/aws_rekognition_detect_moderation_labels/execute/
response:
content: '{"request_id": "6666a652-a79d-4991-9c4b-3f7705ed7c6c"}'
headers:
Access-Control-Allow-Origin:
- https://uploadcare.com
Allow:
- OPTIONS, POST
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 09 Nov 2023 16:40:41 GMT
Server:
- nginx
Transfer-Encoding:
- chunked
Vary:
- Accept-Encoding
- Accept
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Robots-Tag:
- noindex, nofollow, nosnippet, noarchive
X-Uploadcare-Request-Id:
- 6666a652-a79d-4991-9c4b-3f7705ed7c6c
X-XSS-Protection:
- 1; mode=block
http_version: HTTP/1.1
status_code: 200
version: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
interactions:
- request:
body: ''
headers:
accept:
- '*/*'
accept-encoding:
- gzip, deflate
connection:
- keep-alive
host:
- api.uploadcare.com
user-agent:
- PyUploadcare/4.1.2/5d5bb5639e3f2df33674 (CPython/3.11.5)
method: GET
uri: https://api.uploadcare.com/addons/aws_rekognition_detect_moderation_labels/execute/status/?request_id=6666a652-a79d-4991-9c4b-3f7705ed7c6c
response:
content: '{"status": "done"}'
headers:
Access-Control-Allow-Origin:
- https://uploadcare.com
Allow:
- GET, HEAD, OPTIONS
Connection:
- keep-alive
Content-Length:
- '18'
Content-Type:
- application/json
Date:
- Thu, 09 Nov 2023 16:58:59 GMT
Server:
- nginx
Vary:
- Accept
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Robots-Tag:
- noindex, nofollow, nosnippet, noarchive
X-Uploadcare-Request-Id:
- 83aee3a8-cdb3-4684-b364-6278fc8a10b8
X-XSS-Protection:
- 1; mode=block
http_version: HTTP/1.1
status_code: 200
version: 1
Loading

0 comments on commit 4cad73a

Please sign in to comment.