norhan12 commited on
Commit
98be153
·
verified ·
1 Parent(s): dee18ff

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -40
app.py CHANGED
@@ -1,32 +1,43 @@
1
- from fastapi import FastAPI, HTTPException, Body
2
- from pydantic import BaseModel, HttpUrl
3
  import os
4
  import uuid
5
  import shutil
6
  import json
7
  import requests
8
- from process_interview import process_interview
 
 
9
  from fastapi.staticfiles import StaticFiles
10
  from fastapi.responses import FileResponse
 
 
 
 
 
 
11
 
 
12
  app = FastAPI()
13
 
14
- TEMP_DIR = "./temp_files"
15
- OUTPUT_DIR = "./static/outputs"
 
 
 
16
  JSON_DIR = os.path.join(OUTPUT_DIR, "json")
17
  PDF_DIR = os.path.join(OUTPUT_DIR, "pdf")
18
 
19
- os.makedirs(TEMP_DIR, exist_ok=True)
20
- os.makedirs(JSON_DIR, exist_ok=True)
21
- os.makedirs(PDF_DIR, exist_ok=True)
22
 
23
- app.mount("/static", StaticFiles(directory="static"), name="static")
 
24
 
 
25
  VALID_EXTENSIONS = ('.wav', '.mp3', '.m4a', '.flac')
26
  MAX_FILE_SIZE_MB = 300
27
-
28
  BASE_URL = os.getenv("BASE_URL", "https://evalbot-audio-evalbot.hf.space")
29
 
 
30
  class ProcessResponse(BaseModel):
31
  summary: str
32
  json_url: str
@@ -36,42 +47,59 @@ class ProcessAudioRequest(BaseModel):
36
  file_url: HttpUrl
37
  user_id: str
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  @app.post("/process-audio", response_model=ProcessResponse)
40
  async def process_audio(request: ProcessAudioRequest = Body(...)):
41
- file_url = request.file_url
42
  user_id = request.user_id
43
- try:
44
- file_ext = os.path.splitext(str(file_url))[1].lower()
45
- if file_ext not in VALID_EXTENSIONS:
46
- raise HTTPException(status_code=400, detail=f"Invalid file extension: {file_ext}")
47
 
48
- local_filename = f"{user_id}_{uuid.uuid4().hex}{file_ext}"
49
- local_path = os.path.join(TEMP_DIR, local_filename)
 
 
50
 
51
- resp = requests.get(str(file_url), stream=True, timeout=30)
52
- if resp.status_code != 200:
53
- raise HTTPException(status_code=400, detail="Could not download the file from URL")
54
 
55
- with open(local_path, "wb") as f:
56
- for chunk in resp.iter_content(chunk_size=8192):
57
- if chunk:
58
- f.write(chunk)
59
 
60
- file_size_mb = os.path.getsize(local_path) / (1024 * 1024)
61
- if file_size_mb > MAX_FILE_SIZE_MB:
62
- os.remove(local_path)
63
- raise HTTPException(status_code=400, detail=f"File too large: {file_size_mb:.2f} MB")
64
 
65
- result = process_interview(local_path)
66
  if not result:
67
- os.remove(local_path)
68
  raise HTTPException(status_code=500, detail="Processing failed")
69
 
70
- json_dest_name = f"{user_id}_{uuid.uuid4().hex}.json"
71
- pdf_dest_name = f"{user_id}_{uuid.uuid4().hex}.pdf"
72
 
73
- json_dest = os.path.join(JSON_DIR, json_dest_name)
74
- pdf_dest = os.path.join(PDF_DIR, pdf_dest_name)
75
 
76
  shutil.copyfile(result['json_path'], json_dest)
77
  shutil.copyfile(result['pdf_path'], pdf_dest)
@@ -91,17 +119,22 @@ async def process_audio(request: ProcessAudioRequest = Body(...)):
91
  f"Anxiety: {voice.get('anxiety_level', 'N/A')}"
92
  )
93
 
94
- json_url = f"{BASE_URL}/outputs/json/{json_dest_name}"
95
- pdf_url = f"{BASE_URL}/outputs/pdf/{pdf_dest_name}"
96
-
97
- os.remove(local_path)
98
 
 
99
  return ProcessResponse(summary=summary, json_url=json_url, pdf_url=pdf_url)
100
 
 
 
101
  except Exception as e:
102
- raise HTTPException(status_code=500, detail=str(e))
103
-
 
 
 
104
 
 
105
  @app.get("/outputs/json/{filename}")
106
  async def get_json_file(filename: str):
107
  file_path = os.path.join(JSON_DIR, filename)
 
 
 
1
  import os
2
  import uuid
3
  import shutil
4
  import json
5
  import requests
6
+ import logging
7
+
8
+ from fastapi import FastAPI, HTTPException, Body
9
  from fastapi.staticfiles import StaticFiles
10
  from fastapi.responses import FileResponse
11
+ from pydantic import BaseModel, HttpUrl
12
+ from process_interview import process_interview
13
+
14
+ # Setup Logging
15
+ logging.basicConfig(level=logging.INFO)
16
+ logger = logging.getLogger("EvalBot-Audio-Processor")
17
 
18
+ # Initialize App
19
  app = FastAPI()
20
 
21
+ # Directories setup
22
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
23
+ TEMP_DIR = os.path.join(BASE_DIR, "temp_files")
24
+ STATIC_DIR = os.path.join(BASE_DIR, "static")
25
+ OUTPUT_DIR = os.path.join(STATIC_DIR, "outputs")
26
  JSON_DIR = os.path.join(OUTPUT_DIR, "json")
27
  PDF_DIR = os.path.join(OUTPUT_DIR, "pdf")
28
 
29
+ for folder in [TEMP_DIR, JSON_DIR, PDF_DIR]:
30
+ os.makedirs(folder, exist_ok=True)
 
31
 
32
+ # Mount static files for serving output files
33
+ app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
34
 
35
+ # Configurations
36
  VALID_EXTENSIONS = ('.wav', '.mp3', '.m4a', '.flac')
37
  MAX_FILE_SIZE_MB = 300
 
38
  BASE_URL = os.getenv("BASE_URL", "https://evalbot-audio-evalbot.hf.space")
39
 
40
+ # Request and Response models
41
  class ProcessResponse(BaseModel):
42
  summary: str
43
  json_url: str
 
47
  file_url: HttpUrl
48
  user_id: str
49
 
50
+ # Helper functions
51
+ def download_file(file_url: str, dest_path: str):
52
+ logger.info(f"Downloading file from {file_url}")
53
+ try:
54
+ resp = requests.get(file_url, stream=True, timeout=60)
55
+ resp.raise_for_status()
56
+ with open(dest_path, "wb") as f:
57
+ for chunk in resp.iter_content(chunk_size=8192):
58
+ if chunk:
59
+ f.write(chunk)
60
+ except Exception as e:
61
+ logger.error(f"Error downloading file: {e}")
62
+ raise HTTPException(status_code=400, detail="Failed to download file")
63
+
64
+ def validate_file_size(file_path: str):
65
+ file_size_mb = os.path.getsize(file_path) / (1024 * 1024)
66
+ if file_size_mb > MAX_FILE_SIZE_MB:
67
+ logger.warning(f"File too large: {file_size_mb} MB")
68
+ os.remove(file_path)
69
+ raise HTTPException(status_code=400, detail=f"File too large: {file_size_mb:.2f} MB")
70
+
71
+ def generate_public_url(sub_path: str) -> str:
72
+ return f"{BASE_URL}/static/{sub_path}"
73
+
74
+ # Main endpoint
75
  @app.post("/process-audio", response_model=ProcessResponse)
76
  async def process_audio(request: ProcessAudioRequest = Body(...)):
77
+ file_url = str(request.file_url)
78
  user_id = request.user_id
 
 
 
 
79
 
80
+ file_ext = os.path.splitext(file_url)[1].lower()
81
+ if file_ext not in VALID_EXTENSIONS:
82
+ logger.error("Invalid file extension")
83
+ raise HTTPException(status_code=400, detail=f"Invalid file extension: {file_ext}")
84
 
85
+ temp_filename = f"{user_id}_{uuid.uuid4().hex}{file_ext}"
86
+ temp_path = os.path.join(TEMP_DIR, temp_filename)
 
87
 
88
+ try:
89
+ download_file(file_url, temp_path)
90
+ validate_file_size(temp_path)
 
91
 
92
+ logger.info("Processing interview")
93
+ result = process_interview(temp_path)
 
 
94
 
 
95
  if not result:
 
96
  raise HTTPException(status_code=500, detail="Processing failed")
97
 
98
+ json_filename = f"{user_id}_{uuid.uuid4().hex}.json"
99
+ pdf_filename = f"{user_id}_{uuid.uuid4().hex}.pdf"
100
 
101
+ json_dest = os.path.join(JSON_DIR, json_filename)
102
+ pdf_dest = os.path.join(PDF_DIR, pdf_filename)
103
 
104
  shutil.copyfile(result['json_path'], json_dest)
105
  shutil.copyfile(result['pdf_path'], pdf_dest)
 
119
  f"Anxiety: {voice.get('anxiety_level', 'N/A')}"
120
  )
121
 
122
+ json_url = generate_public_url(f"outputs/json/{json_filename}")
123
+ pdf_url = generate_public_url(f"outputs/pdf/{pdf_filename}")
 
 
124
 
125
+ logger.info("Processing completed successfully")
126
  return ProcessResponse(summary=summary, json_url=json_url, pdf_url=pdf_url)
127
 
128
+ except HTTPException as e:
129
+ raise e
130
  except Exception as e:
131
+ logger.exception("Unexpected error during processing")
132
+ raise HTTPException(status_code=500, detail="Internal server error")
133
+ finally:
134
+ if os.path.exists(temp_path):
135
+ os.remove(temp_path)
136
 
137
+ # Serve output files
138
  @app.get("/outputs/json/{filename}")
139
  async def get_json_file(filename: str):
140
  file_path = os.path.join(JSON_DIR, filename)