PYAE1994 commited on
Commit
97250c4
·
verified ·
1 Parent(s): 47c142f

Update server with mock fallback and WebSocket proxy

Browse files
Files changed (1) hide show
  1. server.py +57 -10
server.py CHANGED
@@ -1,10 +1,10 @@
1
- """Simple proxy server to OpenHands Cloud API"""
2
  import os
3
  from fastapi import FastAPI, HTTPException
4
  from fastapi.middleware.cors import CORSMiddleware
5
  import httpx
6
 
7
- app = FastAPI(title="OpenHands Backend Proxy", version="1.0.0")
8
 
9
  app.add_middleware(
10
  CORSMiddleware,
@@ -17,22 +17,37 @@ app.add_middleware(
17
  OPENHANDS_API_KEY = os.getenv("OPENHANDS_API_KEY", "")
18
  OPENHANDS_BASE_URL = os.getenv("OPENHANDS_BASE_URL", "https://app.all-hands.dev")
19
 
 
 
 
20
  @app.get("/health")
21
  async def health():
22
- return {"status": "ok", "backend": "proxy", "version": "1.0.0"}
23
 
24
  @app.get("/ready")
25
  async def ready():
26
- return {"status": "ready", "service": "openhands-proxy"}
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  @app.get("/api/conversations")
29
  async def list_conversations():
30
  if not OPENHANDS_API_KEY:
31
- raise HTTPException(status_code=503, detail="OPENHANDS_API_KEY not configured")
32
- async with httpx.AsyncClient() as client:
 
33
  resp = await client.get(
34
  f"{OPENHANDS_BASE_URL}/api/conversations",
35
- headers={"Authorization": f"Bearer {OPENHANDS_API_KEY}"}
36
  )
37
  resp.raise_for_status()
38
  return resp.json()
@@ -40,12 +55,44 @@ async def list_conversations():
40
  @app.post("/api/conversations")
41
  async def create_conversation(data: dict):
42
  if not OPENHANDS_API_KEY:
43
- raise HTTPException(status_code=503, detail="OPENHANDS_API_KEY not configured")
44
- async with httpx.AsyncClient() as client:
 
 
45
  resp = await client.post(
46
  f"{OPENHANDS_BASE_URL}/api/conversations",
47
- headers={"Authorization": f"Bearer {OPENHANDS_API_KEY}"},
48
  json=data
49
  )
50
  resp.raise_for_status()
51
  return resp.json()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Proxy server to OpenHands Cloud API"""
2
  import os
3
  from fastapi import FastAPI, HTTPException
4
  from fastapi.middleware.cors import CORSMiddleware
5
  import httpx
6
 
7
+ app = FastAPI(title="OpenHands Backend", version="1.0.0")
8
 
9
  app.add_middleware(
10
  CORSMiddleware,
 
17
  OPENHANDS_API_KEY = os.getenv("OPENHANDS_API_KEY", "")
18
  OPENHANDS_BASE_URL = os.getenv("OPENHANDS_BASE_URL", "https://app.all-hands.dev")
19
 
20
+ def get_headers():
21
+ return {"Authorization": f"Bearer {OPENHANDS_API_KEY}", "Content-Type": "application/json"}
22
+
23
  @app.get("/health")
24
  async def health():
25
+ return {"status": "ok", "backend": "cloud-proxy", "version": "1.0.0"}
26
 
27
  @app.get("/ready")
28
  async def ready():
29
+ return {"status": "ready", "service": "openhands-cloud-proxy", "api_key_configured": bool(OPENHANDS_API_KEY)}
30
+
31
+ @app.get("/server_info")
32
+ async def server_info():
33
+ return {
34
+ "version": "1.0.0",
35
+ "llm_proxy": os.getenv("LLM_PROXY_URL", "https://llm-proxy.app.all-hands.dev"),
36
+ "e2b_enabled": bool(os.getenv("E2B_API_KEY")),
37
+ "redis_enabled": False,
38
+ "supabase_enabled": False,
39
+ "openhands_cloud": True,
40
+ }
41
 
42
  @app.get("/api/conversations")
43
  async def list_conversations():
44
  if not OPENHANDS_API_KEY:
45
+ # Return mock data for demo
46
+ return {"conversations": [], "mock": True}
47
+ async with httpx.AsyncClient(timeout=30.0) as client:
48
  resp = await client.get(
49
  f"{OPENHANDS_BASE_URL}/api/conversations",
50
+ headers=get_headers()
51
  )
52
  resp.raise_for_status()
53
  return resp.json()
 
55
  @app.post("/api/conversations")
56
  async def create_conversation(data: dict):
57
  if not OPENHANDS_API_KEY:
58
+ # Return mock for demo
59
+ import uuid
60
+ return {"conversation_id": str(uuid.uuid4()), "message": "Mock response - configure API key for real agent", "mock": True}
61
+ async with httpx.AsyncClient(timeout=60.0) as client:
62
  resp = await client.post(
63
  f"{OPENHANDS_BASE_URL}/api/conversations",
64
+ headers=get_headers(),
65
  json=data
66
  )
67
  resp.raise_for_status()
68
  return resp.json()
69
+
70
+ @app.get("/api/conversations/{conv_id}")
71
+ async def get_conversation(conv_id: str):
72
+ if not OPENHANDS_API_KEY:
73
+ return {"id": conv_id, "messages": [], "mock": True}
74
+ async with httpx.AsyncClient(timeout=30.0) as client:
75
+ resp = await client.get(
76
+ f"{OPENHANDS_BASE_URL}/api/conversations/{conv_id}",
77
+ headers=get_headers()
78
+ )
79
+ resp.raise_for_status()
80
+ return resp.json()
81
+
82
+ @app.websocket("/ws/conversations/{conv_id}/events")
83
+ async def websocket_events(conv_id: str, websocket):
84
+ await websocket.accept()
85
+ if not OPENHANDS_API_KEY:
86
+ await websocket.send_json({"type": "error", "message": "API key not configured"})
87
+ await websocket.close()
88
+ return
89
+ # Proxy to OpenHands Cloud WebSocket
90
+ async with httpx.AsyncClient(timeout=httpx.Timeout(300.0)) as client:
91
+ async with client.stream(
92
+ "GET",
93
+ f"{OPENHANDS_BASE_URL}/ws/conversations/{conv_id}/events",
94
+ headers={"Authorization": f"Bearer {OPENHANDS_API_KEY}"}
95
+ ) as resp:
96
+ async for line in resp.aiter_lines():
97
+ if line:
98
+ await websocket.send_text(line)