idvpackage 3.0.13__tar.gz → 3.0.14__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. {idvpackage-3.0.13/idvpackage.egg-info → idvpackage-3.0.14}/PKG-INFO +1 -1
  2. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/common.py +3 -2
  3. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/ocr.py +42 -39
  4. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/qatar_id_extraction.py +10 -10
  5. {idvpackage-3.0.13 → idvpackage-3.0.14/idvpackage.egg-info}/PKG-INFO +1 -1
  6. {idvpackage-3.0.13 → idvpackage-3.0.14}/setup.cfg +1 -1
  7. {idvpackage-3.0.13 → idvpackage-3.0.14}/setup.py +1 -1
  8. {idvpackage-3.0.13 → idvpackage-3.0.14}/LICENSE +0 -0
  9. {idvpackage-3.0.13 → idvpackage-3.0.14}/MANIFEST.in +0 -0
  10. {idvpackage-3.0.13 → idvpackage-3.0.14}/README.md +0 -0
  11. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/__init__.py +0 -0
  12. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/blur_detection.py +0 -0
  13. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/constants.py +0 -0
  14. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/icons/battery1.png +0 -0
  15. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/icons/battery3.png +0 -0
  16. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/icons/network1.png +0 -0
  17. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/icons/network2.png +0 -0
  18. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/icons/wifi1.png +0 -0
  19. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/icons/wifi3.png +0 -0
  20. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/icons/wifi4.png +0 -0
  21. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/iraq_id_extraction_withopenai.py +0 -0
  22. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/jor_passport_extraction.py +0 -0
  23. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/lebanon_id_extraction.py +0 -0
  24. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/liveness_spoofing_v2.py +0 -0
  25. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/ocr_utils.py +0 -0
  26. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/pse_passport_extraction.py +0 -0
  27. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/spoof_resources/2.7_80x80_MiniFASNetV2.pth +0 -0
  28. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/spoof_resources/4_0_0_80x80_MiniFASNetV1SE.pth +0 -0
  29. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/spoof_resources/MiniFASNet.py +0 -0
  30. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/spoof_resources/__init__.py +0 -0
  31. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/spoof_resources/functional.py +0 -0
  32. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/spoof_resources/generate_patches.py +0 -0
  33. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/spoof_resources/transform.py +0 -0
  34. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/sudan_passport_extraction.py +0 -0
  35. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/syr_passport_extraction.py +0 -0
  36. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage/uae_id_extraction.py +0 -0
  37. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage.egg-info/SOURCES.txt +0 -0
  38. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage.egg-info/dependency_links.txt +0 -0
  39. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage.egg-info/requires.txt +0 -0
  40. {idvpackage-3.0.13 → idvpackage-3.0.14}/idvpackage.egg-info/top_level.txt +0 -0
  41. {idvpackage-3.0.13 → idvpackage-3.0.14}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idvpackage
3
- Version: 3.0.13
3
+ Version: 3.0.14
4
4
  Summary: This repository contains a Python program designed to execute Optical Character Recognition (OCR) and Facial Recognition on images.
5
5
  Home-page: https://github.com/NymCard-Payments/project_idv_package
6
6
  Classifier: Programming Language :: Python :: 3
@@ -346,13 +346,14 @@ def load_and_process_image_deepface(image_input, country=None):
346
346
 
347
347
  if face_objs is None:
348
348
  continue
349
-
350
349
  else:
351
350
  break # Exit loop on first valid detection
352
351
 
353
352
  # Keep best fallback (just in case)
354
353
 
355
- if best_face_objs is None or best_confidence < CONFIDENCE_THRESHOLD:
354
+
355
+ #remove best_confidence < CONFIDENCE_THRESHOLD to take best of all angles when confidence is less than threshold
356
+ if best_face_objs is None:
356
357
  print(f"No valid face found (threshold={CONFIDENCE_THRESHOLD})")
357
358
  return [], []
358
359
 
@@ -896,34 +896,35 @@ class IdentityVerification:
896
896
  from idvpackage.ocr_utils import document_on_printed_paper
897
897
  from idvpackage.qatar_id_extraction import get_response_from_openai_qat
898
898
 
899
- front_data = {"error": "", "doc_type": "national_identity_card"}
899
+ result = {"error": "", "doc_type": "national_identity_card"}
900
900
 
901
901
  try:
902
902
  processed_front_id ,compressed_image_data= self.image_conversion_and_compression(front_id)
903
903
  st = time.time()
904
- front_data_fields = get_response_from_openai_qat(
904
+
905
+ front_data = get_response_from_openai_qat(
905
906
  compressed_image_data, "front", country, self.openai_key
906
907
  )
907
908
  logging.info(f"----------------Time taken for vision front: {time.time() - st} seconds\n")
908
- logging.info(f"front_data_fields: {json.dumps(front_data_fields, indent=2, ensure_ascii=False)}")
909
+ logging.info(f"front_data: {json.dumps(front_data, indent=2, ensure_ascii=False)}")
909
910
 
910
- front_data_fields['issuing_country'] = 'QAT'
911
+ front_data['issuing_country'] = 'QAT'
912
+
913
+ if not front_data.get("header_verified", False):
914
+ result["error"] = "not_front_id"
915
+ return result
911
916
 
912
- if not front_data_fields["header_verified"]:
913
- front_data["error"] = "not_front_id"
914
- return front_data
915
-
916
917
  logging.info( f"----------------Time taken for qatar OpenAI and final extraction front: {time.time() - st} seconds\n")
917
918
 
918
- expiry_date = front_data_fields.get("expiry_date", "")
919
+ expiry_date = front_data.get("expiry_date", "")
919
920
  try:
920
921
  if expiry_date:
921
922
  logging.info(f"Extracted Expiry Date for expiry verification: {expiry_date}")
922
923
  from idvpackage.ocr_utils import is_expired_id
923
924
  if is_expired_id(expiry_date):
924
- front_data['error'] = 'expired_id'
925
+ result['error'] = 'expired_id'
925
926
  logging.info(f"ID is expired with expiry date: {expiry_date}")
926
- return front_data
927
+ return result
927
928
  except Exception as e:
928
929
  logging.info(f"Error in expiry date calculation: {e}")
929
930
 
@@ -937,9 +938,9 @@ class IdentityVerification:
937
938
 
938
939
 
939
940
  if front_face_encodings is None or len(front_face_encodings) == 0:
940
- front_data['error'] = 'face_not_detected'
941
+ result['error'] = 'face_not_detected'
941
942
  logging.info("No face detected in front image")
942
- return front_data
943
+ return result
943
944
 
944
945
  logging.info(f"----------------Time taken for face extraction front: {time.time() - st} seconds\n")
945
946
 
@@ -964,8 +965,8 @@ class IdentityVerification:
964
965
  "front_face_encodings": front_face_encodings_str,
965
966
  }
966
967
 
967
- front_data_fields.update(front_data_temp)
968
- front_data.update(front_data_fields)
968
+ front_data.update(front_data_temp)
969
+ result.update(front_data)
969
970
 
970
971
  required_keys = ["expiry_date", "name", "id_number"]
971
972
  empty_string_keys = [
@@ -975,18 +976,18 @@ class IdentityVerification:
975
976
  ]
976
977
 
977
978
  if empty_string_keys:
978
- front_data["error"] = "missing_key_fields"
979
+ result["error"] = "missing_key_fields"
979
980
 
980
981
  if front_data.get("error"):
981
- return front_data
982
+ return result
982
983
 
983
984
 
984
985
  except Exception as e:
985
986
  logging.info(f"exception in QAT front ID extraction: {e}")
986
- front_data["error"] = "bad_image"
987
- front_data["error_details"] = e
987
+ result["error"] = "bad_image"
988
+ result["error_details"] = e
988
989
 
989
- return front_data
990
+ return result
990
991
 
991
992
  if country == "LBN":
992
993
  logging.info("----------------Working on LBN\n")
@@ -1034,9 +1035,10 @@ class IdentityVerification:
1034
1035
  logging.info(f"----------------Time taken for OpenAI and final extraction front: {time.time() - st} seconds\n")
1035
1036
  logging.info(f"Extracted LBN front data fields: {json.dumps(front_data_fields, indent=2, ensure_ascii=False)}")
1036
1037
 
1037
- if front_data_fields.get('header_verified') is not True:
1038
+ if not front_data_fields.get("header_verified", False):
1038
1039
  front_data["error"] = "not_front_id"
1039
1040
  return front_data
1041
+
1040
1042
  if 'id_number' in front_data_fields:
1041
1043
  id_number = front_data_fields['id_number']
1042
1044
  if id_number and len(id_number) < 12:
@@ -1200,7 +1202,7 @@ class IdentityVerification:
1200
1202
  logging.info(f"Extracted SDN front data fields: {json.dumps(front_data_fields, indent=2, ensure_ascii=False)}")
1201
1203
  logging.info(f"----------------Time taken for OpenAI and final extraction front: {time.time() - st} seconds\n")
1202
1204
 
1203
- if not front_data_fields['header_verified']:
1205
+ if not front_data_fields.get("header_verified", False):
1204
1206
  front_data_fields['error'] = 'not_front_id'
1205
1207
  logging.error(f"ID not verified in the document data: {front_data_fields['header_verified']}")
1206
1208
  return front_data_fields
@@ -1789,7 +1791,7 @@ class IdentityVerification:
1789
1791
 
1790
1792
  if country == "QAT":
1791
1793
  from idvpackage.qatar_id_extraction import get_response_from_openai_qat
1792
- back_data = {"error": "", "doc_type": "national_identity_card"}
1794
+ result = {"error": "", "doc_type": "national_identity_card"}
1793
1795
  try:
1794
1796
  processed_back_id = self.image_conversion(back_id)
1795
1797
  compressed_image = BytesIO()
@@ -1799,11 +1801,15 @@ class IdentityVerification:
1799
1801
  compressed_image_data = compressed_image.getvalue()
1800
1802
 
1801
1803
  st = time.time()
1802
- back_extraction_result = get_response_from_openai_qat(compressed_image_data, "back", country, self.openai_key)
1804
+ back_data = get_response_from_openai_qat(compressed_image_data, "back", country, self.openai_key)
1803
1805
  logging.info(f"----------------Time taken for OpenAI and final extraction back: {time.time() - st} seconds\n")
1804
- logging.info(f"back_extraction_result: {json.dumps(back_extraction_result, ensure_ascii=False, indent=2)}")
1805
-
1806
- back_data.update(back_extraction_result)
1806
+ logging.info(f"back_extraction_result: {json.dumps(back_data, ensure_ascii=False, indent=2)}")
1807
+
1808
+ if not back_data.get('back_header_verified', False):
1809
+ result["error"] = "not_back_id"
1810
+ return result
1811
+
1812
+ result.update(back_data)
1807
1813
  back_data_update = {
1808
1814
  "back_extracted_data": "",
1809
1815
  "back_coloured": True,
@@ -1814,13 +1820,13 @@ class IdentityVerification:
1814
1820
  "back_glare": "clear",
1815
1821
  }
1816
1822
 
1817
- back_data.update(back_data_update)
1823
+ result.update(back_data_update)
1818
1824
 
1819
1825
  except Exception as e:
1820
- back_data["error"] = "bad_image"
1821
- back_data["error_details"] = e
1826
+ result["error"] = "bad_image"
1827
+ result["error_details"] = e
1822
1828
 
1823
- return back_data
1829
+ return result
1824
1830
 
1825
1831
  if country == "LBN":
1826
1832
  from idvpackage.blur_detection import is_image_blur
@@ -2341,7 +2347,7 @@ class IdentityVerification:
2341
2347
  )
2342
2348
  logging.info(f"passport_details: {json.dumps(passport_details, ensure_ascii=False, indent=2)}")
2343
2349
 
2344
- if not passport_details['header_verified'] :
2350
+ if not passport_details.get('header_verified', False):
2345
2351
  passport_data["error"] = "not_passport"
2346
2352
  return passport_data
2347
2353
 
@@ -2499,7 +2505,7 @@ class IdentityVerification:
2499
2505
  logging.info(f"Passport details extracted: {json.dumps(passport_details, ensure_ascii=False, indent=2)}")
2500
2506
  logging.info(f"----------------Time taken for OpenAI and final extraction passport: {time.time() - st} seconds\n")
2501
2507
 
2502
- if not passport_details['header_verified']:
2508
+ if not passport_details.get('header_verified', False):
2503
2509
  passport_data["error"] = "not_passport"
2504
2510
  return passport_data
2505
2511
 
@@ -2639,7 +2645,7 @@ class IdentityVerification:
2639
2645
  )
2640
2646
  logging.info(f"passport_details: {json.dumps(passport_details, ensure_ascii=False, indent=2)}")
2641
2647
 
2642
- if not passport_details['header_verified']:
2648
+ if not passport_details.get('header_verified', False):
2643
2649
  passport_data["error"] = "not_passport"
2644
2650
  return passport_data
2645
2651
 
@@ -2779,10 +2785,7 @@ class IdentityVerification:
2779
2785
  logging.info(f"----------------Passport details: {json.dumps(passport_details, indent=4, ensure_ascii=False)}\n")
2780
2786
  logging.info(f"----------------Time taken for openai final extraction passport: {time.time() - st} seconds\n")
2781
2787
 
2782
- if (
2783
- passport_details.get("header_verified", "")
2784
- and passport_details["header_verified"] == "False"
2785
- ):
2788
+ if not passport_details.get("header_verified", False):
2786
2789
  passport_data["error"] = "not_passport"
2787
2790
  return passport_data
2788
2791
 
@@ -2911,7 +2914,7 @@ class IdentityVerification:
2911
2914
  f"----------------Time taken for OpenAI and final extraction passport: {time.time() - st} seconds\n"
2912
2915
  )
2913
2916
 
2914
- if passport_details.get("header_verified", "") == "False":
2917
+ if not passport_details.get("header_verified", False):
2915
2918
  passport_data["error"] = "not_passport"
2916
2919
  return passport_data
2917
2920
 
@@ -23,7 +23,7 @@ Extract ALL fields from this Qatar National ID **front side** image with high ac
23
23
 
24
24
  Return a JSON object with the following fields (use the exact field names):
25
25
 
26
- -id_number: The ID number exactly as shown on the card (preserve original format)
26
+ - id_number: The ID number exactly as shown on the card (preserve original format)
27
27
  - dob: Date of birth exactly as shown on the card, but always return in DD/MM/YYYY format (e.g., '15/06/1990'). If the card shows a different format, convert it to DD/MM/YYYY.
28
28
  - expiry_date: Date of expiry exactly as shown on the card, but always return in DD/MM/YYYY format (e.g., '15/06/1990'). If the card shows a different format, convert it to DD/MM/YYYY.
29
29
  - name: Full name in English as printed on the card (extract exactly as written)
@@ -49,8 +49,8 @@ Extract ALL fields from this Qatar National ID **back side** image with high acc
49
49
  Return a JSON object with the following fields (use the exact field names):
50
50
 
51
51
  - employer: Employer name in Arabic as printed on the card (extract exactly as written)
52
- - employer_en: Translate the Arabic employer name to English (e.g., شركة → Company, مؤسسة → Establishment)
53
- - passport_number: Passport number as printed on the card (extract exactly as written, e.g., EA0605652)
52
+ - employer_en: Translate the Arabic employer name to English
53
+ - passport_number: Passport number as printed on the card (extract exactly as written)
54
54
  - passport_expiry: Passport expiry date always in DD/MM/YYYY format.
55
55
  - back_header_verified: Return True if one of the texts present in the image is "Director General of the General Department" or "Directorate of Passports" or "Passport number" or "Serial"; otherwise False.
56
56
  - card_number: Serial number exactly as shown on the card (preserve original format)
@@ -64,7 +64,7 @@ Instructions:
64
64
 
65
65
  class QatarFront(BaseModel):
66
66
 
67
- id_number: str = Field(...,min_length=9, max_length=11,
67
+ id_number: str = Field(...,min_length=11, max_length=11,
68
68
  description = "The ID number exactly as shown on the card (preserve original format)",
69
69
  )
70
70
 
@@ -114,29 +114,29 @@ class QatarFront(BaseModel):
114
114
  )
115
115
  class QatarBack(BaseModel):
116
116
  employer: str = Field(...,
117
- description = "Employer name in Arabic (extract exactly as written on the card)",
117
+ description = "Employer name in Arabic (extract exactly as written on the card) return empty string if not present",
118
118
  )
119
119
 
120
120
  employer_en: str = Field(...,
121
- description = "TRANSLATE the Arabic employer name to English (e.g., شركة Company, مؤسسة Establishment)",
121
+ description = "TRANSLATE the Arabic employer name to English, if employer is not present return empty string",
122
122
 
123
123
  )
124
124
 
125
125
  passport_number: str = Field(...,
126
- description = "Passport number extract exactly as written on the card ex: EA0605652."
126
+ description = "Passport number extract exactly as written on the card, return empty string if not present",
127
127
  )
128
128
 
129
129
  passport_expiry: str = Field(...,
130
- description = "Passport expiry date exactly as shown on the card (preserve (dd/mm/yyyy) format)",
130
+ description = "Passport expiry date exactly as shown on the card (preserve (dd/mm/yyyy) format), return empty string if not present",
131
131
  )
132
132
 
133
133
  back_header_verified: bool = Field(
134
134
  ...,
135
- description=" Return True if one of the texts present in the image Director General of the General Department or Directorate of Passports or Passport number or Serial",
135
+ description=" Return True if one of the texts present in the image Director General of the General Department or Directorate of Passports or Passport number or Serial else return False",
136
136
  )
137
137
 
138
138
  card_number: str = Field(...,
139
- description = "Serial number exactly as shown on the card (preserve original format)",
139
+ description = "Serial number exactly as shown on the card (preserve original format), return empty string if not present",
140
140
  )
141
141
 
142
142
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idvpackage
3
- Version: 3.0.13
3
+ Version: 3.0.14
4
4
  Summary: This repository contains a Python program designed to execute Optical Character Recognition (OCR) and Facial Recognition on images.
5
5
  Home-page: https://github.com/NymCard-Payments/project_idv_package
6
6
  Classifier: Programming Language :: Python :: 3
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = idvpackage
3
- version = 3.0.13
3
+ version = 3.0.14
4
4
  description = This repository contains a Python program designed to execute Optical Character Recognition (OCR) and Facial Recognition on images.
5
5
  long_description = file: README.md
6
6
  long_description_content_type = text/markdown
@@ -9,7 +9,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
9
9
 
10
10
  setup(
11
11
  name="idvpackage",
12
- version="3.0.13",
12
+ version="3.0.14",
13
13
  description=(
14
14
  "This repository contains a Python program designed to execute Optical Character Recognition (OCR)"
15
15
  " and Facial Recognition on images."
File without changes
File without changes
File without changes
File without changes