Nagesh Muralidhar commited on
Commit
62fea8b
·
1 Parent(s): 72e705f

midterm-submission

Browse files
Files changed (1) hide show
  1. server/main.py +110 -110
server/main.py CHANGED
@@ -39,10 +39,29 @@ chat_model = ChatOpenAI(
39
  openai_api_key=openai_api_key
40
  )
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  # Initialize FastAPI app
43
  app = FastAPI()
44
 
45
- # Configure CORS for frontend development server
46
  app.add_middleware(
47
  CORSMiddleware,
48
  allow_origins=["http://localhost:5173", "http://localhost:3000", "https://*.hf.space", "*"],
@@ -53,37 +72,49 @@ app.add_middleware(
53
  max_age=600,
54
  )
55
 
56
- # Mount static files for React frontend
57
- app.mount("/", StaticFiles(directory="static", html=True), name="frontend")
58
-
59
- # Configure audio storage
60
  audio_dir = os.path.join(os.path.dirname(__file__), "audio_storage")
61
  os.makedirs(audio_dir, exist_ok=True)
62
 
63
- # Mount the audio directory as a static file directory
64
- app.mount("/audio-files", StaticFiles(directory=audio_dir), name="audio")
65
-
66
- # Configure context storage
67
  context_dir = os.path.join(os.path.dirname(__file__), "context_storage")
68
  os.makedirs(context_dir, exist_ok=True)
69
 
70
- class ChatMessage(BaseModel):
71
- content: str
72
- context: Optional[Dict[str, Any]] = None
73
- agent_type: Optional[str] = "believer"
74
-
75
- class WorkflowResponse(BaseModel):
76
- debate_history: List[Dict[str, str]]
77
- supervisor_notes: List[str]
78
- supervisor_chunks: List[Dict[str, List[str]]]
79
- extractor_data: Dict[str, Any]
80
- final_podcast: Dict[str, Any]
81
-
82
- class PodcastChatRequest(BaseModel):
83
- message: str
84
 
85
- class PodcastChatResponse(BaseModel):
86
- response: str
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  @app.get("/audio-list")
89
  async def list_audio_files():
@@ -103,55 +134,7 @@ async def list_audio_files():
103
  except Exception as e:
104
  raise HTTPException(status_code=500, detail=str(e))
105
 
106
- @app.delete("/audio/{filename}")
107
- async def delete_audio_file(filename: str):
108
- """Delete an audio file and its corresponding transcript."""
109
- try:
110
- # Delete audio file
111
- file_path = os.path.join(audio_dir, filename)
112
- if not os.path.exists(file_path):
113
- raise HTTPException(status_code=404, detail="File not found")
114
-
115
- # Get all audio files to determine the podcast ID
116
- audio_files = [f for f in os.listdir(audio_dir) if f.endswith(('.mp3', '.wav'))]
117
- try:
118
- # Find the index (0-based) of the file being deleted
119
- podcast_id = audio_files.index(filename) + 1 # Convert to 1-based ID
120
- logger.info(f"Deleting podcast with ID: {podcast_id}")
121
-
122
- # Path to transcripts file
123
- transcripts_file = os.path.join(os.path.dirname(__file__), "transcripts", "podcasts.json")
124
-
125
- # Update transcripts if file exists
126
- if os.path.exists(transcripts_file):
127
- with open(transcripts_file, 'r') as f:
128
- transcripts = json.load(f)
129
-
130
- # Remove the transcript at the corresponding index
131
- if len(transcripts) >= podcast_id:
132
- transcripts.pop(podcast_id - 1) # Convert back to 0-based index
133
-
134
- # Save updated transcripts
135
- with open(transcripts_file, 'w') as f:
136
- json.dump(transcripts, f, indent=2)
137
- logger.info(f"Removed transcript for podcast ID {podcast_id}")
138
-
139
- # Delete the audio file
140
- os.remove(file_path)
141
- logger.info(f"Deleted audio file: {filename}")
142
-
143
- return {"message": "File and transcript deleted successfully"}
144
-
145
- except ValueError:
146
- logger.error(f"Could not determine podcast ID for file: {filename}")
147
- # Still delete the audio file even if transcript removal fails
148
- os.remove(file_path)
149
- return {"message": "Audio file deleted, but transcript could not be removed"}
150
-
151
- except Exception as e:
152
- logger.error(f"Error in delete_audio_file: {str(e)}")
153
- raise HTTPException(status_code=500, detail=str(e))
154
-
155
  @app.get("/audio/{filename}")
156
  async def get_audio_file(filename: str):
157
  """Get an audio file by filename."""
@@ -288,42 +271,6 @@ async def get_podcast_context(podcast_id: str):
288
  logger.error(f"Error in get_podcast_context: {str(e)}", exc_info=True)
289
  raise HTTPException(status_code=500, detail=str(e))
290
 
291
- @app.post("/chat")
292
- async def chat(message: ChatMessage):
293
- """Process a chat message."""
294
- try:
295
- # Get API key
296
- tavily_api_key = os.getenv("TAVILY_API_KEY")
297
- if not tavily_api_key:
298
- logger.error("Tavily API key not found")
299
- raise HTTPException(status_code=500, detail="Tavily API key not configured")
300
-
301
- # Initialize the workflow
302
- try:
303
- workflow = create_workflow(tavily_api_key)
304
- logger.info("Workflow created successfully")
305
- except Exception as e:
306
- logger.error(f"Error creating workflow: {str(e)}")
307
- raise HTTPException(status_code=500, detail=f"Error creating workflow: {str(e)}")
308
-
309
- # Run the workflow with context
310
- try:
311
- result = await run_workflow(
312
- workflow,
313
- message.content,
314
- agent_type=message.agent_type,
315
- context=message.context
316
- )
317
- logger.info("Workflow completed successfully")
318
- return result
319
- except Exception as e:
320
- logger.error(f"Error running workflow: {str(e)}")
321
- raise HTTPException(status_code=500, detail=f"Error running workflow: {str(e)}")
322
-
323
- except Exception as e:
324
- logger.error(f"Error in chat endpoint: {str(e)}", exc_info=True)
325
- raise HTTPException(status_code=500, detail=str(e))
326
-
327
  @app.post("/podcast-chat/{podcast_id}", response_model=PodcastChatResponse)
328
  async def podcast_chat(podcast_id: str, request: PodcastChatRequest):
329
  """Handle chat messages for a specific podcast."""
@@ -429,6 +376,59 @@ async def podcast_chat(podcast_id: str, request: PodcastChatRequest):
429
  logger.error(f"Error in podcast chat: {str(e)}", exc_info=True)
430
  raise HTTPException(status_code=500, detail=str(e))
431
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  if __name__ == "__main__":
433
  import uvicorn
434
  uvicorn.run(app, host="0.0.0.0", port=8000)
 
39
  openai_api_key=openai_api_key
40
  )
41
 
42
+ # Define Pydantic models
43
+ class ChatMessage(BaseModel):
44
+ content: str
45
+ context: Optional[Dict[str, Any]] = None
46
+ agent_type: Optional[str] = "believer"
47
+
48
+ class WorkflowResponse(BaseModel):
49
+ debate_history: List[Dict[str, str]]
50
+ supervisor_notes: List[str]
51
+ supervisor_chunks: List[Dict[str, List[str]]]
52
+ extractor_data: Dict[str, Any]
53
+ final_podcast: Dict[str, Any]
54
+
55
+ class PodcastChatRequest(BaseModel):
56
+ message: str
57
+
58
+ class PodcastChatResponse(BaseModel):
59
+ response: str
60
+
61
  # Initialize FastAPI app
62
  app = FastAPI()
63
 
64
+ # Configure CORS
65
  app.add_middleware(
66
  CORSMiddleware,
67
  allow_origins=["http://localhost:5173", "http://localhost:3000", "https://*.hf.space", "*"],
 
72
  max_age=600,
73
  )
74
 
75
+ # Configure storage directories
 
 
 
76
  audio_dir = os.path.join(os.path.dirname(__file__), "audio_storage")
77
  os.makedirs(audio_dir, exist_ok=True)
78
 
 
 
 
 
79
  context_dir = os.path.join(os.path.dirname(__file__), "context_storage")
80
  os.makedirs(context_dir, exist_ok=True)
81
 
82
+ # API Routes
83
+ @app.post("/chat")
84
+ async def chat(message: ChatMessage):
85
+ """Process a chat message."""
86
+ try:
87
+ # Get API key
88
+ tavily_api_key = os.getenv("TAVILY_API_KEY")
89
+ if not tavily_api_key:
90
+ logger.error("Tavily API key not found")
91
+ raise HTTPException(status_code=500, detail="Tavily API key not configured")
 
 
 
 
92
 
93
+ # Initialize the workflow
94
+ try:
95
+ workflow = create_workflow(tavily_api_key)
96
+ logger.info("Workflow created successfully")
97
+ except Exception as e:
98
+ logger.error(f"Error creating workflow: {str(e)}")
99
+ raise HTTPException(status_code=500, detail=f"Error creating workflow: {str(e)}")
100
+
101
+ # Run the workflow with context
102
+ try:
103
+ result = await run_workflow(
104
+ workflow,
105
+ message.content,
106
+ agent_type=message.agent_type,
107
+ context=message.context
108
+ )
109
+ logger.info("Workflow completed successfully")
110
+ return result
111
+ except Exception as e:
112
+ logger.error(f"Error running workflow: {str(e)}")
113
+ raise HTTPException(status_code=500, detail=f"Error running workflow: {str(e)}")
114
+
115
+ except Exception as e:
116
+ logger.error(f"Error in chat endpoint: {str(e)}", exc_info=True)
117
+ raise HTTPException(status_code=500, detail=str(e))
118
 
119
  @app.get("/audio-list")
120
  async def list_audio_files():
 
134
  except Exception as e:
135
  raise HTTPException(status_code=500, detail=str(e))
136
 
137
+ # Add other API routes here...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  @app.get("/audio/{filename}")
139
  async def get_audio_file(filename: str):
140
  """Get an audio file by filename."""
 
271
  logger.error(f"Error in get_podcast_context: {str(e)}", exc_info=True)
272
  raise HTTPException(status_code=500, detail=str(e))
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  @app.post("/podcast-chat/{podcast_id}", response_model=PodcastChatResponse)
275
  async def podcast_chat(podcast_id: str, request: PodcastChatRequest):
276
  """Handle chat messages for a specific podcast."""
 
376
  logger.error(f"Error in podcast chat: {str(e)}", exc_info=True)
377
  raise HTTPException(status_code=500, detail=str(e))
378
 
379
+ @app.delete("/audio/{filename}")
380
+ async def delete_audio_file(filename: str):
381
+ """Delete an audio file and its corresponding transcript."""
382
+ try:
383
+ # Delete audio file
384
+ file_path = os.path.join(audio_dir, filename)
385
+ if not os.path.exists(file_path):
386
+ raise HTTPException(status_code=404, detail="File not found")
387
+
388
+ # Get all audio files to determine the podcast ID
389
+ audio_files = [f for f in os.listdir(audio_dir) if f.endswith(('.mp3', '.wav'))]
390
+ try:
391
+ # Find the index (0-based) of the file being deleted
392
+ podcast_id = audio_files.index(filename) + 1 # Convert to 1-based ID
393
+ logger.info(f"Deleting podcast with ID: {podcast_id}")
394
+
395
+ # Path to transcripts file
396
+ transcripts_file = os.path.join(os.path.dirname(__file__), "transcripts", "podcasts.json")
397
+
398
+ # Update transcripts if file exists
399
+ if os.path.exists(transcripts_file):
400
+ with open(transcripts_file, 'r') as f:
401
+ transcripts = json.load(f)
402
+
403
+ # Remove the transcript at the corresponding index
404
+ if len(transcripts) >= podcast_id:
405
+ transcripts.pop(podcast_id - 1) # Convert back to 0-based index
406
+
407
+ # Save updated transcripts
408
+ with open(transcripts_file, 'w') as f:
409
+ json.dump(transcripts, f, indent=2)
410
+ logger.info(f"Removed transcript for podcast ID {podcast_id}")
411
+
412
+ # Delete the audio file
413
+ os.remove(file_path)
414
+ logger.info(f"Deleted audio file: {filename}")
415
+
416
+ return {"message": "File and transcript deleted successfully"}
417
+
418
+ except ValueError:
419
+ logger.error(f"Could not determine podcast ID for file: {filename}")
420
+ # Still delete the audio file even if transcript removal fails
421
+ os.remove(file_path)
422
+ return {"message": "Audio file deleted, but transcript could not be removed"}
423
+
424
+ except Exception as e:
425
+ logger.error(f"Error in delete_audio_file: {str(e)}")
426
+ raise HTTPException(status_code=500, detail=str(e))
427
+
428
+ # Static file mounts (must be last)
429
+ app.mount("/audio-files", StaticFiles(directory=audio_dir), name="audio")
430
+ app.mount("/", StaticFiles(directory="static", html=True), name="frontend")
431
+
432
  if __name__ == "__main__":
433
  import uvicorn
434
  uvicorn.run(app, host="0.0.0.0", port=8000)