""" Handler for verify resource"""
from luna3.common.luna_response import LunaResponse
from luna3.python_matcher.match_objects import Candidates, FaceFilters, Reference
from sanic.response import HTTPResponse
from app.handlers.base_handler import APIProxyBaseHandler
from app.handlers.handlers_mixin import HandlersMixin
from app.handlers.matcher_basic_handler import MatcherBasicHandler
from app.handlers.schemas import PATCH_HANDLER_VERIFY_SCHEMA
from app.mixins import CachedHandlerMixin
from classes.enums import HandlerType
from classes.handler_defaults import VerifyHandlerPolicies
from crutches_on_wheels.errors.errors import ErrorInfo
from crutches_on_wheels.errors.exception import VLException
from crutches_on_wheels.web import query_getters as queryGetters
from crutches_on_wheels.web.base_proxy_handler_class import ProxyRequest
[docs]class HandlerVerify(CachedHandlerMixin, HandlersMixin, MatcherBasicHandler):
"""
Handler for verifying that photo contains given person
Resource: "/{api_version}/verify"
"""
[docs] async def post(self) -> HTTPResponse:
"""
Verify person on provided image, see `spec_handlers_verify`_.
.. _`spec_handlers_verify`:
_static/api.html#operation/verifyFace
"""
noCache = self.getQueryParam("no_cache", queryGetters.boolFrom01Getter, default=False)
personId = self.getQueryParam("person_id", queryGetters.uuidGetter, require=True)
warpedImage = self.getQueryParam("warped_image", queryGetters.int01Getter, default=0)
handler = await self.getHandler(HandlerType.verify, noCache)
handlerId, policiesDict = handler["handler_id"], handler["policies"]
handlerPolicies = VerifyHandlerPolicies(**policiesDict)
event = await self.emitHandlerEvent(
handlerType=HandlerType.verify,
handlerId=handlerId,
handlerPolicies=handlerPolicies,
warpedImage=warpedImage,
)
face = event.face
exif = event.exif
reference = Reference(referenceType="face", referenceId=face["id"])
verifyThreshold = policiesDict["verify_threshold"]
result = {"candidates": [], "face": face, "status": False}
if exif is not None:
result["exif"] = exif
personDescriptors = await self.getPersonDescriptors(personId=personId)
if not personDescriptors:
return self.success(statusCode=201, outputJson=result, extraHeaders=self.getExtraHeaders())
candidates = Candidates(filters=FaceFilters(faceIds=personDescriptors), targets=["face_id", "similarity"])
matchResult = (
await self.lunaApiClient.match(references=[reference], candidates=[candidates], raiseError=True)
).json
candidates = await self.generateVerifyMatchResult(matchResult, personId)
status = candidates and candidates[0]["similarity"] > verifyThreshold
result["candidates"] = candidates
result["status"] = status
return self.success(statusCode=201, outputJson=result, extraHeaders=self.getExtraHeaders())
[docs] async def get(self) -> HTTPResponse:
"""
Get handler info. See `spec_get_handler_verify`_.
.. _spec_get_handler_verify:
_static/api.html#operation/getHandlerVerify
"""
handler = await self.getHandler(handlerType=HandlerType.verify, noCache=True)
return self.success(200, outputJson=handler)
[docs] async def patch(self) -> HTTPResponse:
"""
Patch handler. See `spec_patch_handler_verify`_.
.. _spec_patch_handler_verify:
_static/api.html#operation/patchHandlerVerify
"""
reqJson = self.request.json
self.validateJson(reqJson, PATCH_HANDLER_VERIFY_SCHEMA, useJsonSchema=False)
actualHandlerVersion = await self.patchHandler(handlerType=HandlerType.verify, policies=reqJson)
return self.success(200, outputJson={"version": actualHandlerVersion})
[docs]class HandlerVerifyRaw(CachedHandlerMixin, HandlersMixin, APIProxyBaseHandler):
"""
Handler for raw verifying reference descriptors vs candidates descriptors
Resource: "/{api_version}/verify/raw"
"""
allowedMethods = ("POST",)
[docs] async def prepareRequestPost(self) -> ProxyRequest:
"""
Raw batch verification, see `spec raw verification`_.
.. _`spec raw verification`:
_static/api.html#tag/rawBatchVerification
Returns:
proxy request for matching
"""
headers = self.prepareHeaders()
headers.update({"Luna-Account-Id": self.accountId})
return ProxyRequest(self.request.body, headers, self.prepareQuery())
[docs] async def postProcessingPost(self, response: LunaResponse) -> HTTPResponse:
"""
Add a verification status to match results
Args:
response: response
Returns:
match response in api format
"""
responseJson = response.json
noCache = self.getQueryParam("no_cache", queryGetters.boolFrom01Getter, default=False)
handler = await self.getHandler(HandlerType.verify, noCache)
verifyThreshold = handler["policies"]["verify_threshold"]
for referenceMatches in responseJson["matches"]:
for match in referenceMatches["matches"]:
match["status"] = match["similarity"] > verifyThreshold
return self.success(200, outputJson=responseJson, extraHeaders=response.headers)
[docs] async def postProcessingFailedRequest(self, response: LunaResponse):
"""
Post processing failed response from the api
Args:
response: response
Raises:
VLException(ErrorInfo): re raise error
"""
raise VLException(ErrorInfo.fromDict(response.json), response.statusCode, False)
[docs] def prepareUrl(self) -> str:
"""
Prepare url for raw matching
Returns:
raw matching url
"""
return f"{self.lunaApiClient.baseUri}/matcher/raw"