siham47's picture
create app.py
2810acd verified
"""
Gradio UI wrapper for the Academic Recommendation API
"""
import gradio as gr
import requests
import json
import subprocess
import time
import threading
# Start FastAPI server in background
def start_fastapi():
subprocess.Popen([
"uvicorn",
"api_server:app",
"--host", "0.0.0.0",
"--port", "8000"
])
# Start server in background thread
threading.Thread(target=start_fastapi, daemon=True).start()
time.sleep(10) # Wait for API to start
API_URL = "http://localhost:8000"
def get_recommendations(query, top_k=10):
"""Get recommendations from the API."""
try:
response = requests.post(
f"{API_URL}/recommend",
json={"query": query, "top_k": int(top_k)},
timeout=30
)
if response.status_code == 200:
data = response.json()
# Format output nicely
output = f"**Query:** {data['query']}\n\n"
output += f"**Found {data['total_results']} papers** (in {data['execution_time_ms']:.2f}ms)\n\n"
output += "---\n\n"
for paper in data['recommendations']:
output += f"### {paper['rank']}. {paper['title']}\n\n"
output += f"**Authors:** {', '.join(paper['metadata']['authors'][:3])}\n\n"
output += f"**Year:** {paper['metadata']['published'][:4]} | "
output += f"**Citations:** {paper['metadata']['citationCount']} | "
output += f"**Category:** {paper['metadata']['primary_category']}\n\n"
output += f"**Scores:** Similarity: {paper['scores']['similarity']:.3f}, "
output += f"Impact: {paper['scores']['impact_normalized']:.3f}, "
output += f"Recency: {paper['scores']['recency']:.3f}\n\n"
output += f"**Abstract:** {paper['abstract'][:300]}...\n\n"
output += f"[View on arXiv]({paper['metadata']['url']})\n\n"
output += "---\n\n"
return output
else:
return f"❌ Error: {response.status_code} - {response.text}"
except Exception as e:
return f"❌ Error: {str(e)}"
def check_health():
"""Check API health."""
try:
response = requests.get(f"{API_URL}/health", timeout=5)
if response.status_code == 200:
data = response.json()
return f"βœ… **Status:** {data['status']}\n**Device:** {data['device']}\n**Corpus loaded:** {data['corpus_loaded']} items"
else:
return f"❌ API returned status {response.status_code}"
except Exception as e:
return f"❌ API not responding: {str(e)}"
# Create Gradio interface
with gr.Blocks(title="Academic Paper Recommender") as demo:
gr.Markdown(
"""
# πŸ“š Academic Paper Recommendation System
LLM-powered recommendation system using SPECTER2 embeddings for semantic search.
**Features:**
- Semantic similarity matching using SPECTER2
- Multi-signal ranking (relevance + citations + recency)
- 6,436 physics papers from arXiv
"""
)
with gr.Tab("Search Papers"):
with gr.Row():
query_input = gr.Textbox(
label="Search Query",
placeholder="e.g., quantum entanglement, machine learning, gravitational waves",
lines=2
)
top_k_input = gr.Slider(
minimum=5,
maximum=20,
value=10,
step=1,
label="Number of Results"
)
search_button = gr.Button("πŸ” Search", variant="primary")
output = gr.Markdown(label="Results")
search_button.click(
fn=get_recommendations,
inputs=[query_input, top_k_input],
outputs=output
)
# Examples
gr.Examples(
examples=[
["quantum entanglement", 10],
["machine learning neural networks", 10],
["gravitational wave detection", 10],
["topological insulators", 5],
["quantum computing error correction", 10]
],
inputs=[query_input, top_k_input]
)
with gr.Tab("API Health"):
health_button = gr.Button("Check API Status")
health_output = gr.Markdown()
health_button.click(
fn=check_health,
outputs=health_output
)
# Launch
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)