Files
voice_bridge/app.py
Sam Rolfe de9b06a3d1 Sync live code; move MQTT credentials out of source; untrack venv/
- mqtt_audio_bridge.py: MQTT_USER / MQTT_PASS are read from the environment,
  falling back to ~/.config/environment.d/10-secrets.conf (mode 600). The
  environment.d trap means a fresh SSH shell needs the file fallback.
- docker-compose.yml: pass MQTT_USER / MQTT_PASS through; keeps the live
  network_mode / Dockerfile topology.
- start_bridge.sh: launcher that sources the secrets file before compose up.
- app.py: commits the live initial_prompt that was uncommitted.
- .gitignore: add venv/ (was missing), __pycache__, *.bak*, *.wav.
- git rm -r --cached venv/: 13,413 tracked venv files removed from the index.

Credential note: MQTT_PASS was hardcoded in edaf914. origin/main was later
force-rewritten to redact it, but the value was exposed and must still be
rotated. Removing venv/ from the index does not shrink the repository: the
objects stay in history until a history rewrite and GC.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-07 18:10:51 +11:00

51 lines
1.6 KiB
Python

from flask import Flask, request, jsonify
from faster_whisper import WhisperModel
import os
import tempfile
app = Flask(__name__)
# Load Model
model_size = "small.en"
model = WhisperModel(model_size, device="cpu", compute_type="int8")
@app.route('/transcribe', methods=['POST'])
def transcribe_audio():
if 'audio' not in request.files:
return jsonify({"error": "No audio file provided"}), 400
audio_file = request.files['audio']
temp_file_path = None # Initialize variable
# Save file
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp_audio:
audio_file.save(tmp_audio.name)
temp_file_path = tmp_audio.name
try:
# Now we can safely use temp_file_path
initial_prompt = (
"Jervis, feed the fish, turn on the lights, turn off the lights, "
"shopping list, add to the shopping list, calendar, weather, time, "
"remind me, heater, watering the plants, play music, stop"
)
segments, info = model.transcribe(
temp_file_path,
beam_size=5,
language="en",
initial_prompt=initial_prompt,
)
transcript = " ".join([segment.text for segment in segments])
print(f"Transcript: {transcript}")
return jsonify({"transcript": transcript})
except Exception as e:
print(f"Error: {e}")
return jsonify({"error": str(e)}), 500
finally:
# Cleanup
if temp_file_path and os.path.exists(temp_file_path):
os.remove(temp_file_path)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)