import gradio as gr
import os
import pandas as pd
import shutil
import sys
# ---------------------------------------------------------
# IMPORT LOGICCODE
# ---------------------------------------------------------
# We expect logiccode.py to be in the same directory
try:
import logiccode
except ImportError as e:
print("CRITICAL ERROR: Could not import 'logiccode.py'.")
print(f"Ensure logiccode.py is in the same directory as app.py. Error: {e}")
sys.exit(1)
# ---------------------------------------------------------
# MOCK ARGUMENTS
# ---------------------------------------------------------
# This class mimics the argparse object that logiccode expects
class MockArgs:
def __init__(self):
self.debug = False
self.pages = 3
self.file = []
self.inputkeywords = ""
self.required = []
self.fuzzy = True
self.visualize = False
# Initialize args in logiccode if not already present
if not hasattr(logiccode, 'args'):
logiccode.args = MockArgs()
# ---------------------------------------------------------
# CORE PROCESSING FUNCTION
# ---------------------------------------------------------
def process_documents(files, keywords_input, required_docs, fuzzy_match_enabled, debug_enabled):
"""
Process uploaded files using the imported logiccode module.
"""
# 1. Update global args in logiccode based on UI inputs
logiccode.args.debug = debug_enabled
logiccode.args.fuzzy = fuzzy_match_enabled
# Initialize output containers
results = []
gallery_images = []
logs = []
# Parse keywords
user_keywords = [kw.strip() for kw in keywords_input.split() if kw.strip()]
# Track found documents for "Required" check
found_documents = set()
all_matched_keywords_per_file = []
if not files:
return "
Verification Summary
"""
# Document Status
doc_status_bool = True
if required_set:
if missing_docs:
doc_status_bool = False
html += f"
❌ Missing Documents: {', '.join(sorted(missing_docs))}
"
else:
html += f"
✅ Documents: All required types found.
"
else:
html += "
ℹ️ No specific document types required.
"
# Keyword Status
kw_status_bool = True
if missing_keywords:
kw_status_bool = False
html += f"
❌ Missing Keywords: {', '.join(sorted(missing_keywords))}
"
else:
html += f"
✅ Keywords: All keywords found.
"
# Final Status
overall_color = "#10b981" if (doc_status_bool and kw_status_bool) else "#ef4444"
overall_text = "VERIFIED" if (doc_status_bool and kw_status_bool) else "ACTION REQUIRED"
html += f"
"
html += f"
{overall_text}
"
html += "
"
return html
# ---------------------------------------------------------
# GRADIO UI SETUP
# ---------------------------------------------------------
theme = gr.themes.Soft(
primary_hue="blue",
secondary_hue="slate",
).set(
body_background_fill="#f9fafb",
block_background_fill="white",
block_border_width="1px"
)
with gr.Blocks(theme=theme, title="DocuVerify Pro") as demo:
gr.Markdown(
"""
# 📄 Intelligent Document Verification
Upload documents, specify required types, and verify content matches automatically.
"""
)
with gr.Row():
# Left Column: Inputs
with gr.Column(scale=4):
files_input = gr.File(
file_count="multiple",
label="1. Upload Documents",
file_types=[".pdf", ".png", ".jpg", ".jpeg", ".bmp"],
height=250
)
keywords_input = gr.Textbox(
label="2. Keywords to Verify",
placeholder="Name, ID Number, Date of Birth...",
info="Enter values that MUST appear in the documents (space separated)",
lines=2
)
# Right Column: Configuration
with gr.Column(scale=3):
# Fetch doc types dynamically from logiccode
available_types = sorted(list(logiccode.DOC_KEYWORDS.keys())) if hasattr(logiccode, 'DOC_KEYWORDS') else []
required_docs_input = gr.Dropdown(
choices=available_types,
multiselect=True,
label="3. Required Document Types",
info="Which documents are mandatory?",
value=[]
)
with gr.Group():
gr.Markdown("### Settings")
fuzzy_checkbox = gr.Checkbox(value=True, label="Enable Fuzzy Matching (Approximate spelling)")
debug_checkbox = gr.Checkbox(value=False, label="Show Debug Logs")
verify_btn = gr.Button("🔍 Verify Documents", variant="primary", size="lg")
gr.Markdown("---")
# Results Area
with gr.Row():
# Summary Box
with gr.Column(scale=1):
status_output = gr.HTML(label="Overall Status")
# Detailed Tabs
with gr.Column(scale=2):
with gr.Tabs():
with gr.TabItem("📊 Results Table"):
results_df = gr.Dataframe(
headers=["File", "Type", "Score", "Status", "Matched Keywords"],
interactive=False
)
with gr.TabItem("🖼️ Document Gallery"):
gallery = gr.Gallery(
label="Processed Images",
show_label=False,
columns=[3], rows=[2],
object_fit="contain",
height="auto"
)
with gr.TabItem("📝 System Logs"):
logs_output = gr.Textbox(
label="Processing Logs",
lines=15,
interactive=False,
show_copy_button=True
)
# Event Trigger
verify_btn.click(
fn=process_documents,
inputs=[files_input, keywords_input, required_docs_input, fuzzy_checkbox, debug_checkbox],
outputs=[status_output, gallery, results_df, logs_output]
)
if __name__ == "__main__":
# Increase max file size if needed, allow sharing
demo.launch(share=False, server_name="0.0.0.0")