Update main.py
Browse files
main.py
CHANGED
|
@@ -201,7 +201,7 @@ def extract_fields_with_sarvam(raw_text: str, doc_type: str) -> dict:
|
|
| 201 |
}
|
| 202 |
|
| 203 |
if not SARVAM_API_KEY:
|
| 204 |
-
return {**empty_fields, "ocr_error": "SARVAM_API_KEY not configured"}
|
| 205 |
|
| 206 |
system_prompt = (
|
| 207 |
"You are a document field extractor for Indian identity documents. "
|
|
@@ -210,9 +210,9 @@ def extract_fields_with_sarvam(raw_text: str, doc_type: str) -> dict:
|
|
| 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\n"
|
| 214 |
" - gender: Male / Female / Transgender\n"
|
| 215 |
-
" - id_number: Aadhaar=12-digit, PAN=10-char alphanumeric, Voter ID=alphanumeric\n"
|
| 216 |
" - mobile_number: 10-digit mobile number if present\n\n"
|
| 217 |
"Use null for any field not found. Return a flat JSON object only."
|
| 218 |
)
|
|
@@ -242,38 +242,21 @@ def extract_fields_with_sarvam(raw_text: str, doc_type: str) -> dict:
|
|
| 242 |
timeout=30
|
| 243 |
)
|
| 244 |
|
| 245 |
-
# Log the raw response for debugging
|
| 246 |
-
raw_body = response.text[:500] # truncate for safety
|
| 247 |
-
|
| 248 |
if response.status_code != 200:
|
| 249 |
return {
|
| 250 |
**empty_fields,
|
| 251 |
-
"sarvam_error": f"API returned {response.status_code}: {
|
| 252 |
-
}
|
| 253 |
-
|
| 254 |
-
resp_json = response.json()
|
| 255 |
-
|
| 256 |
-
# Defensive: check schema before indexing
|
| 257 |
-
choices = resp_json.get("choices")
|
| 258 |
-
if not choices or not isinstance(choices, list) or len(choices) == 0:
|
| 259 |
-
return {
|
| 260 |
-
**empty_fields,
|
| 261 |
-
"sarvam_error": f"Unexpected response schema: {raw_body}"
|
| 262 |
}
|
| 263 |
|
| 264 |
-
|
| 265 |
-
content = message.get("content", "").strip()
|
| 266 |
|
| 267 |
-
|
| 268 |
-
return {
|
| 269 |
-
**empty_fields,
|
| 270 |
-
"sarvam_error": f"Empty content in response. Full body: {raw_body}"
|
| 271 |
-
}
|
| 272 |
-
|
| 273 |
-
# Strip markdown code fences if model wraps output
|
| 274 |
content = re.sub(r"^```(?:json)?\s*", "", content)
|
| 275 |
content = re.sub(r"\s*```$", "", content).strip()
|
| 276 |
|
|
|
|
|
|
|
|
|
|
| 277 |
extracted = json.loads(content)
|
| 278 |
|
| 279 |
fields = ["name", "address", "date_of_birth", "gender", "id_number", "mobile_number"]
|
|
@@ -285,11 +268,11 @@ def extract_fields_with_sarvam(raw_text: str, doc_type: str) -> dict:
|
|
| 285 |
return normalized
|
| 286 |
|
| 287 |
except json.JSONDecodeError as e:
|
| 288 |
-
return {**empty_fields, "sarvam_parse_error": f"JSON parse failed: {str(e)}
|
| 289 |
except requests.exceptions.Timeout:
|
| 290 |
return {**empty_fields, "sarvam_error": "Sarvam API request timed out"}
|
| 291 |
except Exception as e:
|
| 292 |
-
return {**empty_fields, "sarvam_error":
|
| 293 |
|
| 294 |
# -----------------------------
|
| 295 |
# FastAPI App
|
|
|
|
| 201 |
}
|
| 202 |
|
| 203 |
if not SARVAM_API_KEY:
|
| 204 |
+
return {**empty_fields, "ocr_error": "SARVAM_API_KEY not configured in Space secrets"}
|
| 205 |
|
| 206 |
system_prompt = (
|
| 207 |
"You are a document field extractor for Indian identity documents. "
|
|
|
|
| 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; use year_of_birth key if only year is present\n"
|
| 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. Return a flat JSON object only."
|
| 218 |
)
|
|
|
|
| 242 |
timeout=30
|
| 243 |
)
|
| 244 |
|
|
|
|
|
|
|
|
|
|
| 245 |
if response.status_code != 200:
|
| 246 |
return {
|
| 247 |
**empty_fields,
|
| 248 |
+
"sarvam_error": f"API returned {response.status_code}: {response.text[:300]}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
}
|
| 250 |
|
| 251 |
+
content = response.json()["choices"][0]["message"]["content"].strip()
|
|
|
|
| 252 |
|
| 253 |
+
# Strip markdown code fences
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
content = re.sub(r"^```(?:json)?\s*", "", content)
|
| 255 |
content = re.sub(r"\s*```$", "", content).strip()
|
| 256 |
|
| 257 |
+
# Strip <think>...</think> reasoning block (sarvam-m is a reasoning model)
|
| 258 |
+
content = re.sub(r"<think>.*?</think>\s*", "", content, flags=re.DOTALL).strip()
|
| 259 |
+
|
| 260 |
extracted = json.loads(content)
|
| 261 |
|
| 262 |
fields = ["name", "address", "date_of_birth", "gender", "id_number", "mobile_number"]
|
|
|
|
| 268 |
return normalized
|
| 269 |
|
| 270 |
except json.JSONDecodeError as e:
|
| 271 |
+
return {**empty_fields, "sarvam_parse_error": f"JSON parse failed: {str(e)}"}
|
| 272 |
except requests.exceptions.Timeout:
|
| 273 |
return {**empty_fields, "sarvam_error": "Sarvam API request timed out"}
|
| 274 |
except Exception as e:
|
| 275 |
+
return {**empty_fields, "sarvam_error": str(e)}
|
| 276 |
|
| 277 |
# -----------------------------
|
| 278 |
# FastAPI App
|