Skip to content

Commit

Permalink
raise validation error if source file is invalid
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandogrd committed Dec 7, 2022
1 parent 17766f8 commit 5bc1cca
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
19 changes: 19 additions & 0 deletions maestro_worker_python/convert_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from dataclasses import dataclass
from typing import List
from subprocess import check_call
from .response import ValidationError

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -45,6 +46,24 @@ def _run_subprocess(command):
try:
process = subprocess.run(command, shell=True, capture_output=True, check=True)
except subprocess.CalledProcessError as exc:
if "Invalid data found when processing input" in exc.stderr.decode():
logger.warning(
f"Could not convert file because of invalid data",
extra={'props': {'stderr': exc.stderr.decode(), 'stdout': exc.stdout.decode()}}
)
raise ValidationError(
f"Could not convert file because of invalid data: {exc.stderr.decode()}"
) from exc

if "Output file #0 does not contain any stream" in exc.stderr.decode():
logger.warning(
f"Could not convert file because it has no audio data",
extra={'props': {'stderr': exc.stderr.decode(), 'stdout': exc.stdout.decode()}}
)
raise ValidationError(
f"Could not convert file because it has no audio data: {exc.stderr.decode()}"
) from exc

logger.error(
f"Fatal error during conversion",
extra={'props': {'stderr': exc.stderr.decode(), 'stdout': exc.stdout.decode()}}
Expand Down
2 changes: 1 addition & 1 deletion maestro_worker_python/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ async def internal_exception_handler(request: Request, exc: Exception):

@app.exception_handler(ValidationError)
async def validation_error_handler(request: Request, exc: ValidationError):
return JSONResponse(status_code=200, content=jsonable_encoder({"error": exc.reason}))
return JSONResponse(status_code=400, content=jsonable_encoder({"error": exc.reason}))


@app.post("/inference", response_model=WorkerResponse)
Expand Down
38 changes: 35 additions & 3 deletions tests/test_convert_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
import subprocess
from pathlib import Path
from maestro_worker_python.convert_files import convert_files, FileToConvert
from maestro_worker_python.response import ValidationError


TEST_PATH = Path(__file__).resolve().parent


@pytest.fixture(scope="session")
def invalid_audio_file(tmp_path_factory):
fn = tmp_path_factory.mktemp("data") / "invalid_audio.mp3"
fn.write_bytes(b"invalid")
fn = tmp_path_factory.mktemp("data") / "invalid_audio.mov"
fn.write_bytes(b"")
return fn


Expand All @@ -20,7 +21,7 @@ def test_should_re_raise_exceptions_in_thread(invalid_audio_file, file_format, c
with pytest.raises(subprocess.CalledProcessError) as exc:
convert_files(
[FileToConvert(
input_file_path=invalid_audio_file,
input_file_path=TEST_PATH / "foobar.mp3",
output_file_path=f"{invalid_audio_file}.wav",
file_format=file_format,
)]
Expand All @@ -30,6 +31,37 @@ def test_should_re_raise_exceptions_in_thread(invalid_audio_file, file_format, c
assert caplog.records[0].message == "Fatal error during conversion"


@pytest.mark.parametrize("file_format", ["m4a", "wav"])
def test_should_raise_validation_error_if_audio_file_is_invalid(invalid_audio_file, file_format, caplog):
with pytest.raises(ValidationError) as exc:
convert_files(
[FileToConvert(
input_file_path=invalid_audio_file,
output_file_path=f"{invalid_audio_file}.wav",
file_format=file_format,
)]
)

assert "Could not convert file because of invalid data" in str(exc.value)
#assert caplog.records[0].levelname == "WARNING"
#assert caplog.records[0].message == "foobar"


@pytest.mark.parametrize("file_format", ["m4a", "wav"])
def test_should_raise_validation_error_if_source_has_no_audio(file_format, caplog):
input_file_path, output_file_path = TEST_PATH / "video-no-audio.mp4", TEST_PATH / "output.wav"
with pytest.raises(ValidationError) as exc:
convert_files(
[FileToConvert(
input_file_path=input_file_path,
output_file_path=output_file_path,
file_format=file_format,
)]
)

assert "Could not convert file because it has no audio data" in str(exc.value)


def test_should_convert_valid_audio_file():
input_file_path, output_file_path = TEST_PATH / "silent.ogg", TEST_PATH / "silent.wav"
convert_files(
Expand Down
Binary file added tests/video-no-audio.mp4
Binary file not shown.

0 comments on commit 5bc1cca

Please sign in to comment.