Spaces:
Build error
Build error
File size: 9,495 Bytes
317700f | 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 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | #!/usr/bin/env python3
"""
Script de teste para a API do Montreal Forced Aligner Portuguese
Testa todos os endpoints e funcionalidades da API
"""
import requests
import json
import time
import os
from pathlib import Path
import wave
import numpy as np
from io import BytesIO
# Configuração da API
API_BASE_URL = "http://localhost:7860" # Para teste local
# API_BASE_URL = "https://marcosremar2-ufpalign.hf.space" # Para Hugging Face Spaces
def create_test_audio(filename="test_audio.wav", duration=3, sample_rate=16000):
"""
Cria um arquivo de áudio de teste simples (tom puro).
Para teste real, use um arquivo WAV com fala em português.
"""
t = np.linspace(0, duration, int(sample_rate * duration), False)
# Tom de 440 Hz (Lá)
audio = np.sin(2 * np.pi * 440 * t) * 0.3
# Converter para 16-bit
audio_int16 = (audio * 32767).astype(np.int16)
# Salvar como WAV
with wave.open(filename, 'w') as wav_file:
wav_file.setnchannels(1) # Mono
wav_file.setsampwidth(2) # 16-bit
wav_file.setframerate(sample_rate)
wav_file.writeframes(audio_int16.tobytes())
print(f"✅ Arquivo de áudio de teste criado: {filename}")
return filename
def test_health_check():
"""Testa o endpoint de health check"""
print("\n🔍 Testando Health Check...")
try:
response = requests.get(f"{API_BASE_URL}/health", timeout=10)
if response.status_code == 200:
data = response.json()
print(f"✅ Health Check OK: {data}")
return True
else:
print(f"❌ Health Check falhou: {response.status_code}")
return False
except Exception as e:
print(f"❌ Erro no Health Check: {e}")
return False
def test_models_list():
"""Testa o endpoint de listagem de modelos"""
print("\n🔍 Testando listagem de modelos...")
try:
response = requests.get(f"{API_BASE_URL}/models", timeout=30)
if response.status_code == 200:
data = response.json()
print(f"✅ Modelos disponíveis:")
print(f" Acústicos: {data.get('acoustic_models', [])[:3]}...")
print(f" G2P: {data.get('g2p_models', [])[:3]}...")
return True
else:
print(f"❌ Falha ao listar modelos: {response.status_code}")
return False
except Exception as e:
print(f"❌ Erro ao listar modelos: {e}")
return False
def test_alignment(audio_file=None, text="Esta é uma frase de teste em português"):
"""Testa o endpoint principal de alinhamento"""
print("\n🔍 Testando alinhamento forçado...")
# Usar arquivo de áudio fornecido ou criar um de teste
if audio_file is None:
audio_file = create_test_audio()
if not os.path.exists(audio_file):
print(f"❌ Arquivo de áudio não encontrado: {audio_file}")
return False
try:
# Preparar dados para upload
files = {'audio': open(audio_file, 'rb')}
data = {'text': text}
print(f"📝 Texto: {text}")
print(f"🎵 Áudio: {audio_file}")
print("⏳ Enviando para alinhamento...")
# Fazer requisição
response = requests.post(
f"{API_BASE_URL}/align",
files=files,
data=data,
timeout=300 # 5 minutos
)
files['audio'].close()
if response.status_code == 200:
result = response.json()
print(f"✅ Alinhamento concluído!")
print(f" Arquivo: {result['filename']}")
print(f" Duração: {result['duration']:.2f}s")
print(f" Tiers: {len(result['tiers'])}")
# Mostrar algumas informações dos tiers
for tier in result['tiers']:
print(f" - {tier['name']}: {len(tier['intervals'])} intervalos")
return result
else:
error_data = response.json() if response.headers.get('content-type') == 'application/json' else response.text
print(f"❌ Falha no alinhamento: {response.status_code}")
print(f" Erro: {error_data}")
return False
except Exception as e:
print(f"❌ Erro no alinhamento: {e}")
return False
finally:
# Limpar arquivo de teste se foi criado
if audio_file == "test_audio.wav" and os.path.exists(audio_file):
os.remove(audio_file)
def test_download(filename):
"""Testa o download do arquivo TextGrid"""
print(f"\n🔍 Testando download do TextGrid: {filename}")
try:
# Remover extensão .TextGrid se presente
base_filename = filename.replace('.TextGrid', '')
response = requests.get(f"{API_BASE_URL}/download/{base_filename}", timeout=30)
if response.status_code == 200:
print(f"✅ Download concluído!")
print(f" Tamanho: {len(response.content)} bytes")
print(f" Tipo: {response.headers.get('content-type', 'unknown')}")
# Salvar arquivo localmente para verificação
download_filename = f"downloaded_{base_filename}.TextGrid"
with open(download_filename, 'w', encoding='utf-8') as f:
f.write(response.text)
print(f" Salvo como: {download_filename}")
return True
else:
print(f"❌ Falha no download: {response.status_code}")
return False
except Exception as e:
print(f"❌ Erro no download: {e}")
return False
def test_web_interface():
"""Testa se a interface web está acessível"""
print("\n🔍 Testando interface web...")
try:
response = requests.get(API_BASE_URL, timeout=10)
if response.status_code == 200:
if "MFA Portuguese Alignment" in response.text:
print("✅ Interface web acessível e funcionando")
return True
else:
print("⚠️ Interface web acessível mas conteúdo inesperado")
return False
else:
print(f"❌ Interface web inacessível: {response.status_code}")
return False
except Exception as e:
print(f"❌ Erro na interface web: {e}")
return False
def run_full_test(audio_file=None, text=None):
"""Executa todos os testes da API"""
print("🚀 Iniciando testes completos da API MFA Portuguese")
print(f"🌐 URL base: {API_BASE_URL}")
print("="*60)
results = {}
# Texto padrão em português
if text is None:
text = "Olá, este é um teste de alinhamento forçado para português brasileiro."
# 1. Health Check
results['health'] = test_health_check()
# 2. Interface Web
results['web'] = test_web_interface()
# 3. Listar Modelos
results['models'] = test_models_list()
# 4. Alinhamento Principal
alignment_result = test_alignment(audio_file, text)
results['alignment'] = alignment_result is not False
# 5. Download (se alinhamento foi bem-sucedido)
if alignment_result and isinstance(alignment_result, dict):
results['download'] = test_download(alignment_result['filename'])
else:
results['download'] = False
print("\n⏭️ Pulando teste de download (alinhamento falhou)")
# Relatório final
print("\n" + "="*60)
print("📊 RELATÓRIO FINAL DOS TESTES")
print("="*60)
total_tests = len(results)
passed_tests = sum(1 for result in results.values() if result)
for test_name, result in results.items():
status = "✅ PASSOU" if result else "❌ FALHOU"
print(f"{test_name.upper():12} | {status}")
print("-"*60)
print(f"RESUMO: {passed_tests}/{total_tests} testes passaram")
if passed_tests == total_tests:
print("🎉 Todos os testes passaram! API funcionando perfeitamente.")
return True
else:
print("⚠️ Alguns testes falharam. Verifique os logs acima.")
return False
def test_with_real_audio():
"""
Exemplo de como testar com áudio real.
Substitua pelos seus próprios arquivos.
"""
# Exemplo de uso com arquivo real
audio_file = "exemplo.wav" # Substitua pelo seu arquivo
text = "Transcrição exata do que está sendo falado no áudio"
if os.path.exists(audio_file):
print(f"\n🎯 Testando com áudio real: {audio_file}")
return run_full_test(audio_file, text)
else:
print(f"⚠️ Arquivo {audio_file} não encontrado. Usando áudio de teste.")
return run_full_test()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Testa a API do MFA Portuguese")
parser.add_argument("--url", default=API_BASE_URL, help="URL base da API")
parser.add_argument("--audio", help="Arquivo de áudio para teste")
parser.add_argument("--text", help="Texto para alinhamento")
parser.add_argument("--real", action="store_true", help="Tenta usar áudio real")
args = parser.parse_args()
# Atualizar URL se fornecida
API_BASE_URL = args.url
if args.real:
success = test_with_real_audio()
else:
success = run_full_test(args.audio, args.text)
exit(0 if success else 1) |