Spaces:
Sleeping
Sleeping
| """ | |
| 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) |