Coverage for website/facedetection/api/facedetection/views.py: 13.04%

47 statements  

« prev     ^ index     » next       coverage.py v7.6.7, created at 2025-08-14 10:31 +0000

1import json 

2 

3from django.shortcuts import get_object_or_404 

4 

5from rest_framework import status 

6from rest_framework.exceptions import PermissionDenied, ValidationError 

7from rest_framework.response import Response 

8from rest_framework.views import APIView 

9 

10from ...models import ( 

11 BaseFaceEncodingSource, 

12 FaceDetectionPhoto, 

13 PhotoFaceEncoding, 

14 ReferenceFace, 

15 ReferenceFaceEncoding, 

16) 

17 

18 

19class FaceEncodingPostView(APIView): 

20 def post(self, request, **kwargs): 

21 """Submit encodings for a face encoding source. 

22 

23 Expects a json body as follows: 

24 

25 { 

26 "token": str, # The base64 token for authentication. 

27 "encodings": [ # A list of 0 or more encodings. 

28 [ <128 floats> ], 

29 ... 

30 ], 

31 } 

32 """ 

33 pk = kwargs["pk"] 

34 obj_type = kwargs["type"] 

35 

36 if obj_type == "reference": 

37 obj = get_object_or_404(ReferenceFace, pk=pk) 

38 elif obj_type == "photo": 

39 obj = get_object_or_404(FaceDetectionPhoto, pk=pk) 

40 else: 

41 return Response(status=status.HTTP_400_BAD_REQUEST) 

42 

43 try: 

44 encodings = request.data["encodings"] 

45 token = request.data["token"] 

46 except (json.JSONDecodeError, KeyError): 

47 return Response(status=status.HTTP_400_BAD_REQUEST) 

48 

49 if not isinstance(token, str) or not isinstance(encodings, list): 

50 return Response(status=status.HTTP_400_BAD_REQUEST) 

51 

52 for encoding in encodings: 

53 if ( 

54 not isinstance(encoding, list) 

55 or len(encoding) != 128 

56 or not all(isinstance(value, float) for value in encoding) 

57 ): 

58 return Response(status=status.HTTP_400_BAD_REQUEST) 

59 

60 if obj.token != token: 

61 raise PermissionDenied(detail="Invalid token.") 

62 if obj.status != BaseFaceEncodingSource.Status.PROCESSING: 

63 raise ValidationError(detail="This object is not processing.") 

64 

65 if isinstance(obj, ReferenceFace): 

66 if len(encodings) == 1: 

67 reference_encoding = ReferenceFaceEncoding(reference=obj) 

68 reference_encoding.encoding = encodings[0] 

69 reference_encoding.save() 

70 obj.status = BaseFaceEncodingSource.Status.DONE 

71 obj.save() 

72 else: # ReferenceFace needs exactly one encoding. 

73 obj.status = BaseFaceEncodingSource.Status.REJECTED 

74 obj.save() 

75 elif isinstance(obj, FaceDetectionPhoto): 

76 for encoding in encodings: 

77 photo_face_encoding = PhotoFaceEncoding(photo=obj) 

78 photo_face_encoding.encoding = encoding 

79 photo_face_encoding.save() 

80 obj.status = BaseFaceEncodingSource.Status.DONE 

81 obj.save() 

82 

83 return Response(status=status.HTTP_200_OK)