luisabwk commited on
Commit
0fb5e8c
·
verified ·
1 Parent(s): 81856ea

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -0
app.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Gradio app wrapping the official `commonforms` package to convert PDFs
2
+ into fillable forms using jbarrow's FFDNet-L object detector (CPU ONNX).
3
+
4
+ - Paper: <https://arxiv.org/abs/2509.16506>
5
+ - Model: <https://huggingface.co/jbarrow/FFDNet-L-cpu>
6
+ - Package: <https://pypi.org/project/commonforms/>
7
+
8
+ Detecta 3 classes de campos: text boxes, checkboxes (choice buttons) e signatures.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import tempfile
13
+ from pathlib import Path
14
+
15
+ import gradio as gr
16
+ from commonforms import prepare_form
17
+
18
+
19
+ def detect_fields(
20
+ pdf_path: str | None,
21
+ image_size: int,
22
+ use_signature_fields: bool,
23
+ keep_existing_fields: bool,
24
+ ) -> str:
25
+ if not pdf_path:
26
+ raise gr.Error("Envie um PDF.")
27
+
28
+ src = Path(pdf_path)
29
+ if not src.exists():
30
+ raise gr.Error(f"Arquivo não encontrado: {src}")
31
+
32
+ fd, out_str = tempfile.mkstemp(suffix="_fillable.pdf")
33
+ out = Path(out_str)
34
+
35
+ try:
36
+ prepare_form(
37
+ path_to_input_pdf=str(src),
38
+ path_to_output_pdf=str(out),
39
+ image_size=int(image_size),
40
+ use_signature_fields=bool(use_signature_fields),
41
+ keep_existing_fields=bool(keep_existing_fields),
42
+ )
43
+ except Exception as exc:
44
+ raise gr.Error(f"Falha ao processar PDF: {exc}") from exc
45
+
46
+ return str(out)
47
+
48
+
49
+ with gr.Blocks(title="CommonForms — Form Field Detector") as demo:
50
+ gr.Markdown(
51
+ "# CommonForms — Form Field Detector\n"
52
+ "Converte um PDF em formulário preenchível usando **FFDNet-L** "
53
+ "(`jbarrow/FFDNet-L-cpu`, Object Detection ONNX em CPU). "
54
+ "Detecta *text boxes*, *checkboxes* e *signature fields*.\n\n"
55
+ "Paper: [arxiv 2509.16506](<https://arxiv.org/abs/2509.16506>) · "
56
+ "Modelo: [jbarrow/FFDNet-L-cpu](<https://huggingface.co/jbarrow/FFDNet-L-cpu>)"
57
+ )
58
+ with gr.Row():
59
+ with gr.Column():
60
+ pdf_in = gr.File(
61
+ label="PDF de entrada",
62
+ file_types=[".pdf"],
63
+ type="filepath",
64
+ )
65
+ image_size = gr.Slider(
66
+ minimum=512,
67
+ maximum=2048,
68
+ value=1600,
69
+ step=32,
70
+ label="Image size (px)",
71
+ info="Tamanho usado na inferência. Maior = mais preciso, mais lento.",
72
+ )
73
+ use_sig = gr.Checkbox(
74
+ value=False,
75
+ label="Incluir signature fields",
76
+ info="Detecta áreas de assinatura além de text/checkbox.",
77
+ )
78
+ keep = gr.Checkbox(
79
+ value=False,
80
+ label="Manter campos já existentes",
81
+ info="Preserva widgets AcroForm que já estavam no PDF.",
82
+ )
83
+ btn = gr.Button("Detectar campos", variant="primary")
84
+ with gr.Column():
85
+ pdf_out = gr.File(label="PDF preenchível")
86
+
87
+ btn.click(
88
+ fn=detect_fields,
89
+ inputs=[pdf_in, image_size, use_sig, keep],
90
+ outputs=pdf_out,
91
+ api_name="detect",
92
+ )
93
+
94
+
95
+ if __name__ == "__main__":
96
+ demo.queue(max_size=4).launch()