tommulder's picture
Deploy gesture detection & validation API
95db528
"""
Pydantic models for validation requests and responses.
This module defines the data structures used for identity validation,
including request models for input validation and response models
for structured output.
"""
from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field, field_serializer
from enum import Enum
import numpy as np
class ValidationStatus(str, Enum):
"""Enumeration of possible validation statuses."""
SUCCESS = "success"
FAILED = "failed"
PARTIAL = "partial"
class ValidationResult(BaseModel):
"""
Detailed result for a specific validation type.
Provides comprehensive information about validation outcomes,
including success status, confidence scores, and detailed metrics.
"""
status: ValidationStatus = Field(description="Overall validation status")
success: bool = Field(description="Boolean success indicator")
confidence: float = Field(description="Confidence score (0.0-1.0)", ge=0.0, le=1.0)
details: Optional[Dict[str, Any]] = Field(default=None, description="Additional validation details")
error_message: Optional[str] = Field(default=None, description="Error message if validation failed")
class ValidationResponse(BaseModel):
"""
Response model for identity validation requests.
Contains results for both facial and gesture validation,
along with overall validation status and optional detailed results.
"""
face: bool = Field(description="Facial recognition result")
gestures: bool = Field(description="Gesture validation result")
overall: bool = Field(description="Overall validation success")
status: ValidationStatus = Field(description="Overall validation status")
face_result: Optional[ValidationResult] = Field(default=None, description="Detailed facial validation result")
gesture_result: Optional[ValidationResult] = Field(default=None, description="Detailed gesture validation result")
processing_time_ms: Optional[int] = Field(default=None, description="Processing time in milliseconds")
timestamp: Optional[str] = Field(default=None, description="ISO timestamp of validation")
@field_serializer('face_result', 'gesture_result')
def serialize_validation_results(self, value: Optional[ValidationResult]) -> Optional[Dict[str, Any]]:
"""Serialize ValidationResult objects, converting numpy types."""
if value is None:
return None
# Convert to dict and handle numpy types
data = value.model_dump()
return self._convert_numpy_types(data)
@field_serializer('status')
def serialize_status(self, value: ValidationStatus) -> str:
"""Serialize ValidationStatus enum."""
return value.value
def _convert_numpy_types(self, obj):
"""Recursively convert numpy types to Python types."""
if isinstance(obj, np.integer):
return int(obj)
elif isinstance(obj, np.floating):
return float(obj)
elif isinstance(obj, np.bool_):
return bool(obj)
elif isinstance(obj, np.ndarray):
return obj.tolist()
elif isinstance(obj, dict):
return {k: self._convert_numpy_types(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [self._convert_numpy_types(item) for item in obj]
return obj
class GestureRequirement(BaseModel):
"""
Individual gesture requirement specification.
Defines a specific gesture that must be performed with optional
parameters like minimum duration or confidence threshold.
"""
gesture: str = Field(description="Name of the required gesture")
min_duration: Optional[int] = Field(default=None, description="Minimum duration in frames")
min_confidence: Optional[float] = Field(default=None, description="Minimum confidence threshold", ge=0.0, le=1.0)
required_count: Optional[int] = Field(default=1, description="Number of times gesture must be performed", ge=1)
class ValidationRequest(BaseModel):
"""
Request model for identity validation.
Specifies the required gestures and optional validation parameters for both
facial recognition and gesture validation. Used to configure the validation
process before processing.
"""
asked_gestures: List[str] = Field(description="List of required gesture names")
# Gesture validation parameters
error_margin: Optional[float] = Field(default=0.33, description="Error margin for gesture validation (0.0-1.0). If None, uses environment default", ge=0.0, le=1.0)
min_gesture_duration: Optional[int] = Field(default=5, description="Minimum duration for gesture detection in frames. If None, uses environment default")
require_all_gestures: Optional[bool] = Field(default=True, description="Whether all gestures must be present. If None, uses environment default")
confidence_threshold: Optional[float] = Field(default=0.7, description="Minimum confidence threshold for gesture detection (0.0-1.0). If None, uses environment default", ge=0.0, le=1.0)
# Facial recognition parameters
similarity_threshold: Optional[float] = Field(default=0.7, description="Minimum similarity threshold for facial matching (0.0-1.0). If None, uses environment default", ge=0.0, le=1.0)
frame_sample_rate: Optional[int] = Field(default=10, description="Rate at which to sample video frames for face detection. If None, uses environment default")
# Response parameters
include_details: Optional[bool] = Field(default=False, description="Include detailed validation results in response")
def to_gesture_requirements(self) -> List[GestureRequirement]:
"""
Convert asked_gestures list to detailed GestureRequirement objects.
Returns
-------
List[GestureRequirement]
List of gesture requirements with default parameters
"""
return [
GestureRequirement(
gesture=gesture,
min_duration=self.min_gesture_duration
)
for gesture in self.asked_gestures
]