""" Extractor handler """
from sanic.response import HTTPResponse
from app.api_sdk_adaptors.extractor import APISDKExtractorAdaptor
from app.api_sdk_adaptors.orientation import handleImageOrientation
from app.handlers.base_handler import BaseHandler
from classes.schemas.extractor import Extractor
from crutches_on_wheels.errors.errors import Error, ErrorInfo
from crutches_on_wheels.errors.exception import VLException
from crutches_on_wheels.monitoring.points import monitorTime
from crutches_on_wheels.utils.functions import currentDateTime
from crutches_on_wheels.web.query_getters import float01Getter, int01Getter, uuidGetter
from sdk.sdk_loop.enums import LoopEstimations, MultifacePolicy
from sdk.sdk_loop.models.image import ImageType
from sdk.sdk_loop.task import HandlersTask
from sdk.sdk_loop.tasks.filters import FaceDetectionFilters, Filters
from sdk.sdk_loop.tasks.task import TaskEstimationParams, TaskParams
[docs]class ExtractorHandler(BaseHandler):
"""
Extract attributes such as gender, age, ethnicity, descriptor from samples.
Resource: "/{api_version}/extractor"
"""
[docs] async def post(self) -> HTTPResponse:
"""
Extract attributes from samples. See `spec_extractor`_.
.. _spec_extractor:
_static/api.html#operation/extractAttributes
Returns:
response with list of extracted attributes
Raises:
VLException(Error.NotSelectedAttributesForExtract, 400, isCriticalError=True): if extract_descriptor=0 and
extract_basic_attributes=0
"""
self.accountId = self.getQueryParam("account_id", uuidGetter, require=True)
targets = set()
if self.getQueryParam("extract_descriptor", int01Getter, default=1):
targets.add(LoopEstimations.faceDescriptor)
if self.getQueryParam("extract_basic_attributes", int01Getter, default=0):
targets.add(LoopEstimations.basicAttributes)
if not targets:
raise VLException(Error.NotSelectedAttributesForExtract, 400, isCriticalError=False)
faceFilters = FaceDetectionFilters(
gcThreshold=self.getQueryParam("score_threshold", float01Getter)
if LoopEstimations.faceDescriptor in targets
else None,
)
params = TaskParams(
targets=targets,
filters=Filters(faceDetection=faceFilters),
estimatorsParams=TaskEstimationParams(
faceDescriptorVersion=self.config.defaultFaceDescriptorVersion,
),
autoRotation=self.config.useAutoRotation,
multifacePolicy=MultifacePolicy.notAllowed,
aggregate=self.getQueryParam("aggregate_attributes", int01Getter, default=0),
)
ttl = self.getQueryParam("ttl", lambda ttl: max(min(int(ttl), 86400), 1), default=300)
sampleIds = self.request.json
self.loadDataFromJson({"samples": sampleIds}, Extractor)
with monitorTime(self.request.dataForMonitoring, "load_face_samples_time"):
inputData = await self._getImagesFromSamples(
inputJson={"samples": sampleIds},
imageType=ImageType.FACE_WARP,
defaultDetectTime=currentDateTime(self.config.storageTime),
)
task = HandlersTask(data=[metaImage.image for metaImage in inputData], params=params)
await task.execute()
if task.result.error:
raise VLException(ErrorInfo.fromDict(task.result.error.asDict()), 400, isCriticalError=False)
if self.config.useAutoRotation:
handleImageOrientation(task.result.images)
extractorAdaptor = APISDKExtractorAdaptor(
estimationTargets=targets,
accountId=self.accountId,
facesClient=self.luna3Client.lunaFaces,
ttl=ttl,
)
result, monitoringData = await extractorAdaptor.buildResult(
task=task.result, meta=[metaImage.meta for metaImage in inputData]
)
self.handleMonitoringData(monitoringData)
return self.success(201, outputJson=result)