Cassius1Morbant's picture
Upload 199 files
10080df verified
# kbis_gradio_ui.py — Standalone Gradio UI for K-bis Analysis
# Jonathan Corke © 2025 – ALL RIGHTS RESERVED
import gradio as gr
import os
import tempfile
from datetime import datetime
from weasyprint import HTML # pip install weasyprint
# Import your core functions
from extract import extract_pdf_text_with_easyocr # OCR extraction
from parsepers import parse_full_kbis # Full K-bis parsing
# Gradio Theme & CSS (your dark theme with fixes)
theme = gr.themes.Base(
primary_hue="violet",
secondary_hue="orange",
neutral_hue="gray",
).set(
body_background_fill="#1a1a1a",
block_background_fill="#1e1e1e",
input_background_fill="#2d2d2d",
button_primary_background_fill="#f97316",
button_primary_background_fill_hover="#ea580c",
)
css = """
/* Full CSS from your original app — insert here */
.gradio-container {
background: #1a1a1a !important;
color: #e4e4e7 !important;
font-family: 'Inter', system-ui, sans-serif;
font-size: 15px;
line-height: 1.6;
}
/* Radio button and input visibility fixes */
.radio label, .radio input[type="radio"] + span {
color: #ffffff !important;
background-color: rgb(45, 45, 45) !important;
}
.radio input[type="radio"]:checked + span {
background-color: #6d28d9 !important;
}
.radio label:hover {
background-color: #5b21b6 !important;
}
input, textarea {
color: #ffffff !important;
}
"""
# Export directory
EXPORT_DIR = "exports"
os.makedirs(EXPORT_DIR, exist_ok=True)
with gr.Blocks(theme=theme, css=css, title="K-bis Analyzer") as demo:
gr.HTML("""
<div id="chat-header">
<div class="brand">
<div class="brand-icon">K-bis</div>
<div class="brand-text">
<h1>K-bis Analyzer</h1>
<p>Automatic analysis of K-bis extracts via OCR and structured parsing</p>
<p>Jonathan Corke, all rights reserved</p>
</div>
</div>
</div>
""")
chatbot = gr.Chatbot(height=620, show_label=False)
pdf_upload = gr.File(
label="Upload a K-bis extract (PDF)",
file_types=[".pdf"],
container=False
)
with gr.Row():
submit = gr.Button("Analyze", variant="primary", elem_classes="button-primary")
summarize = gr.Button("Summarize Core Parts", variant="secondary")
export = gr.Button("Export to PDF", variant="secondary")
# State to store the last report (full text)
state_report = gr.State("")
def analyze(pdf_file, history):
if pdf_file is None:
return history + [["User", "Please upload a K-bis PDF."]], ""
temp_extracted = tempfile.NamedTemporaryFile(mode="w+", suffix="_extracted.txt", delete=False,
encoding="utf-8").name
temp_analysis = tempfile.NamedTemporaryFile(mode='w', suffix="_analysis.txt", delete=False,
encoding="utf-8").name
try:
extract_pdf_text_with_easyocr(pdf_file.name, save_to_file=temp_extracted)
# Added for debugging: Print the extracted text to console
with open(temp_extracted, "r", encoding="utf-8") as f:
extracted_text = f.read()
print("=== Extracted Text from OCR ===")
print(extracted_text)
print("=== End of Extracted Text ===")
parse_full_kbis(temp_extracted, output_file=temp_analysis)
with open(temp_analysis, "r", encoding="utf-8") as f:
report = f.read()
# Display full report in collapsible accordion
full_report_md = f"""
<details>
<summary>Full Report (click to expand)</summary>
<pre>{report}</pre>
</summary>
</details>
"""
history.append([f"Analysis of {os.path.basename(pdf_file.name)}", full_report_md])
except Exception as e:
history.append(["User", f"Error: {str(e)}"])
report = ""
finally:
for path in [temp_extracted, temp_analysis]:
if os.path.exists(path):
os.unlink(path)
return history, report
def summarize_core(report, history):
if not report or "Error" in report:
history.append(["Summarize", "No valid report to summarize."])
return history
# Extract core parts from the report (rule-based, no LLM)
lines = report.split("\n")
core_keys = ["SIREN", "Dénomination", "Forme juridique", "Adresse", "Gérant(s)", "Associé(s)",
"Date de début d'activité"]
core_summary = "Core Parts Summary\n\n"
for line in lines:
for key in core_keys:
if line.startswith(key + ":"):
core_summary += line + "\n"
break
history.append(["Summarize Core Parts", core_summary])
return history
def export_pdf(report, history):
if not report or "Error" in report:
history.append(["Export", "No valid report to export."])
return history
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
pdf_path = os.path.join(EXPORT_DIR, f"kbis_report_{timestamp}.pdf")
html = f"""
<html>
<head><meta charset="utf-8"><title>K-bis Report</title></head>
<body style="font-family: Arial, sans-serif; padding: 40px; line-height: 1.6;">
<h1 style="text-align: center; color: #6d28d9;">K-bis Analysis</h1>
<pre style="white-space: pre-wrap; font-size: 14px;">{report}</pre>
<footer style="margin-top: 50px; text-align: center; color: #666; font-size: 12px;">
Generated by K-bis Analyzer — Jonathan Corke © 2025
</footer>
</body>
</html>
"""
try:
HTML(string=html).write_pdf(pdf_path)
msg = f"Export successful: {pdf_path}"
except Exception as e:
msg = f"Export error: {str(e)}"
history.append(["Export PDF", msg])
return history
submit.click(analyze, inputs=[pdf_upload, chatbot], outputs=[chatbot, state_report])
summarize.click(summarize_core, inputs=[state_report, chatbot], outputs=chatbot)
export.click(export_pdf, inputs=[state_report, chatbot], outputs=chatbot)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)