parth-meet / app.py
parthmax4's picture
Update app.py
a0584da verified
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPException
from fastapi.responses import HTMLResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import uvicorn
import json
import secrets
from typing import Dict, Set
from datetime import datetime
app = FastAPI(title="ParthMeet")
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# In-memory storage
meetings: Dict[str, dict] = {}
connections: Dict[str, Dict[str, WebSocket]] = {}
class MeetingCreate(BaseModel):
host_name: str
class MeetingJoin(BaseModel):
meeting_id: str
participant_name: str
def generate_meeting_id() -> str:
"""Generate a unique 10-character meeting ID"""
return secrets.token_urlsafe(8)[:10].replace('-', 'x').replace('_', 'y')
@app.get("/", response_class=HTMLResponse)
async def read_root():
"""Serve the main HTML page"""
return HTMLResponse(content=open("index.html").read())
@app.post("/api/meeting/create")
async def create_meeting(data: MeetingCreate):
"""Create a new meeting"""
meeting_id = generate_meeting_id()
meetings[meeting_id] = {
"id": meeting_id,
"host": data.host_name,
"participants": [],
"created_at": datetime.now().isoformat(),
"active": True
}
connections[meeting_id] = {}
return {
"success": True,
"meeting_id": meeting_id,
"meeting": meetings[meeting_id]
}
@app.get("/api/meeting/{meeting_id}")
async def get_meeting(meeting_id: str):
"""Get meeting details"""
if meeting_id not in meetings:
raise HTTPException(status_code=404, detail="Meeting not found")
return {
"success": True,
"meeting": meetings[meeting_id]
}
@app.post("/api/meeting/end/{meeting_id}")
async def end_meeting(meeting_id: str):
"""End a meeting"""
if meeting_id not in meetings:
raise HTTPException(status_code=404, detail="Meeting not found")
meetings[meeting_id]["active"] = False
# Notify all participants
if meeting_id in connections:
for ws in connections[meeting_id].values():
try:
await ws.send_json({
"type": "meeting_ended",
"data": {"message": "The meeting has been ended by the host"}
})
except:
pass
connections[meeting_id].clear()
return {"success": True, "message": "Meeting ended"}
@app.websocket("/ws/{meeting_id}/{participant_id}")
async def websocket_endpoint(websocket: WebSocket, meeting_id: str, participant_id: str):
"""WebSocket endpoint for real-time communication"""
await websocket.accept()
if meeting_id not in meetings:
await websocket.send_json({
"type": "error",
"data": {"message": "Meeting not found"}
})
await websocket.close()
return
if not meetings[meeting_id]["active"]:
await websocket.send_json({
"type": "error",
"data": {"message": "Meeting has ended"}
})
await websocket.close()
return
# Add connection
if meeting_id not in connections:
connections[meeting_id] = {}
connections[meeting_id][participant_id] = websocket
# Notify others about new participant
for pid, ws in connections[meeting_id].items():
if pid != participant_id:
try:
await ws.send_json({
"type": "participant_joined",
"data": {"participant_id": participant_id}
})
except:
pass
try:
while True:
data = await websocket.receive_text()
message = json.loads(data)
# Broadcast to specific participant or all
if message.get("target"):
target_id = message["target"]
if target_id in connections[meeting_id]:
try:
await connections[meeting_id][target_id].send_json(message)
except:
pass
else:
# Broadcast to all except sender
for pid, ws in connections[meeting_id].items():
if pid != participant_id:
try:
await ws.send_json(message)
except:
pass
except WebSocketDisconnect:
# Remove connection
if meeting_id in connections and participant_id in connections[meeting_id]:
del connections[meeting_id][participant_id]
# Notify others about participant leaving
if meeting_id in connections:
for ws in connections[meeting_id].values():
try:
await ws.send_json({
"type": "participant_left",
"data": {"participant_id": participant_id}
})
except:
pass
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)