Eyob-Sol's picture
Update app.py
b8510d4 verified
# app.py
from app.gradio_app import build_demo
from models.tts_router import cleanup_old_audio
import os
import shutil
import stat
import huggingface_hub
from shutil import which
# -----------------------------
# Model: ensure GGUF is present
# -----------------------------
def ensure_model() -> str:
"""
Download the GGUF model into ./models if not already present.
Requires in environment:
- LLAMACPP_MODEL_PATH (target path including filename)
- HF_MODEL_REPO (e.g. Qwen/Qwen2.5-1.5B-Instruct-GGUF)
- HF_MODEL_FILE (e.g. qwen2.5-1.5b-instruct-q4_k_m.gguf)
"""
model_path = os.getenv("LLAMACPP_MODEL_PATH")
repo_id = os.getenv("HF_MODEL_REPO")
filename = os.getenv("HF_MODEL_FILE") or (os.path.basename(model_path) if model_path else None)
if not model_path or not repo_id or not filename:
raise RuntimeError("Missing config: set LLAMACPP_MODEL_PATH and HF_MODEL_REPO (optionally HF_MODEL_FILE).")
if os.path.exists(model_path):
print(f"[MODEL] Found existing model at {model_path}")
return model_path
os.makedirs(os.path.dirname(model_path), exist_ok=True)
print(f"[MODEL] Downloading {filename} from {repo_id} …")
local_path = huggingface_hub.hf_hub_download(
repo_id=repo_id,
filename=filename,
local_dir=os.path.dirname(model_path),
local_dir_use_symlinks=False,
)
# If hf_hub_download wrote elsewhere (cache), move/rename into desired path
if os.path.abspath(local_path) != os.path.abspath(model_path):
shutil.copyfile(local_path, model_path)
print(f"[MODEL] Ready at {model_path}")
return model_path
def _ensure_exec(fp: str):
if fp and os.path.exists(fp):
try:
os.chmod(fp, 0o755)
except Exception as e:
print("[WARN] chmod failed for", fp, e)
def log_env_for_audio():
print("[ENV] TTS_ENGINE =", os.getenv("TTS_ENGINE", "(unset)"))
print("[ENV] PIPER_MODEL=", os.getenv("PIPER_MODEL", "(unset)"))
print("[ENV] PIPER_BIN =", os.getenv("PIPER_BIN", "(unset)"))
import os, stat
def ensure_piper_ready():
bin_path = os.getenv("PIPER_BIN", "piper")
model = os.getenv("PIPER_MODEL")
espeak = os.getenv("ESPEAK_DATA_PATH")
print(f"[PIPER] BIN={bin_path} exists={os.path.exists(bin_path)}")
print(f"[PIPER] MODEL={model} exists={os.path.exists(model) if model else None}")
print(f"[PIPER] ESPEAK_DATA_PATH={espeak} exists={os.path.exists(espeak) if espeak else None}")
# If PIPER_BIN is an absolute/relative file in repo, make it executable.
if bin_path and os.path.isfile(bin_path):
try:
st = os.stat(bin_path)
os.chmod(bin_path, st.st_mode | stat.S_IEXEC)
print("[PIPER] chmod +x applied to binary")
except Exception as e:
print("[PIPER] chmod failed:", e)
# -------------
# Application
# -------------
def main():
# Log a few envs to help debug Spaces
log_env_for_audio()
# Clean runtime/audio on boot
cleanup_old_audio(keep_latest=None)
# Ensure model exists locally
# ensure_model()
# Make sure bundled Piper can run (no downloads on Spaces)
ensure_piper_ready()
# Launch Gradio
demo = build_demo()
# On Spaces, share=True is ignored (safe locally)
demo.launch(share=True)
if __name__ == "__main__":
main()