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

midterm-submission

Browse files
podcraft/src/pages/Home.tsx CHANGED
@@ -58,7 +58,7 @@ const Home: React.FC = () => {
58
  agent: "system"
59
  }]);
60
 
61
- const response = await fetch(`${API_URL}/chat`, {
62
  method: 'POST',
63
  headers: {
64
  'Content-Type': 'application/json',
 
58
  agent: "system"
59
  }]);
60
 
61
+ const response = await fetch(`${API_URL}/api/chat`, {
62
  method: 'POST',
63
  headers: {
64
  'Content-Type': 'application/json',
podcraft/src/pages/Podcasts.tsx CHANGED
@@ -2,7 +2,9 @@ import React, { useState, useEffect } from 'react';
2
  import { useNavigate } from 'react-router-dom';
3
  import '../App.css';
4
 
5
- const API_URL = 'http://localhost:8000';
 
 
6
 
7
  interface Podcast {
8
  id: number;
@@ -25,7 +27,7 @@ const Podcasts: React.FC = () => {
25
 
26
  const handleDelete = async (podcast: Podcast) => {
27
  try {
28
- const response = await fetch(`${API_URL}/audio/${podcast.filename}`, {
29
  method: 'DELETE',
30
  headers: {
31
  'Content-Type': 'application/json',
@@ -51,7 +53,7 @@ const Podcasts: React.FC = () => {
51
 
52
  const fetchPodcasts = async () => {
53
  try {
54
- const response = await fetch(`${API_URL}/audio-list`);
55
  if (!response.ok) {
56
  throw new Error('Failed to fetch podcasts');
57
  }
@@ -67,7 +69,7 @@ const Podcasts: React.FC = () => {
67
  id: index + 1,
68
  title: `${descriptionPart.replace(/_/g, ' ').replace(/^\w/, c => c.toUpperCase())}`,
69
  description: `A debate exploring ${queryPart.replace(/_/g, ' ')}`,
70
- audio_file: `${API_URL}${file.path}`,
71
  filename: filename,
72
  category: category.replace(/_/g, ' ')
73
  };
 
2
  import { useNavigate } from 'react-router-dom';
3
  import '../App.css';
4
 
5
+ // Use relative URLs in production, full URLs in development
6
+ const isDevelopment = window.location.hostname === 'localhost';
7
+ const API_URL = isDevelopment ? 'http://localhost:8000' : '';
8
 
9
  interface Podcast {
10
  id: number;
 
27
 
28
  const handleDelete = async (podcast: Podcast) => {
29
  try {
30
+ const response = await fetch(`${API_URL}/api/audio/${podcast.filename}`, {
31
  method: 'DELETE',
32
  headers: {
33
  'Content-Type': 'application/json',
 
53
 
54
  const fetchPodcasts = async () => {
55
  try {
56
+ const response = await fetch(`${API_URL}/api/audio-list`);
57
  if (!response.ok) {
58
  throw new Error('Failed to fetch podcasts');
59
  }
 
69
  id: index + 1,
70
  title: `${descriptionPart.replace(/_/g, ' ').replace(/^\w/, c => c.toUpperCase())}`,
71
  description: `A debate exploring ${queryPart.replace(/_/g, ' ')}`,
72
+ audio_file: file.path, // Use relative path returned from server
73
  filename: filename,
74
  category: category.replace(/_/g, ' ')
75
  };
server/main.py CHANGED
@@ -1,4 +1,4 @@
1
- from fastapi import FastAPI, HTTPException
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import FileResponse
4
  from fastapi.staticfiles import StaticFiles
@@ -61,6 +61,9 @@ class PodcastChatResponse(BaseModel):
61
  # Initialize FastAPI app
62
  app = FastAPI()
63
 
 
 
 
64
  # Configure CORS
65
  app.add_middleware(
66
  CORSMiddleware,
@@ -80,7 +83,7 @@ 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:
@@ -116,7 +119,7 @@ async def chat(message: ChatMessage):
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():
121
  """List all available audio files."""
122
  try:
@@ -134,8 +137,7 @@ 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."""
141
  try:
@@ -146,6 +148,55 @@ async def get_audio_file(filename: str):
146
  except Exception as e:
147
  raise HTTPException(status_code=500, detail=str(e))
148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  @app.get("/podcast/{podcast_id}/context")
150
  async def get_podcast_context(podcast_id: str):
151
  """Get or generate context for a podcast."""
@@ -376,56 +427,10 @@ async def podcast_chat(podcast_id: str, request: PodcastChatRequest):
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
 
 
1
+ from fastapi import FastAPI, HTTPException, APIRouter
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import FileResponse
4
  from fastapi.staticfiles import StaticFiles
 
61
  # Initialize FastAPI app
62
  app = FastAPI()
63
 
64
+ # Create API router
65
+ api_router = APIRouter(prefix="/api")
66
+
67
  # Configure CORS
68
  app.add_middleware(
69
  CORSMiddleware,
 
83
  os.makedirs(context_dir, exist_ok=True)
84
 
85
  # API Routes
86
+ @api_router.post("/chat")
87
  async def chat(message: ChatMessage):
88
  """Process a chat message."""
89
  try:
 
119
  logger.error(f"Error in chat endpoint: {str(e)}", exc_info=True)
120
  raise HTTPException(status_code=500, detail=str(e))
121
 
122
+ @api_router.get("/audio-list")
123
  async def list_audio_files():
124
  """List all available audio files."""
125
  try:
 
137
  except Exception as e:
138
  raise HTTPException(status_code=500, detail=str(e))
139
 
140
+ @api_router.get("/audio/{filename}")
 
141
  async def get_audio_file(filename: str):
142
  """Get an audio file by filename."""
143
  try:
 
148
  except Exception as e:
149
  raise HTTPException(status_code=500, detail=str(e))
150
 
151
+ @api_router.delete("/audio/{filename}")
152
+ async def delete_audio_file(filename: str):
153
+ """Delete an audio file and its corresponding transcript."""
154
+ try:
155
+ # Delete audio file
156
+ file_path = os.path.join(audio_dir, filename)
157
+ if not os.path.exists(file_path):
158
+ raise HTTPException(status_code=404, detail="File not found")
159
+
160
+ # Get all audio files to determine the podcast ID
161
+ audio_files = [f for f in os.listdir(audio_dir) if f.endswith(('.mp3', '.wav'))]
162
+ try:
163
+ # Find the index (0-based) of the file being deleted
164
+ podcast_id = audio_files.index(filename) + 1 # Convert to 1-based ID
165
+ logger.info(f"Deleting podcast with ID: {podcast_id}")
166
+
167
+ # Path to transcripts file
168
+ transcripts_file = os.path.join(os.path.dirname(__file__), "transcripts", "podcasts.json")
169
+
170
+ # Update transcripts if file exists
171
+ if os.path.exists(transcripts_file):
172
+ with open(transcripts_file, 'r') as f:
173
+ transcripts = json.load(f)
174
+
175
+ # Remove the transcript at the corresponding index
176
+ if len(transcripts) >= podcast_id:
177
+ transcripts.pop(podcast_id - 1) # Convert back to 0-based index
178
+
179
+ # Save updated transcripts
180
+ with open(transcripts_file, 'w') as f:
181
+ json.dump(transcripts, f, indent=2)
182
+ logger.info(f"Removed transcript for podcast ID {podcast_id}")
183
+
184
+ # Delete the audio file
185
+ os.remove(file_path)
186
+ logger.info(f"Deleted audio file: {filename}")
187
+
188
+ return {"message": "File and transcript deleted successfully"}
189
+
190
+ except ValueError:
191
+ logger.error(f"Could not determine podcast ID for file: {filename}")
192
+ # Still delete the audio file even if transcript removal fails
193
+ os.remove(file_path)
194
+ return {"message": "Audio file deleted, but transcript could not be removed"}
195
+
196
+ except Exception as e:
197
+ logger.error(f"Error in delete_audio_file: {str(e)}")
198
+ raise HTTPException(status_code=500, detail=str(e))
199
+
200
  @app.get("/podcast/{podcast_id}/context")
201
  async def get_podcast_context(podcast_id: str):
202
  """Get or generate context for a podcast."""
 
427
  logger.error(f"Error in podcast chat: {str(e)}", exc_info=True)
428
  raise HTTPException(status_code=500, detail=str(e))
429
 
430
+ # Include the API router
431
+ app.include_router(api_router)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
 
433
+ # Mount static directories
434
  app.mount("/audio-files", StaticFiles(directory=audio_dir), name="audio")
435
  app.mount("/", StaticFiles(directory="static", html=True), name="frontend")
436