File size: 4,766 Bytes
1e5ecc5
 
1f1a99e
 
 
 
5d6a96a
 
 
 
 
 
1f1a99e
 
 
 
 
 
 
bf73927
 
1f1a99e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bf73927
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1f1a99e
 
 
 
 
 
29c8e57
1f1a99e
 
 
 
 
 
 
 
 
bf73927
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e10b362
1f1a99e
bf73927
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e10b362
1f1a99e
bf73927
1f1a99e
bf73927
 
 
 
1f1a99e
 
5d6a96a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import os

import gradio as gr
from core import RAG, parse_cas_input

rag = RAG()
auth_list = []
auth_env = os.getenv("AUTH_USERS", "")
for pair in auth_env.split(","):
    if ":" in pair:
        user, pwd = pair.split(":", 1)
        auth_list.append((user.strip(), pwd.strip()))
EXAMPLE_INPUTS = [
    "7664-39-3",
    "7664-39-3, 128-37-0",
    "50-00-0, 7664-93-9, 67-64-1",
]


def _run_pipeline(cas_numbers):
    result = rag.pipeline(cas_numbers)

    rows = []
    for r in result.results:
        rows.append([r.casNumber, r.chemicalName, r.status, r.reason])

    summary_parts = []
    for r in result.results:
        summary_parts.append(
            f"### {r.casNumber}{r.chemicalName}\n"
            f"**Yêu cầu pháp lý:** {r.status}\n\n"
            f"**Cơ sở:** {r.reason}\n"
        )
    summary_md = "\n---\n".join(summary_parts)
    return rows, summary_md


def analyse_text(raw_input: str):
    if not raw_input or not raw_input.strip():
        raise gr.Error("Vui lòng nhập ít nhất một mã CAS.")

    cas_numbers = parse_cas_input(raw_input)
    if not cas_numbers:
        raise gr.Error(
            f"Không tìm thấy mã CAS hợp lệ trong '{raw_input}'. "
            "Định dạng đúng: 7664-39-3"
        )
    return _run_pipeline(cas_numbers)


def analyse_image(image_path: str):
    if image_path is None:
        raise gr.Error("Vui lòng upload một ảnh chứa mã CAS.")

    cas_numbers = rag.extract_cas_from_image(image_path)
    if not cas_numbers:
        raise gr.Error("Không tìm thấy mã CAS nào trong ảnh. Vui lòng thử ảnh khác.")

    cas_display = ", ".join(cas_numbers)
    rows, summary_md = _run_pipeline(cas_numbers)
    return cas_display, rows, summary_md


with gr.Blocks(
    title="Chemical & Precursor Declaration Checker",
    theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
    css="""
        .main-header {text-align:center; margin-bottom:4px}
        .sub-header  {text-align:center; color:#555; margin-top:0}
        .result-table {height: 120px; overflow-y: auto}
    """,
) as demo:
    gr.Markdown(
        "<h1 class='main-header'>Chemical & Precursor Declaration Checker</h1>"
        "<p class='sub-header'>"
        "Tra cứu nghĩa vụ khai báo hóa chất & tiền chất theo quy định Việt Nam"
        "</p>"
    )

    with gr.Tabs():
        # ---- Tab 1: Nhập text ----
        with gr.TabItem("Nhập mã CAS"):
            with gr.Row():
                with gr.Column(scale=4):
                    cas_input = gr.Textbox(
                        label="Nhập mã CAS",
                        placeholder="VD: 7664-39-3, 128-37-0  (phân cách bằng dấu phẩy)",
                        lines=2,
                    )
                with gr.Column(scale=1, min_width=140):
                    text_btn = gr.Button("Tra cứu", variant="primary", size="lg")

            gr.Examples(examples=EXAMPLE_INPUTS, inputs=cas_input, label="Ví dụ")

            gr.Markdown("### Kết quả")
            text_table = gr.Dataframe(
                headers=["CAS", "Tên hóa chất", "Yêu cầu pháp lý", "Cơ sở pháp lý"],
                datatype=["str", "str", "str", "str"],
                interactive=False, wrap=True,
                elem_classes=["result-table"],
            )
            text_detail = gr.Markdown()

            text_btn.click(fn=analyse_text, inputs=cas_input, outputs=[text_table, text_detail])
            cas_input.submit(fn=analyse_text, inputs=cas_input, outputs=[text_table, text_detail])

        # ---- Tab 2: Upload ảnh ----
        with gr.TabItem("Upload ảnh"):
            with gr.Row():
                with gr.Column(scale=4):
                    img_input = gr.Image(
                        label="Upload ảnh chứa danh sách mã CAS",
                        type="filepath",
                    )
                with gr.Column(scale=1, min_width=140):
                    img_btn = gr.Button("Trích xuất & Tra cứu", variant="primary", size="lg")

            extracted_cas = gr.Textbox(label="Mã CAS trích xuất được", interactive=False)

            gr.Markdown("### Kết quả")
            img_table = gr.Dataframe(
                headers=["CAS", "Tên hóa chất", "Yêu cầu pháp lý", "Cơ sở pháp lý"],
                datatype=["str", "str", "str", "str"],
                interactive=False, wrap=True,
                elem_classes=["result-table"],
            )
            img_detail = gr.Markdown()

            img_btn.click(
                fn=analyse_image, inputs=img_input,
                outputs=[extracted_cas, img_table, img_detail],
            )

if __name__ == "__main__":
    demo.launch(auth=auth_list)