tunnel / gradio_app.py
theshresthshukla's picture
tool to download logos from internet
2c01a8f verified
"""
Gradio web interface for the Logo Downloader
"""
import os
import gradio as gr
import logging
from pathlib import Path
from typing import Optional
from services.logo_downloader import LogoDownloader
from services.appconfig import GEMINI_API_KEY, DEFAULT_LOGOS_PER_ENTITY, MAX_LOGOS_PER_ENTITY
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def process_text_request(text: str, api_key: Optional[str], num_logos: int = DEFAULT_LOGOS_PER_ENTITY):
"""
Process text and download logos through Gradio interface
Args:
text (str): Input text
api_key (str): Optional Gemini API key
num_logos (int): Number of logos per entity
Returns:
Tuple: (status_message, zip_file_path or None, detailed_results)
"""
try:
# Validate inputs
if not text or not text.strip():
return "❌ Please provide some text to analyze.", None, "No text provided."
if num_logos < 1 or num_logos > MAX_LOGOS_PER_ENTITY:
return f"❌ Number of logos must be between 1 and {MAX_LOGOS_PER_ENTITY}.", None, f"Invalid number: {num_logos}"
# Use provided API key or environment variable
final_api_key = api_key.strip() if api_key and api_key.strip() else GEMINI_API_KEY
# Initialize downloader
downloader = LogoDownloader(gemini_api_key=final_api_key)
# Process the text
results = downloader.process_text(text, num_logos)
# Format response based on results
if results['status'] == 'success' and results['stats']['total_downloads'] > 0:
status_msg = f"βœ… {downloader.get_stats_summary()}"
zip_path = results.get('zip_path')
# Create detailed results
detailed_results = _format_detailed_results(results)
return status_msg, zip_path, detailed_results
elif results['status'] == 'warning':
return f"⚠️ {results['message']}", None, results.get('message', 'No details available')
else:
return f"❌ Processing failed: {results['message']}", None, results.get('message', 'Unknown error')
except Exception as e:
logger.error(f"Error in process_text_request: {e}")
return f"❌ An error occurred: {str(e)}", None, f"Error details: {str(e)}"
def _format_detailed_results(results):
"""Format detailed results for display"""
if not results.get('results'):
return "No detailed results available."
details = []
details.append(f"πŸ“Š **Processing Summary:**")
details.append(f"- Total entities found: {results['stats']['total_entities']}")
details.append(f"- Total logos downloaded: {results['stats']['total_downloads']}")
details.append(f"- Successful entities: {results['stats']['successful_entities']}")
details.append(f"- Failed entities: {results['stats']['failed_entities']}")
details.append("")
details.append("πŸ“‹ **Entity Details:**")
for result in results['results']:
entity = result['entity']
count = result['downloaded_count']
if count > 0:
details.append(f"βœ… **{entity}**: {count} logos downloaded")
else:
error_msg = result.get('error', 'No logos found')
details.append(f"❌ **{entity}**: Failed ({error_msg})")
return "\n".join(details)
def create_interface():
"""Create and configure Gradio interface"""
# Custom CSS for better styling
css = """
.gradio-container {
max-width: 1200px !important;
margin: auto !important;
}
.main-header {
text-align: center;
margin-bottom: 2rem;
}
.status-success {
color: #10b981 !important;
}
.status-error {
color: #ef4444 !important;
}
.status-warning {
color: #f59e0b !important;
}
"""
with gr.Blocks(css=css, title="Logo Downloader", theme=gr.themes.Soft()) as interface:
# Header
gr.HTML("""
<div class="main-header">
<h1>🎨 Logo Downloader</h1>
<p>Extract entities from text and download their logos automatically</p>
</div>
""")
with gr.Row():
with gr.Column(scale=2):
# Input section
gr.Markdown("## πŸ“ Input")
text_input = gr.Textbox(
label="Text to analyze",
placeholder="Enter text containing company names, products, or brands (e.g., 'We use AWS, Docker, React, and Adobe Photoshop for our projects')",
lines=5,
max_lines=10
)
with gr.Row():
api_key_input = gr.Textbox(
label="Gemini API Key (optional)",
placeholder="Enter your Gemini API key for better entity extraction",
type="password",
value=""
)
num_logos_input = gr.Slider(
label="Logos per entity",
minimum=1,
maximum=MAX_LOGOS_PER_ENTITY,
value=DEFAULT_LOGOS_PER_ENTITY,
step=1
)
process_btn = gr.Button("πŸš€ Download Logos", variant="primary", size="lg")
# API key help
gr.Markdown("""
πŸ’‘ **Tip:** Get a free Gemini API key at [Google AI Studio](https://makersuite.google.com/app/apikey) for better entity extraction.
Without an API key, the tool will use basic pattern matching.
""")
with gr.Column(scale=1):
# Output section
gr.Markdown("## πŸ“Š Results")
status_output = gr.Textbox(
label="Status",
interactive=False,
lines=2
)
download_output = gr.File(
label="Download ZIP",
interactive=False
)
detailed_output = gr.Textbox(
label="Detailed Results",
interactive=False,
lines=10,
max_lines=15
)
# Examples section
gr.Markdown("## πŸ’‘ Examples")
examples = [
[
"Our tech stack includes React, Node.js, MongoDB, Docker, AWS, and we use Figma for design, along with GitHub for version control.",
"",
8
],
[
"The team uses Microsoft Office, Adobe Creative Suite, Slack for communication, Zoom for meetings, and Salesforce for CRM.",
"",
6
],
[
"Popular social media platforms like Instagram, TikTok, Twitter, LinkedIn, and YouTube are essential for digital marketing.",
"",
5
]
]
gr.Examples(
examples=examples,
inputs=[text_input, api_key_input, num_logos_input],
outputs=[status_output, download_output, detailed_output],
fn=process_text_request,
cache_examples=False
)
# Process button click event
process_btn.click(
fn=process_text_request,
inputs=[text_input, api_key_input, num_logos_input],
outputs=[status_output, download_output, detailed_output],
show_progress='minimal'
)
# Footer
gr.HTML("""
<div style="text-align: center; margin-top: 2rem; padding: 1rem; border-top: 1px solid #e5e7eb;">
<p>πŸ”§ Built with Gradio | πŸ€– Powered by Gemini AI</p>
<p><small>This tool respects rate limits and downloads publicly available logos.</small></p>
</div>
""")
return interface
def main():
"""Main function to launch the application"""
logger.info("Starting Logo Downloader application...")
# Check for API key
if not GEMINI_API_KEY:
logger.warning("No Gemini API key found in environment variables")
logger.info("The application will work with fallback entity extraction")
else:
logger.info("Gemini API key found")
# Create and launch interface
interface = create_interface()
# Launch configuration
launch_kwargs = {
"server_name": "0.0.0.0",
"server_port": int(os.environ.get("PORT", 7860)),
"share": False,
"show_error": True,
"max_threads": 4
}
# Launch the interface
interface.launch(**launch_kwargs)
if __name__ == "__main__":
main()