import gradio as gr import requests import json from typing import List, Dict, Any import pandas as pd # Hardcoded API endpoint API_ENDPOINT = "https://huggingface.co/spaces/JayBene1/testapicontacts" # Professional color scheme inspired by corporate/real estate companies theme = gr.themes.Soft( primary_hue="blue", secondary_hue="slate", neutral_hue="slate", text_size="md", spacing_size="md", radius_size="md" ).set( body_background_fill="#f8fafc", body_background_fill_dark="#1e293b", block_background_fill="#ffffff", block_background_fill_dark="#334155", block_border_color="#e2e8f0", block_border_color_dark="#475569", input_background_fill="#ffffff", input_background_fill_dark="#334155", input_border_color="#cbd5e1", input_border_color_dark="#64748b", button_primary_background_fill="#1e40af", button_primary_background_fill_hover="#1d4ed8", button_primary_text_color="#ffffff", button_secondary_background_fill="#f1f5f9", button_secondary_background_fill_hover="#e2e8f0", button_secondary_text_color="#334155" ) def search_contacts(url: str) -> tuple[str, str]: """ Search for contacts associated with a given URL using the Hugging Face API. Args: url: The website URL to search for contacts Returns: Tuple of (formatted_results, raw_json) """ if not url.strip(): return "❌ Please enter a website URL", "" # Clean and validate URL url = url.strip() if not url.startswith(('http://', 'https://')): url = 'https://' + url try: # Prepare the API request headers = { 'Content-Type': 'application/json' } payload = { "inputs": url, "parameters": { "task": "contact_search", "url": url } } # Make the API request to the hardcoded endpoint response = requests.post( API_ENDPOINT, headers=headers, json=payload, timeout=30 ) if response.status_code == 200: try: result = response.json() # Format the results for display formatted_output = format_contact_results(result, url) raw_json = json.dumps(result, indent=2) return formatted_output, raw_json except json.JSONDecodeError: return f"❌ Error: Invalid JSON response from API", response.text else: return f"❌ API Error ({response.status_code}): {response.text}", "" except requests.exceptions.Timeout: return "❌ Request timeout. Please try again.", "" except requests.exceptions.ConnectionError: return "❌ Connection error. Please check your API endpoint.", "" except Exception as e: return f"❌ Error: {str(e)}", "" def format_contact_results(results: Dict[Any, Any], url: str) -> str: """ Format the API results into a readable format. Args: results: The JSON response from the API url: The searched URL Returns: Formatted string with contact information """ output = f"# 🔍 Contact Search Results for: {url}\n\n" # Handle different possible result structures if isinstance(results, dict): if 'contacts' in results: contacts = results['contacts'] elif 'results' in results: contacts = results['results'] elif 'data' in results: contacts = results['data'] else: contacts = results if isinstance(contacts, list) and len(contacts) > 0: output += f"**Found {len(contacts)} contact(s):**\n\n" for i, contact in enumerate(contacts, 1): output += f"## 👤 Contact {i}\n" # Handle different contact field names name = contact.get('name') or contact.get('full_name') or contact.get('contact_name') or "N/A" email = contact.get('email') or contact.get('email_address') or "N/A" title = contact.get('title') or contact.get('job_title') or contact.get('position') or "N/A" company = contact.get('company') or contact.get('organization') or "N/A" phone = contact.get('phone') or contact.get('phone_number') or "N/A" linkedin = contact.get('linkedin') or contact.get('linkedin_url') or "N/A" output += f"- **Name:** {name}\n" output += f"- **Email:** {email}\n" output += f"- **Title:** {title}\n" output += f"- **Company:** {company}\n" output += f"- **Phone:** {phone}\n" output += f"- **LinkedIn:** {linkedin}\n\n" # Add any additional fields additional_fields = {k: v for k, v in contact.items() if k not in ['name', 'full_name', 'contact_name', 'email', 'email_address', 'title', 'job_title', 'position', 'company', 'organization', 'phone', 'phone_number', 'linkedin', 'linkedin_url']} if additional_fields: output += "**Additional Information:**\n" for key, value in additional_fields.items(): output += f"- **{key.replace('_', ' ').title()}:** {value}\n" output += "\n" output += "---\n\n" else: output += "❌ No contacts found for this URL.\n\n" elif isinstance(results, list): if len(results) > 0: output += f"**Found {len(results)} contact(s):**\n\n" for i, contact in enumerate(results, 1): output += f"## 👤 Contact {i}\n" output += f"{contact}\n\n" else: output += "❌ No contacts found for this URL.\n\n" else: output += f"**Result:** {results}\n\n" output += f"*Search completed at: {pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')}*" return output def create_sample_data(): """Create sample data for demonstration""" return '''# 🔍 Contact Search Results for: example.com **Found 2 contact(s):** ## 👤 Contact 1 - **Name:** John Smith - **Email:** john.smith@example.com - **Title:** CEO - **Company:** Example Corp - **Phone:** (555) 123-4567 - **LinkedIn:** linkedin.com/in/johnsmith --- ## 👤 Contact 2 - **Name:** Jane Doe - **Email:** jane.doe@example.com - **Title:** VP of Sales - **Company:** Example Corp - **Phone:** (555) 123-4568 - **LinkedIn:** linkedin.com/in/janedoe --- *Search completed at: 2025-01-15 10:30:00*''' # Create the Gradio interface with gr.Blocks(theme=theme, title="Contact Search - Kwekel Companies", css=""" .gradio-container { max-width: 1200px !important; margin: 0 auto !important; } .header { background: linear-gradient(135deg, #1e40af 0%, #3b82f6 100%); color: white; padding: 2rem; border-radius: 0.5rem; margin-bottom: 2rem; text-align: center; } .header h1 { margin: 0; font-size: 2.5rem; font-weight: 700; margin-bottom: 0.5rem; } .header p { margin: 0; font-size: 1.2rem; opacity: 0.9; } .info-box { background: #f0f9ff; border: 1px solid #0ea5e9; border-radius: 0.5rem; padding: 1rem; margin: 1rem 0; } .footer { text-align: center; margin-top: 2rem; padding-top: 2rem; border-top: 1px solid #e2e8f0; color: #64748b; } """) as demo: # Header gr.HTML("""
Professional contact discovery powered by AI
API Endpoint: {API_ENDPOINT}