-
Notifications
You must be signed in to change notification settings - Fork 30
Add Voice Reporting and Vandalism Detection #294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a5bdfc7
b3e3ff1
fb307fc
a2b2cfd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,11 +4,11 @@ | |||||||||||
| from fastapi.middleware.gzip import GZipMiddleware | ||||||||||||
| from fastapi.concurrency import run_in_threadpool | ||||||||||||
| from sqlalchemy import func | ||||||||||||
| from sqlalchemy.orm import Session, defer | ||||||||||||
| from sqlalchemy.orm import Session, defer, joinedload | ||||||||||||
| from pydantic import BaseModel | ||||||||||||
| from contextlib import asynccontextmanager | ||||||||||||
| from functools import lru_cache | ||||||||||||
| from typing import List, Union, Any, Dict | ||||||||||||
| from typing import List, Union, Any, Dict, Optional | ||||||||||||
| from datetime import datetime, timedelta, timezone | ||||||||||||
| from PIL import Image | ||||||||||||
|
|
||||||||||||
|
|
@@ -79,7 +79,8 @@ | |||||||||||
| detect_water_leak_clip, | ||||||||||||
| detect_accessibility_issue_clip, | ||||||||||||
| detect_crowd_density_clip, | ||||||||||||
| detect_audio_event | ||||||||||||
| detect_audio_event, | ||||||||||||
| transcribe_audio | ||||||||||||
| ) | ||||||||||||
|
|
||||||||||||
| # Configure structured logging | ||||||||||||
|
|
@@ -1409,6 +1410,27 @@ async def detect_audio_endpoint(request: Request, file: UploadFile = File(...)): | |||||||||||
| raise HTTPException(status_code=500, detail="Internal server error") | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| @app.post("/api/transcribe-audio") | ||||||||||||
| async def transcribe_audio_endpoint(request: Request, file: UploadFile = File(...)): | ||||||||||||
| # Basic audio validation | ||||||||||||
| if hasattr(file, 'size') and file.size and file.size > 25 * 1024 * 1024: | ||||||||||||
| raise HTTPException(status_code=413, detail="Audio file too large (max 25MB)") | ||||||||||||
|
|
||||||||||||
| try: | ||||||||||||
| audio_bytes = await file.read() | ||||||||||||
|
||||||||||||
| audio_bytes = await file.read() | |
| audio_bytes = await file.read() | |
| # Enforce size limit based on actual bytes read, in case file.size is missing or inaccurate | |
| if len(audio_bytes) > 25 * 1024 * 1024: | |
| raise HTTPException(status_code=413, detail="Audio file too large (max 25MB)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enforce size limit based on actual bytes, not just file.size.
UploadFile.size can be unset, so large uploads can bypass the 25MB gate. Add a post‑read length check (and optionally reject empty audio) to prevent oversized uploads from slipping through.
🛡️ Proposed fix (post‑read size validation)
- try:
- audio_bytes = await file.read()
- except Exception as e:
- logger.error(f"Invalid audio file: {e}", exc_info=True)
- raise HTTPException(status_code=400, detail="Invalid audio file")
+ try:
+ audio_bytes = await file.read()
+ except Exception as e:
+ logger.error(f"Invalid audio file: {e}", exc_info=True)
+ raise HTTPException(status_code=400, detail="Invalid audio file")
+
+ if len(audio_bytes) > 25 * 1024 * 1024:
+ raise HTTPException(status_code=413, detail="Audio file too large (max 25MB)")
+ if len(audio_bytes) == 0:
+ raise HTTPException(status_code=400, detail="Empty audio file")🧰 Tools
🪛 Ruff (0.14.14)
[warning] 1414-1414: Do not perform function call File in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
[warning] 1423-1423: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
[warning] 1428-1428: Consider moving this statement to an else block
(TRY300)
[warning] 1431-1431: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
🤖 Prompt for AI Agents
In `@backend/main.py` around lines 1413 - 1432, transcribe_audio_endpoint
currently trusts UploadFile.size which may be unset; fix by validating the
actual byte length after reading: in transcribe_audio_endpoint read audio_bytes
= await file.read(), then if not audio_bytes raise HTTPException(400, "Empty
audio file") and if len(audio_bytes) > 25 * 1024 * 1024 raise HTTPException(413,
"Audio file too large (max 25MB)"); proceed to call
transcribe_audio(client=client, audio_bytes=audio_bytes) only after these checks
and keep existing exception logging for read/transcription errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Propagate transcription failures instead of returning empty text.
On non‑200 or exceptions, returning
""makes the endpoint respond 200 with an empty transcript, so the UI can’t distinguish silence from failure. Prefer raising (or returning explicit error details) so callers can surface a real error.🔧 Proposed fix (propagate failures)
🧰 Tools
🪛 Ruff (0.14.14)
[warning] 195-195: Do not catch blind exception:
Exception(BLE001)
[warning] 196-196: Use
logging.exceptioninstead oflogging.errorReplace with
exception(TRY400)
🤖 Prompt for AI Agents