speech / speech_server.py
Haswanth Raj
Update speech_server.py
8302cb3 verified
Raw
History Blame Contribute Delete
5.29 kB
import subprocess
import time
import os
from wit import Wit
import random
import json
from fastapi import FastAPI, Request, HTTPException
import logging
import threading
from mutagen.mp3 import MP3
logging.basicConfig(filename='WebServer.log', filemode='w', level=logging.DEBUG)
# System updated for Hugging Face container environment
platform = "Linux"
# --- CHANGED SECTION ---
# Fetch the Wit.ai API Key(s) from Hugging Face Secrets
# If using multiple keys, separate them with commas in the Secret (e.g., KEY1,KEY2)
env_keys = os.getenv("WIT_API_KEY", "")
api_keys = [key.strip() for key in env_keys.split(",")] if env_keys else []
if not api_keys or not api_keys[0]:
print("WARNING: WIT_API_KEY Secret is not set in Hugging Face!")
# ----------------------
wit_api = {}
resp = {}
for api_key in api_keys:
wit_api[api_key] = Wit(api_key)
# Environment setup using a safe container directory (/tmp)
base_dir = "/tmp/SpeechRecognition"
if platform == "Linux":
try:
if not os.path.exists(base_dir):
os.makedirs(f"{base_dir}/Cache", exist_ok=True)
os.chdir(base_dir)
else:
os.chdir(base_dir)
except Exception as e:
print(f"Error setting up directory: {e}")
app = FastAPI()
# Replace your current @app.get('/') with this:
@app.get('/')
def index(request: Request):
return {
"status": "online",
"message": "Speech server is running. Send a .webm audio file via POST to /speech"
}
@app.post('/speech')
async def process(request: Request):
start_execution = time.time()
# Request Processing
data_length = str(round(float(int(request.headers.get('content-length', 0)) / 1024),2))
random_hash = random.randint(10000000000,99999999999)
if float(data_length) > 500:
print('The incoming speech request has exceeded the 500KB limit established by the Developer, Size: ' + str(data_length) + "KB")
return
print("[" + str(random_hash) + "] Speech request received from " + request.client.host + " | " + " Size of incoming data: " + data_length + "KB.")
logging.info("[" + str(random_hash) + "] Speech request received from " + request.client.host + " | " + " Size of incoming data: " + data_length + "KB.")
webm = await request.body()
logging.debug("[" + str(random_hash) + "] .webm obtained from the Body request.")
# File Writing
with open("Cache/" + str(random_hash) + ".webm", "wb") as file:
file.write(webm)
file.close()
logging.debug("[" + str(random_hash) + "] .webm written to file " + str(random_hash) + ".webm")
# File Conversion
logging.debug("[" + str(random_hash) + "] Starting conversion .webm to .mp3")
start_time = time.time()
if platform == "Linux":
convert = subprocess.Popen([
"ffmpeg", "-i", f"{base_dir}/Cache/{random_hash}.webm",
"-af", "silenceremove=stop_periods=-1:stop_duration=0.02:stop_threshold=-53dB",
"-vn", "-ac", "1", "-b:a", "64k", f"{base_dir}/Cache/{random_hash}.mp3"
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
convert.wait()
logging.debug("[" + str(random_hash) + "] Conversion finished, time " + str(round(float((time.time() - start_time) * 1000),2)) + " msec")
# File Open
with open("Cache/" + str(random_hash) + ".mp3", "rb") as file:
audio_read = file.read()
file.close()
# Audio Length
length = 0
try:
audio = MP3("Cache/" + str(random_hash) + ".mp3")
length = audio.info.length
except:
print("Error reading Audio")
start_req = time.time()
# Failsafe if no API keys are loaded
if not api_keys:
return {"error": "API keys not configured on server."}
random_api_key = random.choice(api_keys)
# Req to Wit.Ai
try:
resp[random_hash] = wit_api[random_api_key].speech(audio_read, {'Content-Type': 'audio/mpeg3'})
logging.debug("[" + str(random_hash) + "] .mp3 sent to Wit.Ai | Request to Wit.Ai completed in " + str(round(float((time.time() - start_req) * 1000),2)) + " msec | Audio Length: " + str(round(float(length),2)) + "s")
print("[" + str(random_hash) + "] .mp3 sent to Wit.Ai | Request to Wit.Ai completed in " + str(round(float((time.time() - start_req) * 1000),2)) + " msec | Audio Length: " + str(round(float(length),2)) + "s")
print("[" + str(random_hash) + "] Recognized text ", resp[random_hash])
except Exception as e:
logging.debug(e)
logging.info("[" + str(random_hash) + "] Unable to make request, manual check required.")
# Clean-up
def RemoveEnvironment(random_hash):
try:
os.remove("Cache/" + str(random_hash) + ".webm")
os.remove("Cache/" + str(random_hash) + ".mp3")
logging.debug("[" + str(random_hash) + "] Cleaned up environment.")
except:
logging.debug("[" + str(random_hash) + "] Unable to clean environment.")
threading.Thread(target=RemoveEnvironment, args=[random_hash]).start()
print("[" + str(random_hash) + "] Speech request completed for " + request.client.host)
logging.info("[" + str(random_hash) + "] Speech request completed for " + request.client.host)
logging.info("[" + str(random_hash) + "] Request completed in " + str(round(float((time.time() - start_execution) * 1000),2)) + " msec")
try:
print("[" + str(random_hash) + "] Answer from Wit.Ai API: " + resp[random_hash]['text'])
return resp[random_hash]['text']
except KeyError:
return {"error": "Could not recognize speech or invalid Wit.ai response."}