""" ISO estimator handler"""
from typing import List
import msgpack
from sanic.response import HTTPResponse
from app.api_sdk_adaptors.iso_adaptor import APISDKCheckISOAdaptor
from app.api_sdk_adaptors.orientation import handleImageOrientation
from app.handlers.base_handler import BaseHandlerWithMultipart
from app.handlers.custom_query_getters import multifacePolicyGetter
from classes.image_meta import InputImageData
from classes.multipart_processing import ISOMultipartProcessor
from classes.schemas.iso import ISOInputEstimationsModel
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.web.query_getters import boolFrom01Getter, int01Getter
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.task import TaskParams
# constant face estimation targets for ISO handler
ISO_FACE_ESTIMATION_TARGETS = {
LoopEstimations.faceLandmarks68,
LoopEstimations.faceWarpQuality,
LoopEstimations.mouthAttributes,
LoopEstimations.gaze,
LoopEstimations.eyes,
LoopEstimations.headPose,
LoopEstimations.glasses,
LoopEstimations.imageColorType,
LoopEstimations.headwear,
LoopEstimations.faceNaturalLight,
LoopEstimations.fisheye,
LoopEstimations.eyebrowExpression,
LoopEstimations.redEyes,
# faceDetectionBackground,
}
[docs]class ISOHandler(BaseHandlerWithMultipart):
"""
ISO estimator handler
Resource: "/{api_version}/iso"
"""
[docs] async def getDataFromMultipart(self, imageType: ImageType = ImageType.IMAGE) -> List[InputImageData]:
"""Description see :func:`~BaseHandlerWithMultipart.getDataFromMultipart`."""
dataFromRequest = await ISOMultipartProcessor().getData(self.request)
estimationDataFromMultiPart = self._getDataFromMultipart(dataFromRequest.images, imageType)
return estimationDataFromMultiPart
[docs] def checkIsoLicensing(self):
"""
Check that an ISO license is available.
Raises:
VLException(Error.LicenseProblem, 403): if some checks failed
"""
if not self.app.ctx.licenseChecker.checkExpirationTime():
raise VLException(Error.LicenseProblem.format("License expired"), 403, isCriticalError=False)
if (
not self.app.ctx.licenseChecker.licenseState.iso
or not self.app.ctx.licenseChecker.licenseState.iso.isAvailable
):
raise VLException(
Error.LicenseProblem.format("ISO license feature is disabled."),
statusCode=403,
isCriticalError=False,
)
[docs] async def post(self) -> HTTPResponse:
"""
ISO estimations handler. See spec `check iso`_.
.. _`check iso`:
_static/api.html#operation/checkISO
Returns:
Response with estimations
"""
self.checkIsoLicensing()
targets = ISO_FACE_ESTIMATION_TARGETS.copy()
if self.getQueryParam("extract_exif", boolFrom01Getter, default=False):
targets.add(LoopEstimations.exif)
multifacePolicy = self.getQueryParam(
"multiface_policy", multifacePolicyGetter, default=MultifacePolicy.notAllowed
)
params = TaskParams(
targets=targets,
multifacePolicy=multifacePolicy,
useExifInfo=False,
autoRotation=self.config.useAutoRotation,
)
imageType = self.getQueryParam("image_type", lambda x: ImageType(int01Getter(x)), default=ImageType.IMAGE)
with monitorTime(self.request.dataForMonitoring, "load_images_for_processing_time"):
inputData = await self.getInputEstimationData(
self.request, imageType=imageType, validationModel=ISOInputEstimationsModel
)
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)
isoAdaptor = APISDKCheckISOAdaptor(estimationTargets=targets)
result, monitoringData = await isoAdaptor.buildResult(
task.result, meta=[metaImage.meta for metaImage in inputData]
)
self.handleMonitoringData(monitoringData)
if self.getResponseContentType() == "application/msgpack":
body = msgpack.packb(result, use_bin_type=True)
return self.success(200, body=body, contentType="application/msgpack")
return self.success(200, outputJson=result)