add all
This commit is contained in:
commit
0255257a1a
1
.env.example
Normal file
1
.env.example
Normal file
@ -0,0 +1 @@
|
|||||||
|
TRITON_URL=****
|
||||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/data
|
||||||
|
.venv
|
||||||
|
__pycache__
|
||||||
23
Dockerfile
Normal file
23
Dockerfile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive \
|
||||||
|
PYTHONUNBUFFERED=1 \
|
||||||
|
PYTHONDONTWRITEBYTECODE=1
|
||||||
|
|
||||||
|
# Copy requirements file
|
||||||
|
COPY requirements.txt /app/requirements.txt
|
||||||
|
|
||||||
|
# Install requirements
|
||||||
|
RUN pip install --no-deps git+https://git.d.aiengines.ir/bi/asr_triton_client.git@05c8f7a88d3ff41d82591b6beb41bab86d81d421
|
||||||
|
RUN pip install --no-cache-dir -r /app/requirements.txt
|
||||||
|
|
||||||
|
# Set working directory and copy app
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . /app
|
||||||
|
|
||||||
|
# Expose necessary ports
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Command to run the script
|
||||||
|
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
27
README.md
Normal file
27
README.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
## ASR SERVICE
|
||||||
|
|
||||||
|
### A FASTAPI client for receieving audio data from font and sending audio to a Triton ASR service using SSE or WebSocket streaming. It yields real-time transcription results as JSON-like events.
|
||||||
|
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
|
||||||
|
### SET ENVIRONMENT
|
||||||
|
|
||||||
|
1-create a file .env and set TRITON_URL
|
||||||
|
|
||||||
|
### 1-DEVELOPMENT
|
||||||
|
#### Run the system : Uvicorn and Fastapi
|
||||||
|
.venv/bin/uvicorn src.main:app --host 0.0.0.0 --port 8000
|
||||||
|
|
||||||
|
### 2-DEPLOYMENT
|
||||||
|
#### Docker Build
|
||||||
|
docker build -t asr_client:latest --build-arg DEBIAN_FRONTEND=noninteractive .
|
||||||
|
|
||||||
|
|
||||||
|
#### Docker Run
|
||||||
|
docker run -d --gpus all --network host --restart unless-stopped asr_client:latest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
there was a problem in installing ast_client package :
|
||||||
|
pip couldnot find a versaion for perf-analyzer==2.59.1 : so i removed it
|
||||||
7
config/base.py
Normal file
7
config/base.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from dotenv import load_dotenv
|
||||||
|
import os
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
TRITON_URL = os.getenv("TRITON_URL")
|
||||||
|
MIN_CHUNK_SIZE = 90000
|
||||||
30
requirements.txt
Normal file
30
requirements.txt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
fastapi==0.116.1
|
||||||
|
uvicorn==0.35.0
|
||||||
|
aiohappyeyeballs==2.6.1
|
||||||
|
aiohttp==3.13.0
|
||||||
|
aiosignal==1.4.0
|
||||||
|
async-timeout==5.0.1
|
||||||
|
attrs==25.4.0
|
||||||
|
Brotli==1.1.0
|
||||||
|
certifi==2025.10.5
|
||||||
|
frozenlist==1.8.0
|
||||||
|
gevent==25.9.1
|
||||||
|
geventhttpclient==2.3.4
|
||||||
|
greenlet==3.2.4
|
||||||
|
grpcio==1.67.1
|
||||||
|
idna==3.11
|
||||||
|
multidict==6.7.0
|
||||||
|
numpy==2.2.6
|
||||||
|
packaging==25.0
|
||||||
|
propcache==0.4.1
|
||||||
|
protobuf==5.29.5
|
||||||
|
pydub==0.25.1
|
||||||
|
python-dotenv==1.1.1
|
||||||
|
python-rapidjson==1.21
|
||||||
|
tritonclient==2.61.0
|
||||||
|
typing_extensions==4.15.0
|
||||||
|
urllib3==2.5.0
|
||||||
|
websockets==15.0.1
|
||||||
|
yarl==1.22.0
|
||||||
|
zope.event==6.0
|
||||||
|
zope.interface==8.0.1
|
||||||
30
src/main.py
Normal file
30
src/main.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
from fastapi import FastAPI, WebSocket
|
||||||
|
import asyncio
|
||||||
|
from asr.service import TritonGrpcClient
|
||||||
|
import json
|
||||||
|
|
||||||
|
from config.base import TRITON_URL, MIN_CHUNK_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
client = TritonGrpcClient(TRITON_URL)
|
||||||
|
|
||||||
|
|
||||||
|
@app.websocket("/asr")
|
||||||
|
async def websocket_endpoint(ws: WebSocket):
|
||||||
|
print("Starting ASR service")
|
||||||
|
await ws.accept()
|
||||||
|
|
||||||
|
audio_buffer = bytearray()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
data = await ws.receive_bytes()
|
||||||
|
audio_buffer.extend(data)
|
||||||
|
|
||||||
|
async for s in client.event_stream_from_bytes(raw=bytes(audio_buffer), filename="stream.webm"):
|
||||||
|
await ws.send_text(json.dumps(s, ensure_ascii=False))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("WebSocket error:", e)
|
||||||
|
await ws.close()
|
||||||
16
test/test.js
Normal file
16
test/test.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
const ws = new WebSocket("ws://localhost:8000/asr");
|
||||||
|
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
console.log("ASR Result:", event.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
async function startStreaming() {
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
|
const recorder = new MediaRecorder(stream, { mimeType: "audio/webm" });
|
||||||
|
|
||||||
|
recorder.ondataavailable = (event) => {
|
||||||
|
ws.send(event.data); // send audio chunks to backend
|
||||||
|
};
|
||||||
|
|
||||||
|
recorder.start(500); // send audio every 250 ms
|
||||||
|
}
|
||||||
27
test/test.py
Normal file
27
test/test.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import asyncio
|
||||||
|
import websockets
|
||||||
|
import json
|
||||||
|
|
||||||
|
AUDIO_FILE = "./khabar_1_5.wav" # Replace with your audio file path
|
||||||
|
WS_URL = "ws://127.0.0.1:8000/asr"
|
||||||
|
|
||||||
|
async def send_audio():
|
||||||
|
async with websockets.connect(WS_URL) as ws:
|
||||||
|
print("Connected to ASR WebSocket")
|
||||||
|
|
||||||
|
# Read the audio file in chunks
|
||||||
|
with open(AUDIO_FILE, "rb") as f:
|
||||||
|
chunk_size = 21920
|
||||||
|
while chunk := f.read(chunk_size):
|
||||||
|
await ws.send(chunk)
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
message = await ws.recv()
|
||||||
|
data = json.loads(message)
|
||||||
|
print("Received:", data)
|
||||||
|
except websockets.exceptions.ConnectionClosed:
|
||||||
|
print("WebSocket closed by server")
|
||||||
|
|
||||||
|
# Run the async client
|
||||||
|
asyncio.run(send_audio())
|
||||||
Loading…
x
Reference in New Issue
Block a user