luisabwk commited on
Commit
8a82008
·
verified ·
1 Parent(s): 97214f8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -0
app.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 inspect
13
+ import tempfile
14
+ from pathlib import Path
15
+
16
+ import gradio as gr
17
+ from commonforms import prepare_form
18
+
19
+ _PARAMS = inspect.signature(prepare_form).parameters
20
+ print(f"[commonforms] prepare_form signature: {list(_PARAMS.keys())}")
21
+
22
+
23
+ def detect_fields(
24
+ pdf_path: str | None,
25
+ image_size: int,
26
+ use_signature_fields: bool,
27
+ keep_existing_fields: bool,
28
+ ) -> str:
29
+ if not pdf_path:
30
+ raise gr.Error("Envie um PDF.")
31
+
32
+ src = Path(pdf_path)
33
+ if not src.exists():
34
+ raise gr.Error(f"Arquivo não encontrado: {src}")
35
+
36
+ _, out_str = tempfile.mkstemp(suffix="_fillable.pdf")
37
+ out = Path(out_str)
38
+
39
+ optional = {
40
+ "image_size": int(image_size),
41
+ "use_signature_fields": bool(use_signature_fields),
42
+ "keep_existing_fields": bool(keep_existing_fields),
43
+ "device": "cpu",
44
+ }
45
+ accepted = {k: v for k, v in optional.items() if k in _PARAMS}
46
+
47
+ try:
48
+ # input/output passados posicionalmente — robusto ao nome real do param
49
+ prepare_form(str(src), str(out), **accepted)
50
+ except Exception as exc:
51
+ raise gr.Error(f"Falha ao processar PDF: {exc}") from exc
52
+
53
+ return str(out)
54
+
55
+
56
+ with gr.Blocks(title="CommonForms — Form Field Detector") as demo:
57
+ gr.Markdown(
58
+ "# CommonForms — Form Field Detector\n"
59
+ "Converte um PDF em formulário preenchível usando **FFDNet-L** "
60
+ "(`jbarrow/FFDNet-L-cpu`, Object Detection ONNX em CPU). "
61
+ "Detecta *text boxes*, *checkboxes* e *signature fields*.\n\n"
62
+ "Paper: [arxiv 2509.16506](<https://arxiv.org/abs/2509.16506>) · "
63
+ "Modelo: [jbarrow/FFDNet-L-cpu](<https://huggingface.co/jbarrow/FFDNet-L-cpu>)"
64
+ )
65
+ with gr.Row():
66
+ with gr.Column():
67
+ pdf_in = gr.File(
68
+ label="PDF de entrada",
69
+ file_types=[".pdf"],
70
+ type="filepath",
71
+ )
72
+ image_size = gr.Slider(
73
+ minimum=512,
74
+ maximum=2048,
75
+ value=1600,
76
+ step=32,
77
+ label="Image size (px)",
78
+ info="Tamanho usado na inferência. Maior = mais preciso, mais lento.",
79
+ )
80
+ use_sig = gr.Checkbox(
81
+ value=False,
82
+ label="Incluir signature fields",
83
+ info="Detecta áreas de assinatura além de text/checkbox.",
84
+ )
85
+ keep = gr.Checkbox(
86
+ value=False,
87
+ label="Manter campos já existentes",
88
+ info="Preserva widgets AcroForm que já estavam no PDF.",
89
+ )
90
+ btn = gr.Button("Detectar campos", variant="primary")
91
+ with gr.Column():
92
+ pdf_out = gr.File(label="PDF preenchível")
93
+
94
+ btn.click(
95
+ fn=detect_fields,
96
+ inputs=[pdf_in, image_size, use_sig, keep],
97
+ outputs=pdf_out,
98
+ api_name="detect",
99
+ )
100
+
101
+
102
+ if __name__ == "__main__":
103
+ demo.queue(max_size=4).launch()