1+ import json
2+ from typing import Dict , Any
3+
4+ from starlette .applications import Starlette
5+ from starlette .middleware import Middleware
6+ from starlette .middleware .cors import CORSMiddleware
7+ from starlette .requests import Request
8+ from starlette .responses import JSONResponse , Response
9+ from starlette .routing import Route
10+ from starlette .templating import Jinja2Templates
11+
12+ from .room_service import RoomService
13+
14+
15+ # Initialize services
16+ room_service = RoomService ()
17+ templates = Jinja2Templates (directory = "templates" )
18+
19+
20+ async def create_peer (request : Request ) -> Response :
21+ """Create a new peer in a room."""
22+ try :
23+ body = await request .json ()
24+ room_name = body .get ("room_name" )
25+ peer_name = body .get ("peer_name" )
26+
27+ if not room_name or not peer_name :
28+ return JSONResponse (
29+ {"error" : "room_name and peer_name are required" },
30+ status_code = 400
31+ )
32+
33+ peer , token = room_service .create_peer ()
34+
35+ return JSONResponse ({
36+ "peer_id" : peer .id ,
37+ "token" : token ,
38+ "room_name" : room_name ,
39+ "peer_name" : peer_name
40+ })
41+
42+ except Exception as e :
43+ return JSONResponse ({"error" : str (e )}, status_code = 500 )
44+
45+
46+ async def get_available_peers (request : Request ) -> Response :
47+ """Get peers available for subscription."""
48+ room_name = request .path_params .get ("room_name" )
49+ peer_id = request .query_params .get ("peer_id" )
50+
51+ if not room_name :
52+ return JSONResponse ({"error" : "room_name is required" }, status_code = 400 )
53+
54+ peers = room_service .get_available_peers (room_name , peer_id )
55+
56+ return JSONResponse ({
57+ "peers" : [
58+ {
59+ "id" : peer .id ,
60+ "metadata" : peer .metadata if peer .metadata else {},
61+ "tracks" : [
62+ {
63+ "id" : track ["id" ],
64+ "type" : track .get ("type" , "unknown" )
65+ }
66+ for track in peer .tracks
67+ ]
68+ }
69+ for peer in peers
70+ ]
71+ })
72+
73+
74+ async def toggle_subscription (request : Request ) -> Response :
75+ """Toggle subscription to a peer's tracks."""
76+ try :
77+ body = await request .json ()
78+ peer_id = body .get ("peer_id" )
79+ target_peer_id = body .get ("target_peer_id" )
80+
81+ if not peer_id or not target_peer_id :
82+ return JSONResponse (
83+ {"error" : "peer_id and target_peer_id are required" },
84+ status_code = 400
85+ )
86+
87+ subscribed = room_service .toggle_subscription (peer_id , target_peer_id )
88+
89+ return JSONResponse ({
90+ "subscribed" : subscribed ,
91+ "peer_id" : peer_id ,
92+ "target_peer_id" : target_peer_id
93+ })
94+
95+ except Exception as e :
96+ return JSONResponse ({"error" : str (e )}, status_code = 500 )
97+
98+
99+ async def get_subscription_status (request : Request ) -> Response :
100+ """Get current subscription status for a peer."""
101+ peer_id = request .path_params .get ("peer_id" )
102+
103+ if not peer_id :
104+ return JSONResponse ({"error" : "peer_id is required" }, status_code = 400 )
105+
106+ session = room_service .get_peer_session (peer_id )
107+
108+ if not session :
109+ return JSONResponse ({"error" : "Peer not found" }, status_code = 404 )
110+
111+ return JSONResponse ({
112+ "peer_id" : peer_id ,
113+ "subscribed_peers" : list (session .subscribed_peers )
114+ })
115+
116+
117+ async def health_check (request : Request ) -> Response :
118+ """Health check endpoint."""
119+ return JSONResponse ({"status" : "OK" })
120+
121+
122+ async def serve_index (request : Request ) -> Response :
123+ """Serve the main HTML interface."""
124+ return templates .TemplateResponse ("index.html" , {"request" : request })
125+
126+
127+ # Define routes
128+ routes = [
129+ Route ("/" , serve_index , methods = ["GET" ]),
130+ Route ("/health" , health_check , methods = ["GET" ]),
131+ Route ("/api/peers" , create_peer , methods = ["POST" ]),
132+ Route ("/api/rooms/{room_name}/peers" , get_available_peers , methods = ["GET" ]),
133+ Route ("/api/subscriptions" , toggle_subscription , methods = ["POST" ]),
134+ Route ("/api/peers/{peer_id}/subscriptions" , get_subscription_status , methods = ["GET" ]),
135+ ]
136+
137+ # Define middleware
138+ middleware = [
139+ Middleware (
140+ CORSMiddleware ,
141+ allow_origins = ["*" ],
142+ allow_credentials = True ,
143+ allow_methods = ["*" ],
144+ allow_headers = ["*" ],
145+ )
146+ ]
147+
148+ # Create application
149+ app = Starlette (
150+ routes = routes ,
151+ middleware = middleware ,
152+ )
0 commit comments