add logging config to audio server
add audio client change delimiter for mcp tools from "::" to ":" to save tokens
This commit is contained in:
@@ -16,4 +16,4 @@ RUN apt -y install ffmpeg
|
||||
WORKDIR /app
|
||||
|
||||
EXPOSE 8000
|
||||
CMD ["uvicorn", "audio_server:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
CMD ["uvicorn", "audio_server:app", "--host", "0.0.0.0", "--port", "8000", "--log-config", "logging_config.yaml"]
|
||||
@@ -0,0 +1,42 @@
|
||||
version: 1
|
||||
disable_existing_logger: false
|
||||
formatters:
|
||||
main:
|
||||
format: "\x1b[1;32m%(name)s \x1b[0m- %(levelname)s - %(message)s"
|
||||
default:
|
||||
format: "\x1b[1;93m%(name)s \x1b[0m- %(levelname)s - %(message)s"
|
||||
use_colors: yes
|
||||
handlers:
|
||||
main:
|
||||
formatter: main
|
||||
class: logging.StreamHandler
|
||||
stream: ext://sys.stdout
|
||||
default:
|
||||
formatter: default
|
||||
class: logging.StreamHandler
|
||||
stream: ext://sys.stdout
|
||||
access:
|
||||
formatter: default
|
||||
class: logging.StreamHandler
|
||||
stream: ext://sys.stdout
|
||||
loggers:
|
||||
audio_server:
|
||||
level: INFO
|
||||
handlers:
|
||||
- main
|
||||
propagate: no
|
||||
uvicorn.error:
|
||||
level: INFO
|
||||
handlers:
|
||||
- default
|
||||
propagate: no
|
||||
uvicorn.access:
|
||||
level: INFO
|
||||
handlers:
|
||||
- default
|
||||
propagate: no
|
||||
root:
|
||||
level: INFO
|
||||
handlers:
|
||||
- default
|
||||
propagate: no
|
||||
@@ -5,4 +5,5 @@ uvicorn~=0.44.0
|
||||
starlette~=1.0.0
|
||||
python-multipart~=0.0.24
|
||||
aiofiles~=25.1.0
|
||||
piper-tts~=1.4.2
|
||||
piper-tts~=1.4.2
|
||||
PyYAML~=6.0.3
|
||||
@@ -5,13 +5,14 @@ from wave import Wave_write
|
||||
from pathlib import Path
|
||||
|
||||
import aiofiles
|
||||
from piper import PiperVoice, SynthesisConfig
|
||||
from piper import PiperVoice
|
||||
from piper.download_voices import download_voice
|
||||
import psutil
|
||||
from fastapi import FastAPI, UploadFile
|
||||
from fastapi import FastAPI, UploadFile, HTTPException
|
||||
import whisper
|
||||
from pydantic import BaseModel
|
||||
from fastapi.responses import FileResponse, JSONResponse
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
from .models import TranscriptionResponse, VoiceRequest, StatusResponse
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@@ -28,26 +29,28 @@ download_voice(piper_model_name, piper_path)
|
||||
temporary_audio_path = Path("temporary_audio")
|
||||
temporary_audio_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger = logging.getLogger("audio_server")
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def index():
|
||||
return {
|
||||
"memory_usage": psutil.Process(os.getpid()).memory_info().rss,
|
||||
"piper_model": piper_model_name,
|
||||
"whisper_model": whisper_model_name,
|
||||
}
|
||||
async def index() -> StatusResponse:
|
||||
return StatusResponse(memory_usage=psutil.Process(os.getpid()).memory_info().rss, piper_model=piper_model_name,
|
||||
whisper_model=whisper_model_name)
|
||||
|
||||
|
||||
@app.get("/transcribe")
|
||||
async def transcribe(audio_file: UploadFile):
|
||||
async def transcribe(audio_file: UploadFile) -> TranscriptionResponse:
|
||||
file_extensions = {
|
||||
"audio/wav": "wav",
|
||||
"audio/wave": "wav",
|
||||
"audio/mpeg": "mp3",
|
||||
}
|
||||
|
||||
if audio_file.content_type not in file_extensions.keys():
|
||||
logger.error("%s is not supported", audio_file.content_type)
|
||||
return JSONResponse({"detail": "wrong file type"}, status_code=400)
|
||||
print("CONTENT TYPE:")
|
||||
print(audio_file.content_type)
|
||||
raise HTTPException(status_code=400, detail="file type not supported")
|
||||
|
||||
file_path = temporary_audio_path / f"{uuid.uuid4()}.{file_extensions[audio_file.content_type]}"
|
||||
|
||||
@@ -58,14 +61,11 @@ async def transcribe(audio_file: UploadFile):
|
||||
# noinspection PyArgumentList
|
||||
transcription = whisper_model.transcribe(file_path.as_posix())
|
||||
|
||||
return JSONResponse(transcription)
|
||||
return TranscriptionResponse.model_validate(transcription)
|
||||
|
||||
class VoiceRequest(BaseModel):
|
||||
text: str
|
||||
config: SynthesisConfig | None
|
||||
|
||||
@app.get("/tts")
|
||||
async def tts(voice_request: VoiceRequest):
|
||||
async def tts(voice_request: VoiceRequest) -> FileResponse:
|
||||
voice = PiperVoice.load(piper_path / f"{piper_model_name}.onnx")
|
||||
|
||||
audio_file_path = temporary_audio_path / f"{uuid.uuid4()}.wav"
|
||||
@@ -73,4 +73,4 @@ async def tts(voice_request: VoiceRequest):
|
||||
with Wave_write(audio_file_path.as_posix()) as writer:
|
||||
voice.synthesize_wav(voice_request.text, writer, syn_config=voice_request.config)
|
||||
|
||||
return FileResponse(audio_file_path, media_type="audio/wav")
|
||||
return FileResponse(audio_file_path, media_type="audio/wav")
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
from piper import SynthesisConfig
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class StatusResponse(BaseModel):
|
||||
memory_usage: int
|
||||
piper_model: str
|
||||
whisper_model: str
|
||||
|
||||
|
||||
# noinspection SpellCheckingInspection
|
||||
class TranscriptionSegment(BaseModel):
|
||||
id: int
|
||||
seek: int
|
||||
start: float
|
||||
end: float
|
||||
text: str
|
||||
tokens: list[int]
|
||||
temperature: float
|
||||
avg_logprob: float
|
||||
compression_ratio: float
|
||||
no_speech_prob: float
|
||||
|
||||
class TranscriptionResponse(BaseModel):
|
||||
text: str
|
||||
segments: list[TranscriptionSegment]
|
||||
language: str
|
||||
|
||||
|
||||
class VoiceRequest(BaseModel):
|
||||
text: str
|
||||
config: SynthesisConfig | None
|
||||
Reference in New Issue
Block a user