| import gradio as gr |
| import threading |
| import time |
| from datetime import datetime |
| from report_generator import ( |
| generate_csv_report, |
| generate_xlsx_report, |
| generate_pdf_report, |
| generate_diagram_report, |
| ) |
| import cohere |
|
|
| |
| COHERE_API_KEY = "ffwtfyfLwqSOtw65psZardfqhUxMr1h7u5vzYotI" |
| co = cohere.Client(COHERE_API_KEY) |
|
|
| |
| cohere_examples = [ |
| {"text": "generate a report on unemployment", "label": "report"}, |
| {"text": "create a report on market trends", "label": "report"}, |
| {"text": "generate diagram of sales data", "label": "diagram"}, |
| {"text": "create a diagram of quarterly revenue", "label": "diagram"} |
| ] |
|
|
| def cohere_parse_command(command): |
| """Uses Cohere's classify endpoint to determine the intent of the command.""" |
| try: |
| response = co.classify( |
| model="large", |
| inputs=[command], |
| examples=cohere_examples |
| ) |
| prediction = response.classifications[0].prediction |
| return prediction |
| except Exception as e: |
| print("Cohere classification error, falling back to keyword search:", e) |
| lower = command.lower() |
| if "diagram" in lower: |
| return "diagram" |
| elif "report" in lower: |
| return "report" |
| else: |
| return "unknown" |
|
|
| |
| task_bucket = [] |
| generated_files = [] |
| bucket_lock = threading.Lock() |
|
|
| def process_single_task(task): |
| """Process one task with a countdown timer and update its details.""" |
| print(f"[{datetime.now()}] Processing task: {task['command']}") |
| |
| for remaining in range(5, 0, -1): |
| task["timer"] = remaining |
| time.sleep(1) |
| intent = cohere_parse_command(task["command"]) |
| cmd = task["command"].lower() |
| |
| if intent == "report": |
| if "csv" in cmd: |
| filename = generate_csv_report(subject=task["command"]) |
| task["result"] = f"CSV report generated for '{task['command']}'" |
| elif "xlsx" in cmd: |
| filename = generate_xlsx_report(subject=task["command"]) |
| task["result"] = f"XLSX report generated for '{task['command']}'" |
| else: |
| filename = generate_pdf_report(subject=task["command"]) |
| task["result"] = f"PDF report generated for '{task['command']}'" |
| elif intent == "diagram": |
| filename = generate_diagram_report() |
| task["result"] = f"Diagram generated for '{task['command']}'" |
| else: |
| filename = None |
| task["result"] = f"Unrecognized command: {task['command']}" |
| if filename: |
| task["file"] = filename |
| generated_files.append(filename) |
| task["completed_at"] = datetime.now().strftime("%H:%M:%S") |
| task["status"] = "Complete" |
| task["details"] = f"Task '{task['command']}' processed with result: {task['result']}" |
| print(f"[{datetime.now()}] Task completed: {task}") |
|
|
| def background_task_processor(): |
| """Continuously monitors the task bucket and spawns a new thread per task.""" |
| while True: |
| time.sleep(1) |
| task = None |
| with bucket_lock: |
| if task_bucket: |
| task = task_bucket.pop(0) |
| if task: |
| task["status"] = "In Progress" |
| threading.Thread(target=process_single_task, args=(task,), daemon=True).start() |
|
|
| def submit_task(command, current_tasks): |
| """Adds a new task when the user clicks Submit (command remains visible).""" |
| if command.strip() == "": |
| return current_tasks, generated_files, command |
| new_task = { |
| "command": command, |
| "submitted_at": datetime.now().strftime("%H:%M:%S"), |
| "timer": "", |
| "result": "", |
| "file": "", |
| "completed_at": "", |
| "status": "Pending", |
| "details": "" |
| } |
| with bucket_lock: |
| task_bucket.append(new_task) |
| current_tasks.append(new_task) |
| return current_tasks, generated_files, command |
|
|
| def build_tasks_html(tasks): |
| """Builds an HTML table showing task details.""" |
| html = """ |
| <style> |
| table {width: 100%; border-collapse: collapse; margin: 10px 0; font-family: Arial, sans-serif;} |
| th, td {border: 1px solid #ddd; padding: 8px; text-align: left; font-size: 14px;} |
| th {background-color: #f2f2f2;} |
| .Complete {background-color: #d4edda;} |
| .In\\ Progress {background-color: #fff3cd;} |
| .Pending {background-color: #f8d7da;} |
| </style> |
| <table> |
| <tr> |
| <th>Submitted At</th> |
| <th>Command</th> |
| <th>Status</th> |
| <th>Timer</th> |
| <th>Result</th> |
| <th>Completed At</th> |
| <th>Details</th> |
| <th>Done</th> |
| </tr> |
| """ |
| for task in tasks: |
| status = task.get("status", "Pending") |
| timer = task.get("timer", "") |
| result = task.get("result", "") |
| completed_at = task.get("completed_at", "") |
| details = task.get("details", "") |
| checkbox = "<input type='checkbox' disabled " + ("checked" if status == "Complete" else "") + ">" |
| html += ( |
| f"<tr class='{status}'>" |
| f"<td>{task.get('submitted_at','')}</td>" |
| f"<td>{task.get('command','')}</td>" |
| f"<td>{status}</td>" |
| f"<td>{timer}</td>" |
| f"<td>{result}</td>" |
| f"<td>{completed_at}</td>" |
| f"<td>{details}</td>" |
| f"<td>{checkbox}</td>" |
| f"</tr>" |
| ) |
| html += "</table>" |
| return html |
|
|
| def refresh_ui(tasks, files): |
| """Refreshes the UI by rebuilding the task list and updating the files state.""" |
| |
| files = generated_files[:] |
| tasks_html = build_tasks_html(tasks) |
| return tasks, files, tasks_html, files |
|
|
| def update_dropdown(files): |
| """Updates the dropdown choices for preview from the list of generated files.""" |
| return files |
|
|
| def preview_file(file_path): |
| """Returns HTML for previewing the file based on its type.""" |
| if not file_path: |
| return "No file selected." |
| if file_path.endswith(".png"): |
| return f'<img src="{file_path}" style="max-width:100%;">' |
| elif file_path.endswith(".pdf"): |
| return f'<embed src="{file_path}" type="application/pdf" width="100%" height="600px">' |
| elif file_path.endswith(".csv") or file_path.endswith(".xlsx"): |
| return f'<a href="{file_path}" target="_blank">Download and view file: {file_path}</a>' |
| else: |
| return f'<a href="{file_path}" target="_blank">Download file: {file_path}</a>' |
|
|
| def main(): |
| threading.Thread(target=background_task_processor, daemon=True).start() |
| |
| with gr.Blocks(css=""" |
| body {background-color: #121212; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #fdfdfd; margin: 0; padding: 0;} |
| .gradio-container {max-width: 900px; margin: auto; padding: 20px; background-color: #1e1e1e; border-radius: 8px; box-shadow: 0px 0px 15px rgba(0,0,0,0.5);} |
| .title {text-align: center; color: #fdfdfd; margin-bottom: 20px;} |
| .section-title {color: #fdfdfd; margin-top: 30px; border-bottom: 2px solid #fdfdfd; padding-bottom: 5px;} |
| """) as demo: |
| gr.Markdown("<h1 class='title'>Advanced Multi-Task Application</h1>") |
| gr.Markdown( |
| "Enter a task command below or click one of the sample commands. For example: <i>generate a report on unemployment in the United States in 2024</i>.<br>" |
| "Tasks run concurrently and once complete, files will appear in the <b>Completed Downloads</b> section.<br>" |
| "You can also preview a completed file in the <b>File Preview</b> section." |
| ) |
| |
| with gr.Row(): |
| with gr.Column(scale=8): |
| command_input = gr.Textbox(label="Task Command", placeholder="Type your command here...", lines=2) |
| with gr.Column(scale=2): |
| submit_btn = gr.Button("Submit", variant="primary") |
| |
| gr.Markdown("<h3 class='section-title'>Sample Commands</h3>") |
| with gr.Row(): |
| sample1 = gr.Button("Report on US Unemployment 2024") |
| sample2 = gr.Button("Diagram of Sales Data") |
| sample3 = gr.Button("CSV Report of User Activity") |
| |
| gr.Markdown("<h3 class='section-title'>Task List</h3>") |
| tasks_html_output = gr.HTML(label="Tasks Overview") |
| |
| gr.Markdown("<h3 class='section-title'>Completed Downloads</h3>") |
| file_output = gr.Files(label="Download Files", file_count="multiple") |
| |
| gr.Markdown("<h3 class='section-title'>File Preview</h3>") |
| with gr.Row(): |
| file_dropdown = gr.Dropdown(choices=[], label="Select File for Preview") |
| preview_btn = gr.Button("Preview File") |
| preview_output = gr.HTML(label="File Preview") |
| |
| with gr.Row(): |
| refresh_btn = gr.Button("Manual Refresh") |
| auto_refresh_toggle = gr.Checkbox(value=True, label="Auto Refresh Task List") |
| |
| tasks_state = gr.State([]) |
| files_state = gr.State([]) |
| |
| |
| submit_btn.click( |
| submit_task, |
| inputs=[command_input, tasks_state], |
| outputs=[tasks_state, files_state, command_input] |
| ).then( |
| refresh_ui, |
| inputs=[tasks_state, files_state], |
| outputs=[tasks_state, files_state, tasks_html_output, file_output] |
| ) |
| sample1.click(lambda: "generate a report on unemployment in the United States in 2024", None, command_input) |
| sample2.click(lambda: "generate diagram of sales data", None, command_input) |
| sample3.click(lambda: "generate csv report of user activity", None, command_input) |
| refresh_btn.click( |
| refresh_ui, |
| inputs=[tasks_state, files_state], |
| outputs=[tasks_state, files_state, tasks_html_output, file_output] |
| ) |
| |
| auto_refresh_btn = gr.Button("Auto Refresh", visible=False, elem_id="auto_refresh_btn") |
| auto_refresh_btn.click( |
| refresh_ui, |
| inputs=[tasks_state, files_state], |
| outputs=[tasks_state, files_state, tasks_html_output, file_output] |
| ) |
| gr.HTML(""" |
| <script> |
| setInterval(function(){ |
| if(document.getElementById('auto_refresh_toggle').checked){ |
| document.getElementById('auto_refresh_btn').click(); |
| } |
| }, 5000); |
| </script> |
| """) |
| auto_refresh_toggle.elem_id = "auto_refresh_toggle" |
| |
| |
| refresh_btn.click( |
| update_dropdown, |
| inputs=[files_state], |
| outputs=[file_dropdown] |
| ) |
| auto_refresh_btn.click( |
| update_dropdown, |
| inputs=[files_state], |
| outputs=[file_dropdown] |
| ) |
| preview_btn.click( |
| preview_file, |
| inputs=[file_dropdown], |
| outputs=[preview_output] |
| ) |
| |
| demo.launch(server_name="0.0.0.0", server_port=7860) |
|
|
| if __name__ == "__main__": |
| main() |
|
|