Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions src/audio-transcription/audio_transcription/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import logging
from typing import TypedDict

from pathlib import Path
from pydantic import DirectoryPath, field_validator
import typer
from rb.api.models import (
BatchTextResponse,
Expand All @@ -19,7 +21,7 @@
logger = logging.getLogger(__name__)

logging.basicConfig(
level=logging.INFO,
level=logging.DEBUG,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)

Expand All @@ -35,9 +37,40 @@

model = AudioTranscriptionModel()

AUDIO_EXTENSIONS = {".mp3", ".wav", ".flac", ".aac"}


class AudioDirectory(DirectoryInput):
path: DirectoryPath

@field_validator("path")
@classmethod
def validate_directory(cls, v):
path = Path(v)

if not path.exists():
raise ValueError(f"validate audio directory: '{v}' does not exist.")
if not path.is_dir():
raise ValueError(
f"validate audio directory: Path '{v}' is not a directory."
)

audio_files = list(path.glob("*"))
if not audio_files:
raise ValueError(f"validate audio directory: Directory {v} is empty.")

no_audio = [f.name for f in audio_files if f.suffix.lower() in AUDIO_EXTENSIONS]

if len(no_audio) < 1:
raise ValueError(
f"validate audio directory: No-audio files found in directory: {v}"
)

return v


class AudioInput(TypedDict):
input_dir: DirectoryInput
input_dir: AudioDirectory


def task_schema() -> TaskSchema:
Expand Down
17 changes: 16 additions & 1 deletion src/rb-api/rb/api/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import multiprocessing
import os
import sys
from fastapi import FastAPI
from fastapi import FastAPI, HTTPException, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.staticfiles import StaticFiles
from rb.api import routes

Expand All @@ -21,6 +22,20 @@
name="static",
)


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError): # fmt: skip
"""response handler for all plugin input validation errors"""
error_msg = str(exc)
for e in exc.errors():
error_msg = e.get("msg")

raise HTTPException( # pylint: disable=raise-missing-from
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail={"error": f"{error_msg}"},
)


app.include_router(routes.probes_router, prefix="/probes")
app.include_router(routes.cli_to_api_router)
app.include_router(routes.ui_router)
Expand Down
9 changes: 5 additions & 4 deletions src/rb-api/rb/api/routes/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Callable, Generator, Optional

import typer
from fastapi import APIRouter, HTTPException, Response
from fastapi import APIRouter, HTTPException, Response, status
from fastapi.responses import StreamingResponse
from makefun import with_signature
from pydantic import BaseModel
Expand Down Expand Up @@ -68,10 +68,11 @@ def static_endpoint(callback: Callable, *args, **kwargs) -> ResponseBody:
# this has an issue of nor sending back details to desktop ui the api caller ?
raise ValueError(f"Invalid return type from Typer command: {type(result)}")
except Exception as e:
logger.error("Error executing CLI command: %s", e)
# response handler for all plugin runtime errors
logger.error("Error: %s %s", e, stdout)
raise HTTPException( # pylint: disable=raise-missing-from
status_code=400,
detail={"error": f"Typer CLI aborted {e}", "stdout": stdout[-10:]},
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail={"error": f"{e}"},
)


Expand Down
4 changes: 2 additions & 2 deletions src/rb-lib/rb/lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def ensure_ml_func_hinting_and_task_schemas_are_valid(
input_type_hint is FileInput
), f"For key {key}, the input type is NewFileInputType, but the TypeDict hint is {input_type_hint}. Change to FileInput."
case InputType.DIRECTORY:
assert (
input_type_hint is DirectoryInput
assert issubclass(
input_type_hint, DirectoryInput
), f"For key {key}, the input type is InputType.DIRECTORY, but the TypeDict hint is {input_type_hint}. Change to DirectoryInput."
case InputType.TEXT:
assert (
Expand Down