Spaces:
No application file
No application file
| """ | |
| Hugging Face Spaces Entry Point for ResearchOS | |
| This serves as the main entry point when using Gradio SDK fallback, | |
| or as a health-check wrapper when using Docker SDK. | |
| """ | |
| import gradio as gr | |
| import os | |
| import subprocess | |
| import threading | |
| import time | |
| # Start all backend services in background thread | |
| def start_services(): | |
| print("[HF Spaces] Starting ResearchOS services...") | |
| # Set SQLite fallback for HF Spaces | |
| os.environ.setdefault('DATABASE_URL', 'sqlite:///app/researchos.db') | |
| os.environ.setdefault('JWT_SECRET', os.getenv('JWT_SECRET', 'hf-spaces-secret')) | |
| services = [ | |
| ("auth", "python services/auth-service/src/main.py"), | |
| ("project", "python services/project-service/src/main.py"), | |
| ("manuscript", "python services/manuscript-service/src/main.py"), | |
| ("analysis", "python services/analysis-service/src/main.py"), | |
| ("agent", "python services/agent-service/src/main.py"), | |
| ("verification", "python services/verification-service/src/main.py"), | |
| ] | |
| for name, cmd in services: | |
| try: | |
| subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
| print(f"[HF Spaces] Started {name} service") | |
| time.sleep(1) | |
| except Exception as e: | |
| print(f"[HF Spaces] Failed to start {name}: {e}") | |
| # Start API Gateway | |
| time.sleep(2) | |
| try: | |
| subprocess.Popen("python services/api-gateway/src/main.py", shell=True) | |
| print("[HF Spaces] Started API Gateway") | |
| except Exception as e: | |
| print(f"[HF Spaces] Failed to start API Gateway: {e}") | |
| # Start Next.js frontend | |
| time.sleep(2) | |
| try: | |
| subprocess.Popen("cd apps/web && PORT=7860 node server.js", shell=True) | |
| print("[HF Spaces] Started Web Frontend on port 7860") | |
| except Exception as e: | |
| print(f"[HF Spaces] Failed to start frontend: {e}") | |
| # Start services in background | |
| threading.Thread(target=start_services, daemon=True).start() | |
| # Gradio interface as fallback/wrapper | |
| def health_check(): | |
| import urllib.request | |
| try: | |
| req = urllib.request.Request('http://localhost:8000/health', method='GET') | |
| with urllib.request.urlopen(req, timeout=5) as resp: | |
| return resp.read().decode() | |
| except Exception as e: | |
| return f"Services starting... ({str(e)})" | |
| with gr.Blocks(title="ResearchOS") as demo: | |
| gr.Markdown("# ResearchOS - AI Research Platform") | |
| gr.Markdown("The full Next.js application is running in the background.") | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown("### System Status") | |
| status_btn = gr.Button("Check Health") | |
| status_output = gr.Textbox(label="Status", value="Starting...") | |
| status_btn.click(health_check, outputs=status_output) | |
| with gr.Column(): | |
| gr.Markdown("### Quick Links") | |
| gr.Markdown("- [Open Full App](/)") | |
| gr.Markdown("- API Gateway: `http://localhost:8000`") | |
| gr.Markdown("---") | |
| gr.Markdown("If the full app doesn't load, wait 30 seconds for services to boot, then refresh.") | |
| # Launch Gradio (this is required for HF Spaces Gradio SDK) | |
| # But if using Docker SDK, this file is ignored and start.sh is used instead | |
| demo.launch(server_name="0.0.0.0", server_port=7860, share=False) | |