feat: Add support for uploading audio files to generate quizzes#673
feat: Add support for uploading audio files to generate quizzes#673AbiramiR-27 wants to merge 3 commits into
Conversation
|
Warning Review limit reached
Next review available in: 38 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughAdds audio upload transcription in the backend, routes WAV/MP3 files through chunked speech recognition, and returns upload errors as HTTP 400. It also adds the required Python dependencies, documents system prerequisites, and updates frontend upload labels and file filters. ChangesAudio Upload and Transcription
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (4)
eduaid_web/src/pages/Text_Input.jsx (1)
190-190: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider adding an
acceptattribute to the file input for better UX.The file input currently has no
acceptattribute to guide users toward supported formats. Since the backend now handles PDF and audio files (.pdf, .mp3, .wav), consider adding:- <input type="file" ref={fileInputRef} onChange={handleFileUpload} style={{ display: "none" }} /> + <input type="file" accept=".pdf,.mp3,.wav" ref={fileInputRef} onChange={handleFileUpload} style={{ display: "none" }} />🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@eduaid_web/src/pages/Text_Input.jsx` at line 190, The file picker in Text_Input.jsx currently allows any file type, so update the hidden input used by handleFileUpload to include an accept restriction for the supported backend formats. Add the accept attribute on the same input element referenced by fileInputRef so users are guided to choose only PDF and audio files such as .pdf, .mp3, and .wav.README.md (2)
25-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winClarify that WAV is also directly supported.
The current wording only mentions MP3→WAV conversion, but the backend also accepts
.wavfiles directly per the PR objectives. Users with WAV files may incorrectly think they need to convert externally. Consider rephrasing to indicate both formats are accepted, e.g.:- **ffmpeg** or **libav** installed and available on your system `PATH`. The backend's `extract_text_from_audio()` method (in `backend/Generator/main.py`) uses `pydub` to convert MP3 to WAV, and `pydub` depends on these tools for audio transcoding. + **ffmpeg** or **libav** installed and available on your system `PATH`. Required for audio file processing (`.mp3`, `.wav`). The backend's `extract_text_from_audio()` method (in `backend/Generator/main.py`) uses `pydub` to transcode audio when needed, and `pydub` depends on these tools.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` around lines 25 - 28, The System Requirements note in README.md only describes MP3-to-WAV conversion, but it should also state that .wav files are accepted directly. Update the wording around extract_text_from_audio() in backend/Generator/main.py so it clearly indicates both MP3 and WAV inputs are supported, while still mentioning ffmpeg/libav for transcoding support where needed. Keep the guidance user-facing and make it explicit that WAV users do not need to convert their files first.
25-28: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider adding the Python package dependencies to the documentation.
The system requirements section mentions
ffmpeg/libavbut doesn't mention the Python packages (pydub,SpeechRecognition) that were added torequirements.txtin a previous layer. Users installing from source may need to know these are required.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` around lines 25 - 28, The System Requirements section only mentions ffmpeg/libav, but it should also call out the Python dependencies added elsewhere. Update the README near the existing backend/extract_text_from_audio() guidance to explicitly list pydub and SpeechRecognition as required packages, so users installing from source know to install them alongside the system audio tools.extension/src/pages/text_input/TextInput.jsx (1)
240-245: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider adding an
acceptattribute to the file input for better UX.The file input currently has no
acceptattribute to guide users toward supported formats. Since the backend now handles PDF and audio files (.pdf, .mp3, .wav), consider adding:- <input type="file" ref={fileInputRef} onChange={handleFileUpload} style={{ display: 'none' }} /> + <input type="file" accept=".pdf,.mp3,.wav" ref={fileInputRef} onChange={handleFileUpload} style={{ display: 'none' }} />🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@extension/src/pages/text_input/TextInput.jsx` around lines 240 - 245, The file picker in TextInput’s hidden input lacks an accept filter, so users can choose unsupported files. Update the input element used by handleFileUpload and fileInputRef to include an accept attribute that matches the backend-supported formats, limiting selection to PDF and audio files such as .pdf, .mp3, and .wav.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/Generator/main.py`:
- Around line 405-406: The new exceptions from process_file() are escaping the
upload flow and turning user-facing failures into 500s. Update the caller in
backend/server.py around the file_processor.process_file invocation to catch
ValueError and RuntimeError explicitly, and map them to the intended HTTP
responses instead of letting them propagate. Use the existing process_file,
ValueError, and RuntimeError symbols to keep the route’s error contract
consistent for unsupported formats and speech API/request failures.
- Around line 381-401: The transcription flow in the upload path eagerly loads
the entire WAV and materializes all 60-second chunks before making one
recognition call per chunk, which can tie up workers and memory for long inputs.
Update the audio handling in the main transcription routine to enforce a
configured maximum duration/size before starting, and change the chunk
processing loop to stream or iterate chunks lazily instead of building the full
chunks list up front. Use the existing Recognizer/audio chunk logic in the
upload transcription path to place the limit and keep memory usage bounded.
- Around line 416-435: The upload handling in process_file currently trusts
file.filename for saving and deleting, which risks path traversal and filename
collisions. Change process_file to generate its own safe temporary storage name
before file.save and use that same generated path in the cleanup block, while
only carrying forward a validated extension from the original filename. Keep the
extension-based dispatch for .txt, .pdf, .docx, .wav, and .mp3, but do not use
the client-provided name directly anywhere in the filesystem path.
- Around line 376-392: The temporary WAV creation in the audio conversion flow
is happening before the cleanup scope, so it can be left behind if later steps
fail. Move the MP3-to-WAV export in `main.py` into the existing `try/finally`
used by the chunking/transcription path, alongside the `wav_path` handling in
`Generator`’s audio processing logic. Keep `wav_path` creation and any file
cleanup within that same scope so failures in `AudioSegment.from_wav` or chunk
construction still trigger deletion of the temp file.
---
Nitpick comments:
In `@eduaid_web/src/pages/Text_Input.jsx`:
- Line 190: The file picker in Text_Input.jsx currently allows any file type, so
update the hidden input used by handleFileUpload to include an accept
restriction for the supported backend formats. Add the accept attribute on the
same input element referenced by fileInputRef so users are guided to choose only
PDF and audio files such as .pdf, .mp3, and .wav.
In `@extension/src/pages/text_input/TextInput.jsx`:
- Around line 240-245: The file picker in TextInput’s hidden input lacks an
accept filter, so users can choose unsupported files. Update the input element
used by handleFileUpload and fileInputRef to include an accept attribute that
matches the backend-supported formats, limiting selection to PDF and audio files
such as .pdf, .mp3, and .wav.
In `@README.md`:
- Around line 25-28: The System Requirements note in README.md only describes
MP3-to-WAV conversion, but it should also state that .wav files are accepted
directly. Update the wording around extract_text_from_audio() in
backend/Generator/main.py so it clearly indicates both MP3 and WAV inputs are
supported, while still mentioning ffmpeg/libav for transcoding support where
needed. Keep the guidance user-facing and make it explicit that WAV users do not
need to convert their files first.
- Around line 25-28: The System Requirements section only mentions ffmpeg/libav,
but it should also call out the Python dependencies added elsewhere. Update the
README near the existing backend/extract_text_from_audio() guidance to
explicitly list pydub and SpeechRecognition as required packages, so users
installing from source know to install them alongside the system audio tools.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 27137517-77ad-4cb2-9f10-30b72ef57382
📒 Files selected for processing (5)
README.mdbackend/Generator/main.pyeduaid_web/src/pages/Text_Input.jsxextension/src/pages/text_input/TextInput.jsxrequirements.txt
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
backend/Generator/main.py (1)
383-409: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winSet a timeout on
Recognizerbeforerecognize_google.SpeechRecognition==3.14.5exposesr.operation_timeout; without it, the/uploadworker can block on stalled network requests.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/Generator/main.py` around lines 383 - 409, The recognizer in the audio transcription flow does not have a network timeout, so stalled Google recognition calls can block the /upload worker. Update the transcription loop in the code that creates sr.Recognizer and calls recognize_google to set r.operation_timeout before making requests, using a reasonable timeout value so each chunk transcription fails fast instead of hanging indefinitely.
♻️ Duplicate comments (2)
backend/server.py (1)
498-501: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winDo not return 400 for speech-service request failures.
RuntimeErrorcomes fromsr.RequestErrorinextract_text_from_audio, so this is an upstream/service failure rather than a bad upload. Return a retryable/server-side status separately fromValueError.Proposed status split
try: content = file_processor.process_file(file) - except (ValueError, RuntimeError) as e: + except ValueError as e: return jsonify({"error": str(e)}), 400 + except RuntimeError as e: + return jsonify({"error": str(e)}), 503🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/server.py` around lines 498 - 501, The error handling in the file processing flow currently treats both validation errors and speech-service failures the same in the try/except around file_processor.process_file. Split the handling in this block so ValueError still returns a client-side bad request, but RuntimeError from extract_text_from_audio/sr.RequestError is mapped to a separate retryable server-side status with an appropriate error payload. Keep the change localized to the processing endpoint and use the existing file_processor.process_file path as the reference point.backend/Generator/main.py (1)
426-432: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winMove
file.saveinside the cleanup scope.If
file.save(file_path)creates a partial file and then raises, thefinallyblock is never entered, leaving temp files inuploads/.Proposed cleanup-scope fix
temp_filename = f"{uuid.uuid4().hex}{ext}" file_path = os.path.join(self.upload_folder, temp_filename) - file.save(file_path) content = "" try: + file.save(file_path) if ext == '.txt':🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@backend/Generator/main.py` around lines 426 - 432, Move the file write in Generator.main’s upload handling so `file.save(file_path)` happens inside the existing try/finally cleanup scope, using the same `temp_filename`/`file_path` flow. This ensures that if `file.save` raises after creating a partial upload, the `finally` block still runs and removes the temp file from `self.upload_folder`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 188-190: The upload helper text in Text_Input should match the
actual formats accepted by handleFileUpload and the file input accept list.
Update the label near the file input to mention TXT and DOCX alongside PDF and
audio so users don’t think those options were removed, and keep the wording
consistent with the formats supported by the backend Generator flow.
---
Outside diff comments:
In `@backend/Generator/main.py`:
- Around line 383-409: The recognizer in the audio transcription flow does not
have a network timeout, so stalled Google recognition calls can block the
/upload worker. Update the transcription loop in the code that creates
sr.Recognizer and calls recognize_google to set r.operation_timeout before
making requests, using a reasonable timeout value so each chunk transcription
fails fast instead of hanging indefinitely.
---
Duplicate comments:
In `@backend/Generator/main.py`:
- Around line 426-432: Move the file write in Generator.main’s upload handling
so `file.save(file_path)` happens inside the existing try/finally cleanup scope,
using the same `temp_filename`/`file_path` flow. This ensures that if
`file.save` raises after creating a partial upload, the `finally` block still
runs and removes the temp file from `self.upload_folder`.
In `@backend/server.py`:
- Around line 498-501: The error handling in the file processing flow currently
treats both validation errors and speech-service failures the same in the
try/except around file_processor.process_file. Split the handling in this block
so ValueError still returns a client-side bad request, but RuntimeError from
extract_text_from_audio/sr.RequestError is mapped to a separate retryable
server-side status with an appropriate error payload. Keep the change localized
to the processing endpoint and use the existing file_processor.process_file path
as the reference point.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c86a3286-aa34-423a-b6d5-2dfec7bb2912
📒 Files selected for processing (5)
README.mdbackend/Generator/main.pybackend/server.pyeduaid_web/src/pages/Text_Input.jsxextension/src/pages/text_input/TextInput.jsx
✅ Files skipped from review due to trivial changes (1)
- README.md
🚧 Files skipped from review as they are similar to previous changes (1)
- extension/src/pages/text_input/TextInput.jsx
…r helper text updates
|
I would really appreciate it if maintainers could review these changes when you have a moment! Thank you. |
Addressed Issues:
Fixes #378
Screenshots/Recordings:
N/A (This is a backend functionality addition implementing
.mp3and.wavtranscription, with accompanying text prompt updates on the frontend pages).Additional Notes:
This PR implements audio upload support (
.wavand.mp3) for quiz generation:pydubto convert.mp3uploads into.wavaudio.SpeechRecognition.recognize_google).uuid.uuid4().hex) prefix, preventing filename collisions across concurrent uploads.try...finallyblock to ensure all temporary chunk files and converted WAV intermediates are immediately deleted from disk after processing.UnknownValueErrorby appending[Unintelligible]to the transcription, and chains connection errors (RequestError) into a standardRuntimeError.PDF, MP3 supportedtoPDF, Audio supportedin both the React Web client and the Chrome extension.README.mdhighlighting the system requirement forffmpeg/libavon the system'sPATH.AI Usage Disclosure:
Check one of the checkboxes below:
I have used the following AI models and tools: Pair programming with the Antigravity AI coding assistant to design the concurrency safety mechanisms, draft clean-up logic, and build/run isolated mock unit tests.
Checklist
Summary by CodeRabbit