Download speech_server.py from lone17k/speech: direct link, hf CLI and curl.
- Browser
- Download file 5.29 kB
-
https://huggingface.co/spaces/lone17k/speech/resolve/main/speech_server.py
- Command line
-
hf download hf://spaces/lone17k/speech/speech_server.py
-
curl -L -o speech_server.py https://huggingface.co/spaces/lone17k/speech/resolve/main/speech_server.py
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: | |
| def index(request: Request): | |
| return { | |
| "status": "online", | |
| "message": "Speech server is running. Send a .webm audio file via POST to /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."} |