apptest3 / app.py
JayBene1's picture
Update app.py
70442a2 verified
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("""
<div class="header">
<h1>πŸ” Contact Search Tool</h1>
<p>Professional contact discovery powered by AI</p>
</div>
""")
# Info box
gr.HTML(f"""
<div class="info-box">
<h3>πŸ“‹ Instructions:</h3>
<ol>
<li>Enter the website URL you want to search for contacts</li>
<li>Click "Search Contacts" to get results</li>
<li>View formatted results and raw JSON response</li>
</ol>
<p><strong>API Endpoint:</strong> {API_ENDPOINT}</p>
</div>
""")
with gr.Row():
with gr.Column(scale=2):
url_input = gr.Textbox(
label="🌐 Website URL",
placeholder="example.com or https://example.com",
info="Enter the website URL to search for contacts",
lines=1
)
with gr.Row():
search_btn = gr.Button("πŸ” Search Contacts", variant="primary", scale=2)
demo_btn = gr.Button("πŸ“‹ Show Demo", variant="secondary", scale=1)
clear_btn = gr.Button("πŸ—‘οΈ Clear", variant="secondary", scale=1)
with gr.Row():
with gr.Column(scale=1):
results_output = gr.Markdown(
label="πŸ“Š Contact Results",
value="Enter a URL and click 'Search Contacts' to see results here.",
height=400
)
with gr.Column(scale=1):
json_output = gr.Code(
label="πŸ“ Raw JSON Response",
language="json",
value="",
height=400
)
# Event handlers
search_btn.click(
fn=search_contacts,
inputs=[url_input],
outputs=[results_output, json_output]
)
demo_btn.click(
fn=lambda: (create_sample_data(), '{"contacts": [{"name": "John Smith", "email": "john.smith@example.com", "title": "CEO"}]}'),
outputs=[results_output, json_output]
)
clear_btn.click(
fn=lambda: ("", ""),
outputs=[url_input, results_output]
)
# Footer
gr.HTML("""
<div class="footer">
<p>Β© 2025 Contact Search Tool - Professional contact discovery solution</p>
</div>
""")
# Launch the app
if __name__ == "__main__":
demo.launch(
share=True,
server_name="0.0.0.0",
server_port=7860,
show_error=True,
debug=True
)