Spaces:
Running on Zero
Running on Zero
Update test_suite.py
Browse files- test_suite.py +117 -146
test_suite.py
CHANGED
|
@@ -1,159 +1,130 @@
|
|
| 1 |
-
import streamlit as st
|
| 2 |
import pdfplumber
|
| 3 |
import re
|
| 4 |
from pdf_engine import extract_header_value, apply_value_replacement
|
| 5 |
from parser_welspun import extract_welspun_items
|
| 6 |
from parser_bkt import extract_bkt_items
|
| 7 |
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
header_rules = shipper_info.get("mapping_rules", {})
|
| 22 |
item_rules = shipper_info.get("item_table_rules", {})
|
| 23 |
assigned_parser = shipper_info.get("item_table_rule_name", "parser_welspun").strip().lower()
|
| 24 |
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
else:
|
| 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 |
else:
|
| 76 |
-
|
| 77 |
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
st.markdown("#### 📋 Item Rule Configuration")
|
| 86 |
-
st.write(f"* **Target Excel Column:** `{col_letter}`")
|
| 87 |
-
st.write(f"* **Rule Type:** `{rule_type}`")
|
| 88 |
-
st.write(f"* **Rule Value / Detail:** `{rule_val}`")
|
| 89 |
-
|
| 90 |
-
st.markdown("---")
|
| 91 |
-
st.markdown(f"#### 📊 Row-by-Row Preview for Column `{col_letter}`")
|
| 92 |
-
|
| 93 |
-
# सही पार्सर कॉल करके सारे आइटम्स निकालें
|
| 94 |
-
if "bkt" in assigned_parser:
|
| 95 |
-
parsed_items = extract_bkt_items(pdf_lines)
|
| 96 |
-
else:
|
| 97 |
-
parsed_items = extract_welspun_items(pdf_lines, pdf_text=pdf_text)
|
| 98 |
-
|
| 99 |
-
if parsed_items:
|
| 100 |
-
preview_table_data = []
|
| 101 |
-
for idx, item in enumerate(parsed_items):
|
| 102 |
-
excel_row_num = 2 + idx # मान लेते हैं डेटा Row 2 से शुरू होता है
|
| 103 |
-
cell_target = f"{col_letter}{excel_row_num}"
|
| 104 |
-
|
| 105 |
-
nums = item.get("nums", [])
|
| 106 |
-
r_val_lower = str(rule_val).lower().strip()
|
| 107 |
-
f_name_lower = target_field.lower().strip()
|
| 108 |
-
extracted_cell_val = ""
|
| 109 |
-
|
| 110 |
-
# सिमुलेशन लॉजिक ठीक वैसे ही जैसे प्रोसेसर में चलता है
|
| 111 |
-
if rule_type == "Constant Text":
|
| 112 |
-
extracted_cell_val = apply_value_replacement(rule_val, rule_val)
|
| 113 |
-
elif rule_type == "Excel Cell Reference":
|
| 114 |
-
extracted_cell_val = f"={rule_val}"
|
| 115 |
-
elif rule_type == "Smart Detection":
|
| 116 |
-
desc = item.get("description_text", "").upper()
|
| 117 |
-
if "PCS" in desc or "PC" in desc:
|
| 118 |
-
extracted_cell_val = "PCS"
|
| 119 |
-
else:
|
| 120 |
-
extracted_cell_val = rule_val if rule_val else "SET"
|
| 121 |
-
else:
|
| 122 |
-
# Standard PDF Row Item logic matching
|
| 123 |
-
if "igst %" in r_val_lower or "igst rate" in f_name_lower:
|
| 124 |
-
extracted_cell_val = nums[5] if len(nums) > 5 else ""
|
| 125 |
-
elif "igst amt" in r_val_lower or "igst amount" in f_name_lower:
|
| 126 |
-
extracted_cell_val = nums[6] if len(nums) > 6 else ""
|
| 127 |
-
elif "hs" in r_val_lower or "ritc" in f_name_lower or "hs code" in r_val_lower:
|
| 128 |
-
extracted_cell_val = item.get("hs_code", "")
|
| 129 |
-
elif "description" in r_val_lower or "description" in f_name_lower:
|
| 130 |
-
extracted_cell_val = item.get("description_text", "")
|
| 131 |
-
elif "dbk" in r_val_lower or "drawback" in f_name_lower or col_letter == "S":
|
| 132 |
-
extracted_cell_val = item.get("dbk_found", "")
|
| 133 |
-
elif "weight" in r_val_lower or "net wt" in f_name_lower:
|
| 134 |
-
extracted_cell_val = nums[0] if len(nums) > 0 else ""
|
| 135 |
-
elif "qty" in r_val_lower or "quantity" in f_name_lower:
|
| 136 |
-
extracted_cell_val = nums[1] if len(nums) > 1 else ""
|
| 137 |
-
elif "rate" in r_val_lower:
|
| 138 |
-
extracted_cell_val = nums[2] if len(nums) > 2 else ""
|
| 139 |
-
elif "amount" in r_val_lower or "goods value" in f_name_lower:
|
| 140 |
-
extracted_cell_val = nums[3] if len(nums) > 3 else ""
|
| 141 |
-
elif "taxable" in r_val_lower:
|
| 142 |
-
extracted_cell_val = nums[4] if len(nums) > 4 else ""
|
| 143 |
-
else:
|
| 144 |
-
extracted_cell_val = rule_val
|
| 145 |
-
|
| 146 |
-
if "=" in str(rule_val):
|
| 147 |
-
extracted_cell_val = apply_value_replacement(str(extracted_cell_val), str(rule_val))
|
| 148 |
-
|
| 149 |
-
preview_table_data.append({
|
| 150 |
-
"Item Sr No": idx + 1,
|
| 151 |
-
"Excel Cell": cell_target,
|
| 152 |
-
"Extracted Value": str(extracted_cell_val)
|
| 153 |
-
})
|
| 154 |
-
|
| 155 |
-
# Streamlit में खूबसूरत टेबल दिखाना
|
| 156 |
-
st.dataframe(preview_table_data, use_container_width=True)
|
| 157 |
-
st.success(f"🎉 कुल {len(parsed_items)} आइटम्स की रो-बाय-रो रिपोर्ट सफलतापूर्वक जनरेट हो गई है!")
|
| 158 |
-
else:
|
| 159 |
-
st.warning("⚠️ इस PDF में कोई आइटम रो नहीं मिली या पार्सर से डेटा एक्सट्रेक्ट नहीं हुआ।")
|
|
|
|
|
|
|
| 1 |
import pdfplumber
|
| 2 |
import re
|
| 3 |
from pdf_engine import extract_header_value, apply_value_replacement
|
| 4 |
from parser_welspun import extract_welspun_items
|
| 5 |
from parser_bkt import extract_bkt_items
|
| 6 |
|
| 7 |
+
# 🚀 LayoutLMv3 & Document AI Integration Imports
|
| 8 |
+
from transformers import LayoutLMv3Processor, LayoutLMv3ForTokenClassification
|
| 9 |
+
import torch
|
| 10 |
+
from PIL import Image
|
| 11 |
+
import io
|
| 12 |
+
|
| 13 |
+
def process_document_with_layoutlmv3(image_or_pdf_bytes):
|
| 14 |
+
"""
|
| 15 |
+
ZeroGPU / GPU environment ke liye LayoutLMv3 processing function.
|
| 16 |
+
Yeh document ki visual bounding boxes aur text dono ko process karta hai.
|
| 17 |
+
"""
|
| 18 |
+
try:
|
| 19 |
+
# Note: Model loading aur inference yahan ZeroGPU decorator ke antargat run hoga
|
| 20 |
+
processor = LayoutLMv3Processor.from_pretrained("microsoft/layoutlmv3-base")
|
| 21 |
+
# Model initialization aur inference logic yahan aage configure kiya ja sakta hai
|
| 22 |
+
return True, "LayoutLMv3 processor initialized successfully."
|
| 23 |
+
except Exception as e:
|
| 24 |
+
return False, str(e)
|
| 25 |
+
|
| 26 |
+
def run_universal_test_suite_backend(selected_shipper, shipper_database, pdf_lines, pdf_text, test_category, target_field):
|
| 27 |
+
"""
|
| 28 |
+
Streamlit-free backend test suite jo Gradio ke through single field ya row-by-row inspection run karta hai.
|
| 29 |
+
"""
|
| 30 |
+
if not pdf_lines:
|
| 31 |
+
return "💡 कृपया पहले इनवॉइस PDF अपलोड करें, फिर टेस्ट रन करें।"
|
| 32 |
+
|
| 33 |
+
shipper_info = shipper_database.get(selected_shipper, {})
|
| 34 |
header_rules = shipper_info.get("mapping_rules", {})
|
| 35 |
item_rules = shipper_info.get("item_table_rules", {})
|
| 36 |
assigned_parser = shipper_info.get("item_table_rule_name", "parser_welspun").strip().lower()
|
| 37 |
|
| 38 |
+
if test_category == "Header Fields Rules":
|
| 39 |
+
if target_field not in header_rules:
|
| 40 |
+
return f"⚠️ Header Field '{target_field}' nahi mila."
|
| 41 |
+
|
| 42 |
+
rule_data = header_rules[target_field]
|
| 43 |
+
ky = rule_data.get("keyword", "")
|
| 44 |
+
pos = rule_data.get("position", "Right (आगे)")
|
| 45 |
+
cl = rule_data.get("cell", "").strip()
|
| 46 |
+
m_mode = rule_data.get("match_mode", "Exact Word")
|
| 47 |
+
stop_kw = rule_data.get("stop_kw", "")
|
| 48 |
+
final_flt = rule_data.get("filter", "None")
|
| 49 |
+
|
| 50 |
+
final_val = extract_header_value(pdf_lines, pdf_text, ky, pos, m_mode, stop_kw, final_flt)
|
| 51 |
+
|
| 52 |
+
display_cell = cl if cl else 'Not Set'
|
| 53 |
+
if cl and cl.isalpha():
|
| 54 |
+
display_cell = f"{cl.upper()}2 (Dynamic Auto-Increment Row)"
|
| 55 |
+
|
| 56 |
+
result_summary = (
|
| 57 |
+
f"🔍 Inspection Result: {target_field}\n"
|
| 58 |
+
f"----------------------------------------\n"
|
| 59 |
+
f"📋 Parameters:\n"
|
| 60 |
+
f"- Target Excel Cell: {display_cell}\n"
|
| 61 |
+
f"- Keyword: {ky if ky else 'N/A'}\n"
|
| 62 |
+
f"- Match Mode: {m_mode}\n"
|
| 63 |
+
f"- Filter: {final_flt}\n\n"
|
| 64 |
+
f"🎯 Extracted Value: {final_val if final_val else 'BLANK / NOT FOUND'}"
|
| 65 |
+
)
|
| 66 |
+
return result_summary
|
| 67 |
+
|
| 68 |
+
else:
|
| 69 |
+
if target_field not in item_rules:
|
| 70 |
+
return f"⚠️ Item Field '{target_field}' nahi mila."
|
| 71 |
+
|
| 72 |
+
rule_info = item_rules[target_field]
|
| 73 |
+
col_letter = rule_info.get("col", "").upper()
|
| 74 |
+
rule_type = rule_info.get("type", "PDF Row Item")
|
| 75 |
+
rule_val = rule_info.get("rule", "")
|
| 76 |
+
|
| 77 |
+
if "bkt" in assigned_parser:
|
| 78 |
+
parsed_items = extract_bkt_items(pdf_lines)
|
| 79 |
else:
|
| 80 |
+
parsed_items = extract_welspun_items(pdf_lines, pdf_text=pdf_text)
|
| 81 |
+
|
| 82 |
+
if not parsed_items:
|
| 83 |
+
return "⚠️ इस PDF में कोई आइटम रो नहीं मिली या पार्सर से डेटा एक्सट्रेक्ट नहीं हुआ।"
|
| 84 |
+
|
| 85 |
+
preview_lines = [f"📊 Row-by-Row Preview for Column {col_letter}:"]
|
| 86 |
+
for idx, item in enumerate(parsed_items):
|
| 87 |
+
excel_row_num = 2 + idx
|
| 88 |
+
cell_target = f"{col_letter}{excel_row_num}"
|
| 89 |
+
nums = item.get("nums", [])
|
| 90 |
+
r_val_lower = str(rule_val).lower().strip()
|
| 91 |
+
f_name_lower = target_field.lower().strip()
|
| 92 |
+
extracted_cell_val = ""
|
| 93 |
+
|
| 94 |
+
if rule_type == "Constant Text":
|
| 95 |
+
extracted_cell_val = apply_value_replacement(rule_val, rule_val)
|
| 96 |
+
elif rule_type == "Excel Cell Reference":
|
| 97 |
+
extracted_cell_val = f"={rule_val}"
|
| 98 |
+
elif rule_type == "Smart Detection":
|
| 99 |
+
desc = item.get("description_text", "").upper()
|
| 100 |
+
extracted_cell_val = "PCS" if ("PCS" in desc or "PC" in desc) else (rule_val if rule_val else "SET")
|
| 101 |
+
else:
|
| 102 |
+
if "igst %" in r_val_lower or "igst rate" in f_name_lower:
|
| 103 |
+
extracted_cell_val = nums[5] if len(nums) > 5 else ""
|
| 104 |
+
elif "igst amt" in r_val_lower or "igst amount" in f_name_lower:
|
| 105 |
+
extracted_cell_val = nums[6] if len(nums) > 6 else ""
|
| 106 |
+
elif "hs" in r_val_lower or "ritc" in f_name_lower or "hs code" in r_val_lower:
|
| 107 |
+
extracted_cell_val = item.get("hs_code", "")
|
| 108 |
+
elif "description" in r_val_lower or "description" in f_name_lower:
|
| 109 |
+
extracted_cell_val = item.get("description_text", "")
|
| 110 |
+
elif "dbk" in r_val_lower or "drawback" in f_name_lower or col_letter == "S":
|
| 111 |
+
extracted_cell_val = item.get("dbk_found", "")
|
| 112 |
+
elif "weight" in r_val_lower or "net wt" in f_name_lower:
|
| 113 |
+
extracted_cell_val = nums[0] if len(nums) > 0 else ""
|
| 114 |
+
elif "qty" in r_val_lower or "quantity" in f_name_lower:
|
| 115 |
+
extracted_cell_val = nums[1] if len(nums) > 1 else ""
|
| 116 |
+
elif "rate" in r_val_lower:
|
| 117 |
+
extracted_cell_val = nums[2] if len(nums) > 2 else ""
|
| 118 |
+
elif "amount" in r_val_lower or "goods value" in f_name_lower:
|
| 119 |
+
extracted_cell_val = nums[3] if len(nums) > 3 else ""
|
| 120 |
+
elif "taxable" in r_val_lower:
|
| 121 |
+
extracted_cell_val = nums[4] if len(nums) > 4 else ""
|
| 122 |
else:
|
| 123 |
+
extracted_cell_val = rule_val
|
| 124 |
|
| 125 |
+
if "=" in str(rule_val):
|
| 126 |
+
extracted_cell_val = apply_value_replacement(str(extracted_cell_val), str(rule_val))
|
| 127 |
+
|
| 128 |
+
preview_lines.append(f"Row {idx+1} | Cell: {cell_target} | Value: {extracted_cell_val}")
|
| 129 |
+
|
| 130 |
+
return "\n".join(preview_lines)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|