Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import os
|
| 3 |
+
import tempfile
|
| 4 |
+
import logging
|
| 5 |
+
import json
|
| 6 |
+
|
| 7 |
+
# Import your dispatcher class from the local summarizer_tool.py file
|
| 8 |
+
from summarizer_tool import AllInOneDispatcher
|
| 9 |
+
|
| 10 |
+
# Configure logging for the Gradio app
|
| 11 |
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
| 12 |
+
|
| 13 |
+
# Initialize the dispatcher globally.
|
| 14 |
+
# This ensures models are loaded only once when the Gradio app starts up.
|
| 15 |
+
# This can take time, especially on CPU.
|
| 16 |
+
try:
|
| 17 |
+
dispatcher = AllInOneDispatcher()
|
| 18 |
+
logging.info("AllInOneDispatcher initialized successfully for Gradio app.")
|
| 19 |
+
except Exception as e:
|
| 20 |
+
logging.error(f"Failed to initialize AllInOneDispatcher: {e}")
|
| 21 |
+
# If dispatcher fails to initialize, the app might not work.
|
| 22 |
+
# Raise a runtime error to make the Space fail gracefully with a clear message.
|
| 23 |
+
raise RuntimeError(f"Failed to initialize AI models. Check logs for details: {e}") from e
|
| 24 |
+
|
| 25 |
+
# --- Gradio Interface Functions ---
|
| 26 |
+
|
| 27 |
+
# Function to handle Text Processing
|
| 28 |
+
def process_text_task(text_input: str, task_name: str, max_summary_len: int, min_summary_len: int, max_gen_tokens: int, num_gen_sequences: int, tts_lang: str):
|
| 29 |
+
"""Handles various text-based AI tasks."""
|
| 30 |
+
if not text_input.strip():
|
| 31 |
+
return "Please enter some text.", None # Return None for audio output
|
| 32 |
+
|
| 33 |
+
kwargs = {}
|
| 34 |
+
if task_name == "summarization":
|
| 35 |
+
kwargs["max_length"] = max_summary_len
|
| 36 |
+
kwargs["min_length"] = min_summary_len
|
| 37 |
+
elif task_name == "text-generation":
|
| 38 |
+
kwargs["max_new_tokens"] = max_gen_tokens
|
| 39 |
+
kwargs["num_return_sequences"] = num_gen_sequences
|
| 40 |
+
elif task_name == "tts":
|
| 41 |
+
kwargs["lang"] = tts_lang
|
| 42 |
+
|
| 43 |
+
try:
|
| 44 |
+
logging.info(f"Processing text with task: {task_name}")
|
| 45 |
+
result = dispatcher.process(text_input, task=task_name, **kwargs)
|
| 46 |
+
|
| 47 |
+
if task_name == "tts":
|
| 48 |
+
# For TTS, dispatcher.process returns a file path
|
| 49 |
+
if os.path.exists(result):
|
| 50 |
+
return "Speech generated successfully!", result # Return text message and audio file path
|
| 51 |
+
else:
|
| 52 |
+
return "TTS failed to generate audio.", None
|
| 53 |
+
else:
|
| 54 |
+
# For other text tasks, return the JSON representation of the result
|
| 55 |
+
return json.dumps(result, indent=2), None
|
| 56 |
+
except Exception as e:
|
| 57 |
+
logging.error(f"Error processing text: {e}")
|
| 58 |
+
return f"An error occurred: {e}", None
|
| 59 |
+
|
| 60 |
+
# Function to handle File Processing
|
| 61 |
+
def process_file_task(file_obj, task_name: str):
|
| 62 |
+
"""Handles image, audio, PDF, and limited video processing."""
|
| 63 |
+
if file_obj is None:
|
| 64 |
+
return "Please upload a file."
|
| 65 |
+
|
| 66 |
+
# Gradio passes the file path directly for type="filepath"
|
| 67 |
+
file_path = file_obj
|
| 68 |
+
|
| 69 |
+
try:
|
| 70 |
+
logging.info(f"Processing file '{file_path}' with task: {task_name}")
|
| 71 |
+
result = dispatcher.process(file_path, task=task_name)
|
| 72 |
+
|
| 73 |
+
if task_name == "automatic-speech-recognition":
|
| 74 |
+
return result.get('text', 'No transcription found.')
|
| 75 |
+
elif task_name == "video":
|
| 76 |
+
# Video analysis returns a dict with image and audio results
|
| 77 |
+
return f"Video Analysis Result:\nImage Analysis: {json.dumps(result.get('image_analysis'), indent=2)}\nAudio Analysis: {json.dumps(result.get('audio_analysis'), indent=2)}"
|
| 78 |
+
else:
|
| 79 |
+
return json.dumps(result, indent=2) # Use json.dumps for structured output
|
| 80 |
+
|
| 81 |
+
except NotImplementedError as e:
|
| 82 |
+
logging.error(f"Task not implemented: {e}")
|
| 83 |
+
return f"Task not fully implemented: {e}. Video processing is complex and requires system-level ffmpeg."
|
| 84 |
+
except ValueError as e:
|
| 85 |
+
logging.error(f"Value error processing file: {e}")
|
| 86 |
+
return f"Error processing file: {e}. Ensure the file type matches the selected task."
|
| 87 |
+
except Exception as e:
|
| 88 |
+
logging.error(f"An unexpected error occurred during file processing: {e}")
|
| 89 |
+
return f"An unexpected error occurred: {e}"
|
| 90 |
+
|
| 91 |
+
# NEW: Function to handle Dataset Processing
|
| 92 |
+
def process_dataset_task(dataset_name: str, subset_name: str, split: str, column_to_process: str, task: str, num_samples: int):
|
| 93 |
+
"""
|
| 94 |
+
Processes a specified column from a Hugging Face dataset using the dispatcher.
|
| 95 |
+
"""
|
| 96 |
+
if not dataset_name.strip() or not column_to_process.strip():
|
| 97 |
+
return "Please provide a Dataset Name and Column to Process."
|
| 98 |
+
|
| 99 |
+
# Define allowed tasks for dataset processing (based on what your dispatcher can handle)
|
| 100 |
+
allowed_dataset_tasks = [
|
| 101 |
+
"sentiment-analysis", "summarization", "text-generation", "image-classification",
|
| 102 |
+
"object-detection", "automatic-speech-recognition", "translation_en_to_fr"
|
| 103 |
+
# "pdf" and "video" are file-specific, not direct dataset column tasks
|
| 104 |
+
]
|
| 105 |
+
if task not in allowed_dataset_tasks:
|
| 106 |
+
return f"Selected task '{task}' is not supported for dataset processing. Choose from: {', '.join(allowed_dataset_tasks)}"
|
| 107 |
+
|
| 108 |
+
try:
|
| 109 |
+
logging.info(f"Starting dataset processing for {dataset_name}/{subset_name} on column '{column_to_process}' with task '{task}'.")
|
| 110 |
+
results = dispatcher.process_dataset_from_hub(
|
| 111 |
+
dataset_name=dataset_name,
|
| 112 |
+
subset_name=subset_name,
|
| 113 |
+
split=split,
|
| 114 |
+
column_to_process=column_to_process,
|
| 115 |
+
task=task,
|
| 116 |
+
num_samples=num_samples
|
| 117 |
+
)
|
| 118 |
+
return json.dumps(results, indent=2) # Return results as pretty-printed JSON
|
| 119 |
+
except Exception as e:
|
| 120 |
+
logging.error(f"Error during dataset processing: {e}")
|
| 121 |
+
return f"An error occurred during dataset processing: {e}"
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
# --- Gradio Interface Definition ---
|
| 125 |
+
|
| 126 |
+
# Text Processing Tab
|
| 127 |
+
text_tab_inputs = [
|
| 128 |
+
gr.Textbox(lines=8, label="Enter Text", placeholder="Type your text here for summarization, sentiment analysis, etc."),
|
| 129 |
+
gr.Dropdown(
|
| 130 |
+
["sentiment-analysis", "summarization", "text-generation", "tts", "translation_en_to_fr"],
|
| 131 |
+
label="Select Text Task",
|
| 132 |
+
value="sentiment-analysis"
|
| 133 |
+
),
|
| 134 |
+
gr.Slider(minimum=10, maximum=200, value=50, step=1, label="Max Summary Length (for Summarization)"),
|
| 135 |
+
gr.Slider(minimum=5, maximum=100, value=10, step=1, label="Min Summary Length (for Summarization)"),
|
| 136 |
+
gr.Slider(minimum=10, maximum=200, value=50, step=1, label="Max Generated Tokens (for Text Generation)"),
|
| 137 |
+
gr.Slider(minimum=1, maximum=3, value=1, step=1, label="Number of Sequences (for Text Generation)"),
|
| 138 |
+
gr.Dropdown(["en", "fr", "es"], label="TTS Language", value="en")
|
| 139 |
+
]
|
| 140 |
+
text_tab_outputs = [
|
| 141 |
+
gr.Textbox(label="Analysis Result / Generated Text"),
|
| 142 |
+
gr.Audio(label="Generated Speech (for TTS)", type="filepath")
|
| 143 |
+
]
|
| 144 |
+
text_interface = gr.Interface(
|
| 145 |
+
fn=process_text_task,
|
| 146 |
+
inputs=text_tab_inputs,
|
| 147 |
+
outputs=text_tab_outputs,
|
| 148 |
+
title="๐ Text Processing",
|
| 149 |
+
description="Perform various NLP tasks like sentiment analysis, summarization, text generation, and text-to-speech."
|
| 150 |
+
)
|
| 151 |
+
|
| 152 |
+
# File Processing Tab
|
| 153 |
+
file_tab_inputs = [
|
| 154 |
+
gr.File(label="Upload File", type="filepath", file_types=[".pdf", ".mp3", ".wav", ".jpg", ".jpeg", ".png", ".mov", ".mp4", ".avi", ".mkv"]),
|
| 155 |
+
gr.Dropdown(
|
| 156 |
+
["image-classification", "object-detection", "automatic-speech-recognition", "pdf", "video"],
|
| 157 |
+
label="Select File Task",
|
| 158 |
+
value="image-classification"
|
| 159 |
+
)
|
| 160 |
+
]
|
| 161 |
+
file_tab_outputs = gr.Textbox(label="File Processing Result")
|
| 162 |
+
file_interface = gr.Interface(
|
| 163 |
+
fn=process_file_task,
|
| 164 |
+
inputs=file_tab_inputs,
|
| 165 |
+
outputs=file_tab_outputs,
|
| 166 |
+
title="๐ File Processing",
|
| 167 |
+
description="Upload an image, audio, PDF, or video file for AI analysis."
|
| 168 |
+
)
|
| 169 |
+
|
| 170 |
+
# Dataset Processing Tab
|
| 171 |
+
dataset_tab_inputs = [
|
| 172 |
+
gr.Textbox(label="Hugging Face Dataset Name", placeholder="e.g., 'glue', 'mnist', 'common_voice'"),
|
| 173 |
+
gr.Textbox(label="Dataset Subset (Optional)", placeholder="e.g., 'sst2' for 'glue', 'en' for 'common_voice'"),
|
| 174 |
+
gr.Dropdown(["train", "validation", "test"], label="Dataset Split", value="train"),
|
| 175 |
+
gr.Textbox(label="Column to Process", placeholder="e.g., 'sentence', 'image', 'audio'"),
|
| 176 |
+
gr.Dropdown(
|
| 177 |
+
["sentiment-analysis", "summarization", "text-generation", "image-classification",
|
| 178 |
+
"object-detection", "automatic-speech-recognition", "translation_en_to_fr"],
|
| 179 |
+
label="AI Task for Dataset Column",
|
| 180 |
+
value="sentiment-analysis"
|
| 181 |
+
),
|
| 182 |
+
gr.Slider(minimum=1, maximum=20, value=5, step=1, label="Number of Samples to Process (max 20 for demo)"),
|
| 183 |
+
]
|
| 184 |
+
dataset_tab_outputs = gr.Textbox(label="Dataset Processing Results (JSON)")
|
| 185 |
+
dataset_interface = gr.Interface(
|
| 186 |
+
fn=process_dataset_task,
|
| 187 |
+
inputs=dataset_tab_inputs,
|
| 188 |
+
outputs=dataset_tab_outputs,
|
| 189 |
+
title="๐ Dataset Processing",
|
| 190 |
+
description="Load a dataset from Hugging Face Hub and apply an AI task to a specified column (processes a limited number of samples)."
|
| 191 |
+
)
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
# Combine all interfaces into a Tabbed Interface
|
| 195 |
+
demo = gr.TabbedInterface(
|
| 196 |
+
[text_interface, file_interface, dataset_interface], # Include all three interfaces
|
| 197 |
+
["Text Analyzer", "File Analyzer", "Dataset Analyzer"] # Tab titles
|
| 198 |
+
)
|
| 199 |
+
|
| 200 |
+
# --- Launch the Gradio App ---
|
| 201 |
+
if __name__ == "__main__":
|
| 202 |
+
# For local testing, use demo.launch()
|
| 203 |
+
# For Hugging Face Spaces, ensure all dependencies are in requirements.txt
|
| 204 |
+
demo.launch(share=True) # share=True creates a public link for easy sharing (temporary)
|