feat: add VIN decode endpoint to OCR Python service (refs #224)

Add POST /decode/vin endpoint using Gemini 2.5 Flash for VIN string
decoding. Returns structured vehicle data (year, make, model, trim,
body/drive/fuel type, engine, transmission) with confidence score.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Eric Gullickson
2026-02-18 21:40:10 -06:00
parent 00aa2a5411
commit a75f7b5583
7 changed files with 403 additions and 5 deletions

View File

@@ -14,6 +14,8 @@ from .schemas import (
ReceiptExtractedField,
ReceiptExtractionResponse,
VinAlternative,
VinDecodeRequest,
VinDecodeResponse,
VinExtractionResponse,
)
@@ -32,5 +34,7 @@ __all__ = [
"ReceiptExtractedField",
"ReceiptExtractionResponse",
"VinAlternative",
"VinDecodeRequest",
"VinDecodeResponse",
"VinExtractionResponse",
]

View File

@@ -169,3 +169,30 @@ class ManualJobResponse(BaseModel):
error: Optional[str] = None
model_config = {"populate_by_name": True}
class VinDecodeRequest(BaseModel):
"""Request body for VIN decode endpoint."""
vin: str
class VinDecodeResponse(BaseModel):
"""Response from VIN decode endpoint."""
success: bool
vin: str
year: Optional[int] = None
make: Optional[str] = None
model: Optional[str] = None
trim_level: Optional[str] = Field(default=None, alias="trimLevel")
body_type: Optional[str] = Field(default=None, alias="bodyType")
drive_type: Optional[str] = Field(default=None, alias="driveType")
fuel_type: Optional[str] = Field(default=None, alias="fuelType")
engine: Optional[str] = None
transmission: Optional[str] = None
confidence: float = Field(ge=0.0, le=1.0)
processing_time_ms: int = Field(alias="processingTimeMs")
error: Optional[str] = None
model_config = {"populate_by_name": True}