File size: 5,697 Bytes
211e423
 
 
 
 
 
 
 
 
 
 
 
5537ceb
211e423
 
 
 
 
 
 
 
5537ceb
211e423
 
 
 
 
 
 
 
5537ceb
 
 
 
 
 
 
 
 
 
 
 
 
211e423
 
 
 
 
 
 
 
 
 
 
 
5537ceb
 
 
211e423
 
5537ceb
 
 
 
 
 
211e423
 
 
 
5537ceb
211e423
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5537ceb
211e423
5537ceb
 
 
211e423
 
 
 
 
 
 
 
 
 
5537ceb
 
 
211e423
 
 
5537ceb
 
 
 
 
 
211e423
 
 
 
5537ceb
211e423
 
 
 
 
 
5537ceb
211e423
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""API models for Dots.OCR text extraction service.

This module defines the data structures used for API requests,
responses, and internal data processing.
"""

from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field


class BoundingBox(BaseModel):
    """Normalized bounding box coordinates."""

    x1: float = Field(..., ge=0.0, le=1.0, description="Top-left x coordinate")
    y1: float = Field(..., ge=0.0, le=1.0, description="Top-left y coordinate")
    x2: float = Field(..., ge=0.0, le=1.0, description="Bottom-right x coordinate")
    y2: float = Field(..., ge=0.0, le=1.0, description="Bottom-right y coordinate")


class ExtractedField(BaseModel):
    """Individual extracted field with confidence and source."""

    field_name: str = Field(..., description="Standardized field name")
    value: Optional[str] = Field(None, description="Extracted field value")
    confidence: float = Field(..., ge=0.0, le=1.0, description="Extraction confidence")
    source: str = Field(..., description="Extraction source (e.g., 'ocr')")


class IdCardFields(BaseModel):
    """Structured fields extracted from identity documents."""

    document_number: Optional[ExtractedField] = Field(
        None, description="Document number/ID"
    )
    document_type: Optional[ExtractedField] = Field(
        None, description="Type of document"
    )
    issuing_country: Optional[ExtractedField] = Field(
        None, description="Issuing country code"
    )
    issuing_authority: Optional[ExtractedField] = Field(
        None, description="Issuing authority"
    )

    # Personal Information
    surname: Optional[ExtractedField] = Field(None, description="Family name/surname")
    given_names: Optional[ExtractedField] = Field(None, description="Given names")
    nationality: Optional[ExtractedField] = Field(None, description="Nationality code")
    date_of_birth: Optional[ExtractedField] = Field(None, description="Date of birth")
    gender: Optional[ExtractedField] = Field(None, description="Gender")
    place_of_birth: Optional[ExtractedField] = Field(None, description="Place of birth")

    # Validity Information
    date_of_issue: Optional[ExtractedField] = Field(None, description="Date of issue")
    date_of_expiry: Optional[ExtractedField] = Field(None, description="Date of expiry")
    personal_number: Optional[ExtractedField] = Field(
        None, description="Personal number"
    )

    # Additional fields for specific document types
    optional_data_1: Optional[ExtractedField] = Field(
        None, description="Optional data field 1"
    )
    optional_data_2: Optional[ExtractedField] = Field(
        None, description="Optional data field 2"
    )


class ExtractedFields(BaseModel):
    """All extracted fields from identity document."""

    document_number: Optional[ExtractedField] = None
    document_type: Optional[ExtractedField] = None
    issuing_country: Optional[ExtractedField] = None
    issuing_authority: Optional[ExtractedField] = None
    surname: Optional[ExtractedField] = None
    given_names: Optional[ExtractedField] = None
    nationality: Optional[ExtractedField] = None
    date_of_birth: Optional[ExtractedField] = None
    gender: Optional[ExtractedField] = None
    place_of_birth: Optional[ExtractedField] = None
    date_of_issue: Optional[ExtractedField] = None
    date_of_expiry: Optional[ExtractedField] = None
    personal_number: Optional[ExtractedField] = None
    optional_data_1: Optional[ExtractedField] = None
    optional_data_2: Optional[ExtractedField] = None


class MRZData(BaseModel):
    """Machine Readable Zone data."""

    # Primary canonical fields
    document_type: Optional[str] = Field(
        None, description="MRZ document type (TD1|TD2|TD3)"
    )
    issuing_country: Optional[str] = Field(None, description="Issuing country code")
    surname: Optional[str] = Field(None, description="Surname from MRZ")
    given_names: Optional[str] = Field(None, description="Given names from MRZ")
    document_number: Optional[str] = Field(None, description="Document number from MRZ")
    nationality: Optional[str] = Field(None, description="Nationality code from MRZ")
    date_of_birth: Optional[str] = Field(None, description="Date of birth from MRZ")
    gender: Optional[str] = Field(None, description="Gender from MRZ")
    date_of_expiry: Optional[str] = Field(None, description="Date of expiry from MRZ")
    personal_number: Optional[str] = Field(None, description="Personal number from MRZ")
    raw_mrz: Optional[str] = Field(None, description="Raw MRZ text")
    confidence: float = Field(
        0.0, ge=0.0, le=1.0, description="MRZ extraction confidence"
    )

    # Backwards compatibility fields (some older code/tests expect these names)
    # These duplicate information from the canonical fields above.
    format_type: Optional[str] = Field(
        None, description="Alias of document_type for backward compatibility"
    )
    raw_text: Optional[str] = Field(
        None, description="Alias of raw_mrz for backward compatibility"
    )


class OCRDetection(BaseModel):
    """Single OCR detection result."""

    mrz_data: Optional[MRZData] = Field(None, description="MRZ data if detected")
    extracted_fields: ExtractedFields = Field(..., description="Extracted field data")


class OCRResponse(BaseModel):
    """OCR API response."""

    request_id: str = Field(..., description="Unique request identifier")
    media_type: str = Field(..., description="Media type processed")
    processing_time: float = Field(..., description="Processing time in seconds")
    detections: List[OCRDetection] = Field(..., description="List of OCR detections")