File size: 5,290 Bytes
4f4c866 b568931 4f4c866 8302cb3 4f4c866 8302cb3 4f4c866 b568931 4f4c866 b568931 4f4c866 b568931 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | 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."} |