Update main.py
Browse files
main.py
CHANGED
|
@@ -25,7 +25,6 @@ type_mapping = {
|
|
| 25 |
"voter_id": "Voter Id"
|
| 26 |
}
|
| 27 |
|
| 28 |
-
# Document types that support OCR extraction
|
| 29 |
EXTRACTABLE_TYPES = {"Aadhaar Card", "Pan Card", "Voter Id"}
|
| 30 |
|
| 31 |
# -----------------------------
|
|
@@ -163,7 +162,6 @@ def predict_file(path):
|
|
| 163 |
|
| 164 |
# -----------------------------
|
| 165 |
# OCR: Extract raw text from file
|
| 166 |
-
# Uses eng+hin Tesseract langs to handle both English and Hindi text
|
| 167 |
# -----------------------------
|
| 168 |
def extract_text_from_file(path: str) -> str:
|
| 169 |
ext = os.path.splitext(path)[1].lower()
|
|
@@ -176,7 +174,6 @@ def extract_text_from_file(path: str) -> str:
|
|
| 176 |
all_text.append(text)
|
| 177 |
|
| 178 |
elif ext == ".pdf":
|
| 179 |
-
# Use higher DPI for better OCR accuracy on PDFs
|
| 180 |
pages = convert_from_path(path, dpi=250)
|
| 181 |
for page in pages:
|
| 182 |
text = pytesseract.image_to_string(page, lang="eng+hin")
|
|
@@ -205,22 +202,31 @@ def extract_fields_with_sarvam(raw_text: str, doc_type: str) -> dict:
|
|
| 205 |
|
| 206 |
system_prompt = (
|
| 207 |
"You are a document field extractor for Indian identity documents. "
|
| 208 |
-
"Given raw OCR text, extract specific fields and return
|
| 209 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
"Fields to extract:\n"
|
| 211 |
" - name: Full name of the document holder\n"
|
| 212 |
" - address: Full address (combine multi-line if needed)\n"
|
| 213 |
-
" - date_of_birth: In DD/MM/YYYY or YYYY format
|
| 214 |
" - gender: Male / Female / Transgender\n"
|
| 215 |
" - id_number: Aadhaar=12-digit number, PAN=10-char alphanumeric, Voter ID=alphanumeric card number\n"
|
| 216 |
" - mobile_number: 10-digit mobile number if present\n\n"
|
| 217 |
-
"Use null for any field not found.
|
| 218 |
)
|
| 219 |
|
| 220 |
user_prompt = (
|
| 221 |
f"Document Type: {doc_type}\n\n"
|
| 222 |
f"Raw OCR Text:\n{raw_text}\n\n"
|
| 223 |
-
"Extract the fields and return
|
| 224 |
)
|
| 225 |
|
| 226 |
try:
|
|
@@ -250,18 +256,22 @@ def extract_fields_with_sarvam(raw_text: str, doc_type: str) -> dict:
|
|
| 250 |
|
| 251 |
content = response.json()["choices"][0]["message"]["content"].strip()
|
| 252 |
|
| 253 |
-
#
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
|
|
|
| 259 |
|
| 260 |
-
|
|
|
|
| 261 |
|
|
|
|
| 262 |
fields = ["name", "address", "date_of_birth", "gender", "id_number", "mobile_number"]
|
| 263 |
normalized = {f: extracted.get(f) for f in fields}
|
| 264 |
|
|
|
|
| 265 |
if normalized["date_of_birth"] is None and "year_of_birth" in extracted:
|
| 266 |
normalized["date_of_birth"] = str(extracted["year_of_birth"])
|
| 267 |
|
|
@@ -308,7 +318,7 @@ async def predict(
|
|
| 308 |
else:
|
| 309 |
result["Authentication"] = "Not valid"
|
| 310 |
|
| 311 |
-
# Step 3: OCR + Sarvam field extraction
|
| 312 |
doc_type = result.get("type")
|
| 313 |
if doc_type in EXTRACTABLE_TYPES:
|
| 314 |
raw_text = extract_text_from_file(temp_path)
|
|
|
|
| 25 |
"voter_id": "Voter Id"
|
| 26 |
}
|
| 27 |
|
|
|
|
| 28 |
EXTRACTABLE_TYPES = {"Aadhaar Card", "Pan Card", "Voter Id"}
|
| 29 |
|
| 30 |
# -----------------------------
|
|
|
|
| 162 |
|
| 163 |
# -----------------------------
|
| 164 |
# OCR: Extract raw text from file
|
|
|
|
| 165 |
# -----------------------------
|
| 166 |
def extract_text_from_file(path: str) -> str:
|
| 167 |
ext = os.path.splitext(path)[1].lower()
|
|
|
|
| 174 |
all_text.append(text)
|
| 175 |
|
| 176 |
elif ext == ".pdf":
|
|
|
|
| 177 |
pages = convert_from_path(path, dpi=250)
|
| 178 |
for page in pages:
|
| 179 |
text = pytesseract.image_to_string(page, lang="eng+hin")
|
|
|
|
| 202 |
|
| 203 |
system_prompt = (
|
| 204 |
"You are a document field extractor for Indian identity documents. "
|
| 205 |
+
"Given raw OCR text, extract specific fields and return the result wrapped in <output> tags like this:\n\n"
|
| 206 |
+
"<output>\n"
|
| 207 |
+
"{\n"
|
| 208 |
+
' "name": "...",\n'
|
| 209 |
+
' "address": "...",\n'
|
| 210 |
+
' "date_of_birth": "...",\n'
|
| 211 |
+
' "gender": "...",\n'
|
| 212 |
+
' "id_number": "...",\n'
|
| 213 |
+
' "mobile_number": "..."\n'
|
| 214 |
+
"}\n"
|
| 215 |
+
"</output>\n\n"
|
| 216 |
"Fields to extract:\n"
|
| 217 |
" - name: Full name of the document holder\n"
|
| 218 |
" - address: Full address (combine multi-line if needed)\n"
|
| 219 |
+
" - date_of_birth: In DD/MM/YYYY or YYYY format\n"
|
| 220 |
" - gender: Male / Female / Transgender\n"
|
| 221 |
" - id_number: Aadhaar=12-digit number, PAN=10-char alphanumeric, Voter ID=alphanumeric card number\n"
|
| 222 |
" - mobile_number: 10-digit mobile number if present\n\n"
|
| 223 |
+
"Use null for any field not found. Only output the <output> block, nothing else outside it."
|
| 224 |
)
|
| 225 |
|
| 226 |
user_prompt = (
|
| 227 |
f"Document Type: {doc_type}\n\n"
|
| 228 |
f"Raw OCR Text:\n{raw_text}\n\n"
|
| 229 |
+
"Extract the fields and return inside <output> tags."
|
| 230 |
)
|
| 231 |
|
| 232 |
try:
|
|
|
|
| 256 |
|
| 257 |
content = response.json()["choices"][0]["message"]["content"].strip()
|
| 258 |
|
| 259 |
+
# Extract JSON from <output>...</output> tag
|
| 260 |
+
output_match = re.search(r"<output>(.*?)</output>", content, flags=re.DOTALL)
|
| 261 |
+
if not output_match:
|
| 262 |
+
return {
|
| 263 |
+
**empty_fields,
|
| 264 |
+
"sarvam_error": f"No <output> tag found in response: {content[:300]}"
|
| 265 |
+
}
|
| 266 |
|
| 267 |
+
json_str = output_match.group(1).strip()
|
| 268 |
+
extracted = json.loads(json_str)
|
| 269 |
|
| 270 |
+
# Normalize keys
|
| 271 |
fields = ["name", "address", "date_of_birth", "gender", "id_number", "mobile_number"]
|
| 272 |
normalized = {f: extracted.get(f) for f in fields}
|
| 273 |
|
| 274 |
+
# Handle year_of_birth fallback
|
| 275 |
if normalized["date_of_birth"] is None and "year_of_birth" in extracted:
|
| 276 |
normalized["date_of_birth"] = str(extracted["year_of_birth"])
|
| 277 |
|
|
|
|
| 318 |
else:
|
| 319 |
result["Authentication"] = "Not valid"
|
| 320 |
|
| 321 |
+
# Step 3: OCR + Sarvam field extraction
|
| 322 |
doc_type = result.get("type")
|
| 323 |
if doc_type in EXTRACTABLE_TYPES:
|
| 324 |
raw_text = extract_text_from_file(temp_path)
|