| import spaces |
| import gradio as gr |
|
|
| from gdpr_logic import ( |
| INITIAL_STATUS, |
| QUICK_QUESTIONS, |
| ask_question as ask_question_backend, |
| clear_chat, |
| refresh_data, |
| ) |
|
|
| custom_css = """ |
| .gradio-container { |
| max-width: 1600px !important; |
| margin: auto !important; |
| padding: 30px !important; |
| background: #F7F3EF !important; |
| } |
| #app-header { |
| text-align: center; |
| margin-bottom: 26px; |
| } |
| #app-header h1 { |
| color: #0F3D3E !important; |
| font-size: 42px !important; |
| font-weight: 700 !important; |
| margin-bottom: 8px !important; |
| } |
| #app-header p { |
| color: #5F6666; |
| font-size: 17px; |
| } |
| #info-card, |
| #chat-card { |
| background: #FFFFFF; |
| border: 1px solid #DDD7CE; |
| border-radius: 18px; |
| padding: 20px; |
| } |
| #send-button { |
| background: #0F3D3E !important; |
| color: white !important; |
| border: none !important; |
| } |
| #send-button:hover { |
| background: #18595B !important; |
| } |
| #refresh-button, |
| #clear-button { |
| border: 1px solid #0F3D3E !important; |
| color: #0F3D3E !important; |
| } |
| .quick-question { |
| min-height: 52px !important; |
| white-space: normal !important; |
| text-align: left !important; |
| background: #FAF8F4 !important; |
| color: #0F3D3E !important; |
| border: 1px solid #D8D2C8 !important; |
| border-radius: 11px !important; |
| font-size: 13px !important; |
| } |
| .quick-question:hover { |
| background: #EFEAE2 !important; |
| border-color: #0F3D3E !important; |
| } |
| footer { |
| display: none !important; |
| } |
| """ |
|
|
|
|
| @spaces.GPU(duration=120) |
| def ask_question(question, history): |
| """ |
| Run GDPR model inference inside a Hugging Face ZeroGPU allocation. |
| """ |
| return ask_question_backend(question, history) |
|
|
|
|
| def make_quick_handler(prompt_text: str): |
| @spaces.GPU(duration=120) |
| def handler(history): |
| return ask_question_backend(prompt_text, history) |
|
|
| return handler |
|
|
|
|
| with gr.Blocks( |
| title="GDPR Compliance Assistant", |
| ) as demo: |
| gr.HTML( |
| """ |
| <div id="app-header"> |
| <h1>GDPR Compliance Assistant</h1> |
| <p> |
| Ask questions based on GDPR articles collected from GDPR.eu. |
| </p> |
| </div> |
| """ |
| ) |
|
|
| with gr.Row(): |
| with gr.Column(scale=1, elem_id="info-card"): |
| gr.Markdown( |
| """ |
| ### GDPR knowledge base |
| |
| The app reads the GDPR.eu table of contents, collects Articles 1–99, and uses the most relevant articles to answer each question. |
| |
| The content is cached after the first successful load. |
| """ |
| ) |
|
|
| status = gr.Markdown(INITIAL_STATUS) |
|
|
| refresh_button = gr.Button( |
| "Refresh GDPR website", |
| elem_id="refresh-button", |
| ) |
|
|
| gr.Markdown( |
| """ |
| ### Important |
| |
| This assistant provides general information based on the loaded GDPR text. It does not provide formal legal advice. |
| """ |
| ) |
|
|
| with gr.Column(scale=2, elem_id="chat-card"): |
| chatbot = gr.Chatbot( |
| label="GDPR Assistant", |
| height=500, |
| placeholder="Ask something about GDPR...", |
| ) |
|
|
| gr.Markdown("#### Quick questions") |
|
|
| quick_buttons = [] |
|
|
| with gr.Row(): |
| for prompt in QUICK_QUESTIONS[:3]: |
| button = gr.Button( |
| prompt, |
| elem_classes=["quick-question"], |
| ) |
| quick_buttons.append((button, prompt)) |
|
|
| with gr.Row(): |
| for prompt in QUICK_QUESTIONS[3:]: |
| button = gr.Button( |
| prompt, |
| elem_classes=["quick-question"], |
| ) |
| quick_buttons.append((button, prompt)) |
|
|
| with gr.Row(): |
| prompt_text = gr.Textbox( |
| lines=2, |
| placeholder="Ask a GDPR-related question...", |
| show_label=False, |
| scale=5, |
| ) |
|
|
| send_button = gr.Button( |
| "Send", |
| variant="primary", |
| elem_id="send-button", |
| scale=1, |
| ) |
|
|
| clear_button = gr.Button( |
| "Clear Chat", |
| elem_id="clear-button", |
| ) |
|
|
| send_button.click( |
| fn=ask_question, |
| inputs=[prompt_text, chatbot], |
| outputs=[chatbot, prompt_text], |
| ) |
|
|
| prompt_text.submit( |
| fn=ask_question, |
| inputs=[prompt_text, chatbot], |
| outputs=[chatbot, prompt_text], |
| ) |
|
|
| clear_button.click( |
| fn=clear_chat, |
| inputs=[], |
| outputs=[chatbot, prompt_text], |
| ) |
|
|
| refresh_button.click( |
| fn=refresh_data, |
| inputs=[], |
| outputs=[status], |
| ) |
|
|
| for button, prompt in quick_buttons: |
| button.click( |
| fn=make_quick_handler(prompt), |
| inputs=[chatbot], |
| outputs=[chatbot, prompt_text], |
| ) |
|
|
|
|
| if __name__ == "__main__": |
| demo.queue(default_concurrency_limit=1) |
| demo.launch(css=custom_css) |
|
|