Commit ·
37b89b9
1
Parent(s): cca5942
Add basic test script for space connectivity
Browse files- .gitignore +20 -0
- README_TESTS.md +173 -0
- test_app.py +292 -0
- test_simple.py +234 -0
- test_status.py +101 -0
.gitignore
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Arquivos de configuração com tokens
|
| 2 |
+
test_config.py
|
| 3 |
+
.env
|
| 4 |
+
*.env
|
| 5 |
+
|
| 6 |
+
# Python
|
| 7 |
+
__pycache__/
|
| 8 |
+
*.py[cod]
|
| 9 |
+
*$py.class
|
| 10 |
+
*.so
|
| 11 |
+
.Python
|
| 12 |
+
env/
|
| 13 |
+
venv/
|
| 14 |
+
.venv
|
| 15 |
+
pip-log.txt
|
| 16 |
+
pip-delete-this-directory.txt
|
| 17 |
+
|
| 18 |
+
# Arquivos temporários de teste
|
| 19 |
+
test_audio_*.wav
|
| 20 |
+
*.tmp
|
README_TESTS.md
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 🧪 Scripts de Teste - Pyannote Space
|
| 2 |
+
|
| 3 |
+
Este diretório contém scripts para testar o funcionamento do Pyannote Speaker Diarization Space.
|
| 4 |
+
|
| 5 |
+
## 📋 Scripts Disponíveis
|
| 6 |
+
|
| 7 |
+
### 1. `test_simple.py` - Teste Básico (Recomendado)
|
| 8 |
+
Script leve que testa apenas conectividade e API básica.
|
| 9 |
+
|
| 10 |
+
**Dependências:**
|
| 11 |
+
- `requests` (biblioteca padrão Python)
|
| 12 |
+
|
| 13 |
+
**Uso:**
|
| 14 |
+
```bash
|
| 15 |
+
python test_simple.py
|
| 16 |
+
```
|
| 17 |
+
|
| 18 |
+
**O que testa:**
|
| 19 |
+
- ✅ Conectividade com o space
|
| 20 |
+
- ✅ API do Gradio funcionando
|
| 21 |
+
- ✅ Health check endpoint
|
| 22 |
+
- ✅ Presença de elementos da interface
|
| 23 |
+
|
| 24 |
+
### 2. `test_app.py` - Teste Completo
|
| 25 |
+
Script completo que testa funcionalidade local e remota.
|
| 26 |
+
|
| 27 |
+
**Dependências:**
|
| 28 |
+
- `torch`
|
| 29 |
+
- `pyannote.audio`
|
| 30 |
+
- `gradio`
|
| 31 |
+
- `soundfile`
|
| 32 |
+
- `numpy`
|
| 33 |
+
- `requests`
|
| 34 |
+
|
| 35 |
+
**Uso:**
|
| 36 |
+
```bash
|
| 37 |
+
# Instalar dependências primeiro
|
| 38 |
+
pip install torch torchaudio pyannote.audio gradio soundfile numpy requests
|
| 39 |
+
|
| 40 |
+
# Executar teste
|
| 41 |
+
python test_app.py
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
**O que testa:**
|
| 45 |
+
- ✅ Imports das dependências
|
| 46 |
+
- ✅ Carregamento local do modelo
|
| 47 |
+
- ✅ Diarização local com áudio sintético
|
| 48 |
+
- ✅ Conectividade com space remoto
|
| 49 |
+
- ✅ API remota do space
|
| 50 |
+
- ✅ Diarização via API remota
|
| 51 |
+
|
| 52 |
+
## 🚀 Como Usar
|
| 53 |
+
|
| 54 |
+
### Teste Rápido (Recomendado)
|
| 55 |
+
```bash
|
| 56 |
+
python test_simple.py
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
### Teste Completo
|
| 60 |
+
```bash
|
| 61 |
+
python test_app.py
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
## 📊 Interpretação dos Resultados
|
| 65 |
+
|
| 66 |
+
### Códigos de Saída
|
| 67 |
+
- **0**: ✅ Todos os testes passaram
|
| 68 |
+
- **1**: ⚠️ Alguns testes falharam (pode estar iniciando)
|
| 69 |
+
- **2**: 🚨 Muitos testes falharam (problemas sérios)
|
| 70 |
+
|
| 71 |
+
### Estados Típicos
|
| 72 |
+
|
| 73 |
+
#### 🎉 Funcionando Perfeitamente
|
| 74 |
+
```
|
| 75 |
+
space_online : ✅ PASSOU
|
| 76 |
+
gradio_api : ✅ PASSOU
|
| 77 |
+
health_check : ✅ PASSOU
|
| 78 |
+
space_info : ✅ PASSOU
|
| 79 |
+
|
| 80 |
+
🎯 RESULTADO: 4/4 testes passaram
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
#### ⏳ Iniciando
|
| 84 |
+
```
|
| 85 |
+
space_online : ❌ FALHOU
|
| 86 |
+
space_ready : ✅ PASSOU
|
| 87 |
+
gradio_api : ✅ PASSOU
|
| 88 |
+
health_check : ❌ FALHOU
|
| 89 |
+
|
| 90 |
+
🎯 RESULTADO: 2/4 testes passaram
|
| 91 |
+
```
|
| 92 |
+
|
| 93 |
+
#### 🚨 Com Problemas
|
| 94 |
+
```
|
| 95 |
+
space_online : ❌ FALHOU
|
| 96 |
+
space_ready : ❌ FALHOU
|
| 97 |
+
gradio_api : ❌ FALHOU
|
| 98 |
+
health_check : ❌ FALHOU
|
| 99 |
+
|
| 100 |
+
🎯 RESULTADO: 0/4 testes passaram
|
| 101 |
+
```
|
| 102 |
+
|
| 103 |
+
## 🔧 Troubleshooting
|
| 104 |
+
|
| 105 |
+
### Erro de Conectividade
|
| 106 |
+
```bash
|
| 107 |
+
❌ Erro de conexão - Space pode estar offline
|
| 108 |
+
```
|
| 109 |
+
**Solução:** Aguarde alguns minutos, o space pode estar reiniciando.
|
| 110 |
+
|
| 111 |
+
### Timeout
|
| 112 |
+
```bash
|
| 113 |
+
⏰ Timeout - Space pode estar iniciando
|
| 114 |
+
```
|
| 115 |
+
**Solução:** Normal durante restart. Aguarde 2-5 minutos.
|
| 116 |
+
|
| 117 |
+
### Health Check Falha
|
| 118 |
+
```bash
|
| 119 |
+
❌ Health check falhou com status: 500
|
| 120 |
+
```
|
| 121 |
+
**Possíveis causas:**
|
| 122 |
+
- Token `HUGGINGFACE_TOKEN` não configurado
|
| 123 |
+
- Modelo não conseguiu carregar
|
| 124 |
+
- Erro interno no código
|
| 125 |
+
|
| 126 |
+
**Solução:**
|
| 127 |
+
1. Verifique se o token foi configurado no space
|
| 128 |
+
2. Verifique os logs do space no Hugging Face
|
| 129 |
+
|
| 130 |
+
### API Não Responde
|
| 131 |
+
```bash
|
| 132 |
+
❌ API retornou status: 404
|
| 133 |
+
```
|
| 134 |
+
**Solução:** O space pode estar em modo de erro. Verifique os logs.
|
| 135 |
+
|
| 136 |
+
## 🔑 Configuração Necessária
|
| 137 |
+
|
| 138 |
+
### Token do Hugging Face
|
| 139 |
+
O space precisa do token configurado como variável de ambiente:
|
| 140 |
+
|
| 141 |
+
1. Acesse: https://huggingface.co/spaces/marcosremar2/pyannote-pt-diarization
|
| 142 |
+
2. Vá em **Settings → Variables and secrets**
|
| 143 |
+
3. Adicione:
|
| 144 |
+
- **Name:** `HUGGINGFACE_TOKEN`
|
| 145 |
+
- **Value:** `your_token_here`
|
| 146 |
+
|
| 147 |
+
### Aceitar Termos do Modelo
|
| 148 |
+
1. Acesse: https://huggingface.co/pyannote/speaker-diarization-3.1
|
| 149 |
+
2. Aceite os termos de uso do modelo
|
| 150 |
+
|
| 151 |
+
## 📝 Logs Úteis
|
| 152 |
+
|
| 153 |
+
### Verificar Logs do Space
|
| 154 |
+
1. Acesse o space no Hugging Face
|
| 155 |
+
2. Vá na aba **"Logs"**
|
| 156 |
+
3. Procure por erros como:
|
| 157 |
+
- `Authentication failed`
|
| 158 |
+
- `Token not found`
|
| 159 |
+
- `Model loading error`
|
| 160 |
+
|
| 161 |
+
### Teste Manual
|
| 162 |
+
Acesse diretamente: https://marcosremar2-pyannote-pt-diarization.hf.space
|
| 163 |
+
|
| 164 |
+
Se a página carregar e mostrar a interface, o space está funcionando.
|
| 165 |
+
|
| 166 |
+
## 🆘 Suporte
|
| 167 |
+
|
| 168 |
+
Se os testes continuarem falhando:
|
| 169 |
+
|
| 170 |
+
1. **Verifique os logs** do space no Hugging Face
|
| 171 |
+
2. **Confirme o token** está configurado corretamente
|
| 172 |
+
3. **Aguarde 5-10 minutos** após configurar o token
|
| 173 |
+
4. **Teste manualmente** acessando a URL do space
|
test_app.py
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Script de teste para o Pyannote Speaker Diarization Space
|
| 4 |
+
Testa tanto funcionamento local quanto remoto via API
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import sys
|
| 9 |
+
import time
|
| 10 |
+
import json
|
| 11 |
+
import requests
|
| 12 |
+
import tempfile
|
| 13 |
+
import numpy as np
|
| 14 |
+
from pathlib import Path
|
| 15 |
+
import soundfile as sf
|
| 16 |
+
from typing import Dict, Any
|
| 17 |
+
|
| 18 |
+
# Configurações
|
| 19 |
+
try:
|
| 20 |
+
from test_config import HF_TOKEN, SPACE_URL
|
| 21 |
+
except ImportError:
|
| 22 |
+
# Fallback se test_config.py não existir
|
| 23 |
+
SPACE_URL = "https://marcosremar2-pyannote-pt-diarization.hf.space"
|
| 24 |
+
HF_TOKEN = os.getenv("HUGGINGFACE_TOKEN", "your_token_here")
|
| 25 |
+
|
| 26 |
+
def create_test_audio(duration: int = 10, sample_rate: int = 22050) -> str:
|
| 27 |
+
"""Cria um arquivo de áudio de teste com dois tons diferentes"""
|
| 28 |
+
print(f"🎵 Criando áudio de teste ({duration}s)...")
|
| 29 |
+
|
| 30 |
+
# Gerar dois tons diferentes para simular diferentes speakers
|
| 31 |
+
t = np.linspace(0, duration, duration * sample_rate)
|
| 32 |
+
|
| 33 |
+
# Tom 1 (440 Hz) - primeiros 5 segundos
|
| 34 |
+
tone1 = 0.3 * np.sin(2 * np.pi * 440 * t[:len(t)//2])
|
| 35 |
+
|
| 36 |
+
# Tom 2 (880 Hz) - últimos 5 segundos
|
| 37 |
+
tone2 = 0.3 * np.sin(2 * np.pi * 880 * t[len(t)//2:])
|
| 38 |
+
|
| 39 |
+
# Combinar os tons
|
| 40 |
+
audio = np.concatenate([tone1, tone2])
|
| 41 |
+
|
| 42 |
+
# Salvar arquivo temporário
|
| 43 |
+
temp_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=False)
|
| 44 |
+
sf.write(temp_file.name, audio, sample_rate)
|
| 45 |
+
|
| 46 |
+
print(f"✅ Áudio de teste criado: {temp_file.name}")
|
| 47 |
+
return temp_file.name
|
| 48 |
+
|
| 49 |
+
def test_local_import():
|
| 50 |
+
"""Testa se consegue importar as dependências localmente"""
|
| 51 |
+
print("\n🔍 Testando imports locais...")
|
| 52 |
+
|
| 53 |
+
try:
|
| 54 |
+
import torch
|
| 55 |
+
print(f"✅ PyTorch: {torch.__version__}")
|
| 56 |
+
print(f"✅ CUDA disponível: {torch.cuda.is_available()}")
|
| 57 |
+
|
| 58 |
+
import gradio as gr
|
| 59 |
+
print(f"✅ Gradio: {gr.__version__}")
|
| 60 |
+
|
| 61 |
+
from pyannote.audio import Pipeline
|
| 62 |
+
print(f"✅ Pyannote Audio importado")
|
| 63 |
+
|
| 64 |
+
return True
|
| 65 |
+
except ImportError as e:
|
| 66 |
+
print(f"❌ Erro de import: {e}")
|
| 67 |
+
return False
|
| 68 |
+
|
| 69 |
+
def test_local_model_loading():
|
| 70 |
+
"""Testa carregamento do modelo localmente"""
|
| 71 |
+
print("\n🤖 Testando carregamento do modelo...")
|
| 72 |
+
|
| 73 |
+
try:
|
| 74 |
+
# Configurar token
|
| 75 |
+
os.environ["HUGGINGFACE_TOKEN"] = HF_TOKEN
|
| 76 |
+
|
| 77 |
+
from pyannote.audio import Pipeline
|
| 78 |
+
import torch
|
| 79 |
+
|
| 80 |
+
print("📥 Carregando modelo pyannote/speaker-diarization-3.1...")
|
| 81 |
+
pipeline = Pipeline.from_pretrained(
|
| 82 |
+
"pyannote/speaker-diarization-3.1",
|
| 83 |
+
token=HF_TOKEN
|
| 84 |
+
)
|
| 85 |
+
|
| 86 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 87 |
+
pipeline = pipeline.to(device)
|
| 88 |
+
|
| 89 |
+
print(f"✅ Modelo carregado com sucesso no device: {device}")
|
| 90 |
+
return pipeline
|
| 91 |
+
|
| 92 |
+
except Exception as e:
|
| 93 |
+
print(f"❌ Erro ao carregar modelo: {e}")
|
| 94 |
+
return None
|
| 95 |
+
|
| 96 |
+
def test_local_diarization(pipeline, audio_file: str):
|
| 97 |
+
"""Testa diarização localmente"""
|
| 98 |
+
print(f"\n🎭 Testando diarização local com: {audio_file}")
|
| 99 |
+
|
| 100 |
+
try:
|
| 101 |
+
start_time = time.time()
|
| 102 |
+
|
| 103 |
+
# Aplicar diarization
|
| 104 |
+
diarization = pipeline(audio_file)
|
| 105 |
+
|
| 106 |
+
# Processar resultados
|
| 107 |
+
segments = []
|
| 108 |
+
speakers = set()
|
| 109 |
+
|
| 110 |
+
for turn, _, speaker in diarization.itertracks(yield_label=True):
|
| 111 |
+
speakers.add(speaker)
|
| 112 |
+
segments.append({
|
| 113 |
+
"start": round(turn.start, 2),
|
| 114 |
+
"end": round(turn.end, 2),
|
| 115 |
+
"duration": round(turn.end - turn.start, 2),
|
| 116 |
+
"speaker": speaker
|
| 117 |
+
})
|
| 118 |
+
|
| 119 |
+
processing_time = time.time() - start_time
|
| 120 |
+
|
| 121 |
+
result = {
|
| 122 |
+
"status": "success",
|
| 123 |
+
"segments": len(segments),
|
| 124 |
+
"num_speakers": len(speakers),
|
| 125 |
+
"speakers": sorted(list(speakers)),
|
| 126 |
+
"processing_time": round(processing_time, 2)
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
print(f"✅ Diarização concluída:")
|
| 130 |
+
print(f" 📊 Speakers: {result['num_speakers']}")
|
| 131 |
+
print(f" 📋 Segmentos: {result['segments']}")
|
| 132 |
+
print(f" ⏱️ Tempo: {result['processing_time']}s")
|
| 133 |
+
|
| 134 |
+
return result
|
| 135 |
+
|
| 136 |
+
except Exception as e:
|
| 137 |
+
print(f"❌ Erro na diarização: {e}")
|
| 138 |
+
return None
|
| 139 |
+
|
| 140 |
+
def test_space_health():
|
| 141 |
+
"""Testa se o space está rodando"""
|
| 142 |
+
print(f"\n🌐 Testando conexão com space: {SPACE_URL}")
|
| 143 |
+
|
| 144 |
+
try:
|
| 145 |
+
response = requests.get(f"{SPACE_URL}/", timeout=10)
|
| 146 |
+
if response.status_code == 200:
|
| 147 |
+
print("✅ Space está online")
|
| 148 |
+
return True
|
| 149 |
+
else:
|
| 150 |
+
print(f"❌ Space retornou status: {response.status_code}")
|
| 151 |
+
return False
|
| 152 |
+
except Exception as e:
|
| 153 |
+
print(f"❌ Erro ao conectar: {e}")
|
| 154 |
+
return False
|
| 155 |
+
|
| 156 |
+
def test_space_api():
|
| 157 |
+
"""Testa a API do space"""
|
| 158 |
+
print(f"\n🔗 Testando API do space...")
|
| 159 |
+
|
| 160 |
+
try:
|
| 161 |
+
# Testar health check primeiro
|
| 162 |
+
health_url = f"{SPACE_URL}/api/predict"
|
| 163 |
+
|
| 164 |
+
# Criar payload para health check
|
| 165 |
+
payload = {
|
| 166 |
+
"data": [],
|
| 167 |
+
"fn_index": 1 # Index da função health_check
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
response = requests.post(health_url, json=payload, timeout=30)
|
| 171 |
+
|
| 172 |
+
if response.status_code == 200:
|
| 173 |
+
result = response.json()
|
| 174 |
+
print("✅ API funcionando")
|
| 175 |
+
print(f" 📊 Resposta: {result}")
|
| 176 |
+
return True
|
| 177 |
+
else:
|
| 178 |
+
print(f"❌ API retornou status: {response.status_code}")
|
| 179 |
+
return False
|
| 180 |
+
|
| 181 |
+
except Exception as e:
|
| 182 |
+
print(f"❌ Erro na API: {e}")
|
| 183 |
+
return False
|
| 184 |
+
|
| 185 |
+
def test_space_diarization(audio_file: str):
|
| 186 |
+
"""Testa diarização via API do space"""
|
| 187 |
+
print(f"\n🎭 Testando diarização via API...")
|
| 188 |
+
|
| 189 |
+
try:
|
| 190 |
+
# Upload do arquivo
|
| 191 |
+
with open(audio_file, 'rb') as f:
|
| 192 |
+
files = {'data': f}
|
| 193 |
+
|
| 194 |
+
# Fazer request para o endpoint de diarização
|
| 195 |
+
response = requests.post(
|
| 196 |
+
f"{SPACE_URL}/api/predict",
|
| 197 |
+
files=files,
|
| 198 |
+
data={"fn_index": 0}, # Index da função process_audio
|
| 199 |
+
timeout=60
|
| 200 |
+
)
|
| 201 |
+
|
| 202 |
+
if response.status_code == 200:
|
| 203 |
+
result = response.json()
|
| 204 |
+
print("✅ Diarização via API concluída")
|
| 205 |
+
print(f" 📊 Resposta: {result}")
|
| 206 |
+
return True
|
| 207 |
+
else:
|
| 208 |
+
print(f"❌ API retornou status: {response.status_code}")
|
| 209 |
+
return False
|
| 210 |
+
|
| 211 |
+
except Exception as e:
|
| 212 |
+
print(f"❌ Erro na diarização via API: {e}")
|
| 213 |
+
return False
|
| 214 |
+
|
| 215 |
+
def run_all_tests():
|
| 216 |
+
"""Executa todos os testes"""
|
| 217 |
+
print("🧪 INICIANDO TESTES DO PYANNOTE SPACE")
|
| 218 |
+
print("=" * 50)
|
| 219 |
+
|
| 220 |
+
results = {}
|
| 221 |
+
|
| 222 |
+
# Teste 1: Imports locais
|
| 223 |
+
results['imports'] = test_local_import()
|
| 224 |
+
|
| 225 |
+
# Teste 2: Criar áudio de teste
|
| 226 |
+
audio_file = create_test_audio()
|
| 227 |
+
|
| 228 |
+
# Teste 3: Carregamento do modelo local
|
| 229 |
+
if results['imports']:
|
| 230 |
+
pipeline = test_local_model_loading()
|
| 231 |
+
results['model_loading'] = pipeline is not None
|
| 232 |
+
|
| 233 |
+
# Teste 4: Diarização local
|
| 234 |
+
if pipeline:
|
| 235 |
+
results['local_diarization'] = test_local_diarization(pipeline, audio_file) is not None
|
| 236 |
+
else:
|
| 237 |
+
results['local_diarization'] = False
|
| 238 |
+
else:
|
| 239 |
+
results['model_loading'] = False
|
| 240 |
+
results['local_diarization'] = False
|
| 241 |
+
|
| 242 |
+
# Teste 5: Space online
|
| 243 |
+
results['space_health'] = test_space_health()
|
| 244 |
+
|
| 245 |
+
# Teste 6: API do space
|
| 246 |
+
if results['space_health']:
|
| 247 |
+
results['space_api'] = test_space_api()
|
| 248 |
+
|
| 249 |
+
# Teste 7: Diarização via API
|
| 250 |
+
if results['space_api']:
|
| 251 |
+
results['space_diarization'] = test_space_diarization(audio_file)
|
| 252 |
+
else:
|
| 253 |
+
results['space_diarization'] = False
|
| 254 |
+
else:
|
| 255 |
+
results['space_api'] = False
|
| 256 |
+
results['space_diarization'] = False
|
| 257 |
+
|
| 258 |
+
# Limpar arquivo temporário
|
| 259 |
+
try:
|
| 260 |
+
os.unlink(audio_file)
|
| 261 |
+
print(f"\n🗑️ Arquivo temporário removido: {audio_file}")
|
| 262 |
+
except:
|
| 263 |
+
pass
|
| 264 |
+
|
| 265 |
+
# Resumo final
|
| 266 |
+
print("\n" + "=" * 50)
|
| 267 |
+
print("📊 RESUMO DOS TESTES:")
|
| 268 |
+
print("=" * 50)
|
| 269 |
+
|
| 270 |
+
for test_name, result in results.items():
|
| 271 |
+
status = "✅ PASSOU" if result else "❌ FALHOU"
|
| 272 |
+
print(f"{test_name:<20}: {status}")
|
| 273 |
+
|
| 274 |
+
# Status geral
|
| 275 |
+
total_tests = len(results)
|
| 276 |
+
passed_tests = sum(results.values())
|
| 277 |
+
|
| 278 |
+
print(f"\n🎯 RESULTADO GERAL: {passed_tests}/{total_tests} testes passaram")
|
| 279 |
+
|
| 280 |
+
if passed_tests == total_tests:
|
| 281 |
+
print("🎉 TODOS OS TESTES PASSARAM!")
|
| 282 |
+
return 0
|
| 283 |
+
elif passed_tests >= total_tests // 2:
|
| 284 |
+
print("⚠️ ALGUNS TESTES FALHARAM - Verificar configuração")
|
| 285 |
+
return 1
|
| 286 |
+
else:
|
| 287 |
+
print("🚨 MUITOS TESTES FALHARAM - Verificar instalação e configuração")
|
| 288 |
+
return 2
|
| 289 |
+
|
| 290 |
+
if __name__ == "__main__":
|
| 291 |
+
exit_code = run_all_tests()
|
| 292 |
+
sys.exit(exit_code)
|
test_simple.py
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Script de teste simples para verificar se o Space está funcionando
|
| 4 |
+
Não requer dependências pesadas - apenas requests
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import requests
|
| 8 |
+
import time
|
| 9 |
+
import json
|
| 10 |
+
|
| 11 |
+
# Configurações
|
| 12 |
+
SPACE_URL = "https://marcosremar2-pyannote-pt-diarization.hf.space"
|
| 13 |
+
|
| 14 |
+
def test_space_online():
|
| 15 |
+
"""Testa se o space está online"""
|
| 16 |
+
print("🌐 Testando se o space está online...")
|
| 17 |
+
|
| 18 |
+
try:
|
| 19 |
+
response = requests.get(SPACE_URL, timeout=15)
|
| 20 |
+
|
| 21 |
+
if response.status_code == 200:
|
| 22 |
+
print("✅ Space está online e respondendo")
|
| 23 |
+
return True
|
| 24 |
+
else:
|
| 25 |
+
print(f"❌ Space retornou status code: {response.status_code}")
|
| 26 |
+
return False
|
| 27 |
+
|
| 28 |
+
except requests.exceptions.Timeout:
|
| 29 |
+
print("⏰ Timeout - Space pode estar iniciando")
|
| 30 |
+
return False
|
| 31 |
+
except requests.exceptions.ConnectionError:
|
| 32 |
+
print("❌ Erro de conexão - Space pode estar offline")
|
| 33 |
+
return False
|
| 34 |
+
except Exception as e:
|
| 35 |
+
print(f"❌ Erro inesperado: {e}")
|
| 36 |
+
return False
|
| 37 |
+
|
| 38 |
+
def test_gradio_api():
|
| 39 |
+
"""Testa se a API do Gradio está respondendo"""
|
| 40 |
+
print("🔗 Testando API do Gradio...")
|
| 41 |
+
|
| 42 |
+
try:
|
| 43 |
+
# Tentar acessar a informação da API
|
| 44 |
+
api_url = f"{SPACE_URL}/api"
|
| 45 |
+
response = requests.get(api_url, timeout=10)
|
| 46 |
+
|
| 47 |
+
if response.status_code == 200:
|
| 48 |
+
print("✅ API do Gradio está respondendo")
|
| 49 |
+
return True
|
| 50 |
+
else:
|
| 51 |
+
print(f"❌ API retornou status: {response.status_code}")
|
| 52 |
+
return False
|
| 53 |
+
|
| 54 |
+
except Exception as e:
|
| 55 |
+
print(f"❌ Erro na API: {e}")
|
| 56 |
+
return False
|
| 57 |
+
|
| 58 |
+
def test_health_endpoint():
|
| 59 |
+
"""Testa o endpoint de health check"""
|
| 60 |
+
print("🏥 Testando health check...")
|
| 61 |
+
|
| 62 |
+
try:
|
| 63 |
+
# Tentar fazer request para o health check
|
| 64 |
+
health_url = f"{SPACE_URL}/api/predict"
|
| 65 |
+
|
| 66 |
+
payload = {
|
| 67 |
+
"data": [],
|
| 68 |
+
"fn_index": 1 # Index da função health_check
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
response = requests.post(
|
| 72 |
+
health_url,
|
| 73 |
+
json=payload,
|
| 74 |
+
timeout=30,
|
| 75 |
+
headers={'Content-Type': 'application/json'}
|
| 76 |
+
)
|
| 77 |
+
|
| 78 |
+
if response.status_code == 200:
|
| 79 |
+
result = response.json()
|
| 80 |
+
print("✅ Health check funcionando")
|
| 81 |
+
|
| 82 |
+
# Tentar extrair informações úteis
|
| 83 |
+
if 'data' in result and len(result['data']) > 0:
|
| 84 |
+
health_data = result['data'][0]
|
| 85 |
+
if isinstance(health_data, str):
|
| 86 |
+
try:
|
| 87 |
+
health_info = json.loads(health_data)
|
| 88 |
+
print(f" 📊 Status: {health_info.get('status', 'N/A')}")
|
| 89 |
+
print(f" 🖥️ Device: {health_info.get('device', 'N/A')}")
|
| 90 |
+
print(f" 🔧 GPU: {health_info.get('gpu_available', 'N/A')}")
|
| 91 |
+
print(f" 🤖 Modelo carregado: {health_info.get('model_loaded', 'N/A')}")
|
| 92 |
+
except:
|
| 93 |
+
print(f" 📄 Resposta: {health_data[:100]}...")
|
| 94 |
+
|
| 95 |
+
return True
|
| 96 |
+
else:
|
| 97 |
+
print(f"❌ Health check falhou com status: {response.status_code}")
|
| 98 |
+
return False
|
| 99 |
+
|
| 100 |
+
except Exception as e:
|
| 101 |
+
print(f"❌ Erro no health check: {e}")
|
| 102 |
+
return False
|
| 103 |
+
|
| 104 |
+
def test_space_logs():
|
| 105 |
+
"""Verifica se consegue acessar informações básicas do space"""
|
| 106 |
+
print("📋 Verificando informações do space...")
|
| 107 |
+
|
| 108 |
+
try:
|
| 109 |
+
# Fazer request para a página principal e procurar por indicadores
|
| 110 |
+
response = requests.get(SPACE_URL, timeout=10)
|
| 111 |
+
|
| 112 |
+
if response.status_code == 200:
|
| 113 |
+
content = response.text.lower()
|
| 114 |
+
|
| 115 |
+
# Verificar indicadores de funcionamento
|
| 116 |
+
indicators = {
|
| 117 |
+
"gradio_running": "gradio" in content,
|
| 118 |
+
"pyannote_mentioned": "pyannote" in content,
|
| 119 |
+
"diarization_mentioned": "diarization" in content,
|
| 120 |
+
"audio_upload": "audio" in content
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
print(" 🔍 Indicadores encontrados:")
|
| 124 |
+
for indicator, found in indicators.items():
|
| 125 |
+
status = "✅" if found else "❌"
|
| 126 |
+
print(f" {status} {indicator}")
|
| 127 |
+
|
| 128 |
+
return any(indicators.values())
|
| 129 |
+
else:
|
| 130 |
+
print(f"❌ Não conseguiu acessar a página: {response.status_code}")
|
| 131 |
+
return False
|
| 132 |
+
|
| 133 |
+
except Exception as e:
|
| 134 |
+
print(f"❌ Erro ao verificar logs: {e}")
|
| 135 |
+
return False
|
| 136 |
+
|
| 137 |
+
def wait_for_space_ready(max_wait: int = 300):
|
| 138 |
+
"""Aguarda o space ficar pronto, com timeout"""
|
| 139 |
+
print(f"⏳ Aguardando space ficar pronto (máximo {max_wait}s)...")
|
| 140 |
+
|
| 141 |
+
start_time = time.time()
|
| 142 |
+
|
| 143 |
+
while time.time() - start_time < max_wait:
|
| 144 |
+
if test_space_online():
|
| 145 |
+
print("✅ Space está pronto!")
|
| 146 |
+
return True
|
| 147 |
+
|
| 148 |
+
print(" ⏳ Aguardando 10 segundos...")
|
| 149 |
+
time.sleep(10)
|
| 150 |
+
|
| 151 |
+
print(f"⏰ Timeout após {max_wait}s - Space pode estar com problemas")
|
| 152 |
+
return False
|
| 153 |
+
|
| 154 |
+
def run_basic_tests():
|
| 155 |
+
"""Executa testes básicos de conectividade"""
|
| 156 |
+
print("🧪 TESTE BÁSICO DO PYANNOTE SPACE")
|
| 157 |
+
print("=" * 40)
|
| 158 |
+
|
| 159 |
+
results = {}
|
| 160 |
+
|
| 161 |
+
# Teste 1: Space online
|
| 162 |
+
results['space_online'] = test_space_online()
|
| 163 |
+
|
| 164 |
+
if not results['space_online']:
|
| 165 |
+
print("\n⏳ Space parece estar offline, tentando aguardar...")
|
| 166 |
+
results['space_ready'] = wait_for_space_ready(120) # 2 minutos
|
| 167 |
+
else:
|
| 168 |
+
results['space_ready'] = True
|
| 169 |
+
|
| 170 |
+
if results['space_ready'] or results['space_online']:
|
| 171 |
+
# Teste 2: API Gradio
|
| 172 |
+
results['gradio_api'] = test_gradio_api()
|
| 173 |
+
|
| 174 |
+
# Teste 3: Health check
|
| 175 |
+
results['health_check'] = test_health_endpoint()
|
| 176 |
+
|
| 177 |
+
# Teste 4: Informações básicas
|
| 178 |
+
results['space_info'] = test_space_logs()
|
| 179 |
+
else:
|
| 180 |
+
results['gradio_api'] = False
|
| 181 |
+
results['health_check'] = False
|
| 182 |
+
results['space_info'] = False
|
| 183 |
+
|
| 184 |
+
# Resumo
|
| 185 |
+
print("\n" + "=" * 40)
|
| 186 |
+
print("📊 RESUMO DOS TESTES:")
|
| 187 |
+
print("=" * 40)
|
| 188 |
+
|
| 189 |
+
for test_name, result in results.items():
|
| 190 |
+
status = "✅ PASSOU" if result else "❌ FALHOU"
|
| 191 |
+
print(f"{test_name:<15}: {status}")
|
| 192 |
+
|
| 193 |
+
# Status geral
|
| 194 |
+
passed = sum(results.values())
|
| 195 |
+
total = len(results)
|
| 196 |
+
|
| 197 |
+
print(f"\n🎯 RESULTADO: {passed}/{total} testes passaram")
|
| 198 |
+
|
| 199 |
+
if passed == total:
|
| 200 |
+
print("🎉 TODOS OS TESTES BÁSICOS PASSARAM!")
|
| 201 |
+
print(" 💡 O space parece estar funcionando corretamente")
|
| 202 |
+
return 0
|
| 203 |
+
elif passed >= total // 2:
|
| 204 |
+
print("⚠️ ALGUNS TESTES FALHARAM")
|
| 205 |
+
print(" 💡 O space pode estar iniciando ou com problemas menores")
|
| 206 |
+
return 1
|
| 207 |
+
else:
|
| 208 |
+
print("🚨 MUITOS TESTES FALHARAM")
|
| 209 |
+
print(" 💡 O space provavelmente tem problemas ou está offline")
|
| 210 |
+
return 2
|
| 211 |
+
|
| 212 |
+
if __name__ == "__main__":
|
| 213 |
+
try:
|
| 214 |
+
exit_code = run_basic_tests()
|
| 215 |
+
|
| 216 |
+
print(f"\n📝 PRÓXIMOS PASSOS:")
|
| 217 |
+
if exit_code == 0:
|
| 218 |
+
print(" ✅ Space funcionando - pode testar upload de áudio")
|
| 219 |
+
print(" 🔗 Acesse: https://marcosremar2-pyannote-pt-diarization.hf.space")
|
| 220 |
+
elif exit_code == 1:
|
| 221 |
+
print(" ⏳ Aguarde alguns minutos e teste novamente")
|
| 222 |
+
print(" 🔧 Verifique se o token HUGGINGFACE_TOKEN foi configurado")
|
| 223 |
+
else:
|
| 224 |
+
print(" 🔧 Verifique os logs do space no Hugging Face")
|
| 225 |
+
print(" 🔑 Confirme se o token foi configurado corretamente")
|
| 226 |
+
|
| 227 |
+
exit(exit_code)
|
| 228 |
+
|
| 229 |
+
except KeyboardInterrupt:
|
| 230 |
+
print("\n⛔ Teste interrompido pelo usuário")
|
| 231 |
+
exit(130)
|
| 232 |
+
except Exception as e:
|
| 233 |
+
print(f"\n💥 Erro inesperado: {e}")
|
| 234 |
+
exit(1)
|
test_status.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Script de diagnóstico rápido para verificar status do Space
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import requests
|
| 7 |
+
import subprocess
|
| 8 |
+
import sys
|
| 9 |
+
|
| 10 |
+
SPACE_URL = "https://marcosremar2-pyannote-pt-diarization.hf.space"
|
| 11 |
+
|
| 12 |
+
def check_status():
|
| 13 |
+
"""Verifica status HTTP e interpreta o resultado"""
|
| 14 |
+
print("🔍 DIAGNÓSTICO RÁPIDO DO SPACE")
|
| 15 |
+
print("=" * 40)
|
| 16 |
+
print(f"🌐 URL: {SPACE_URL}")
|
| 17 |
+
|
| 18 |
+
try:
|
| 19 |
+
response = requests.get(SPACE_URL, timeout=10)
|
| 20 |
+
status_code = response.status_code
|
| 21 |
+
|
| 22 |
+
print(f"📊 Status HTTP: {status_code}")
|
| 23 |
+
|
| 24 |
+
if status_code == 200:
|
| 25 |
+
print("✅ FUNCIONANDO - Space está online e operacional")
|
| 26 |
+
return "working"
|
| 27 |
+
elif status_code == 503:
|
| 28 |
+
print("⚠️ SERVICE UNAVAILABLE - Space existe mas tem erro interno")
|
| 29 |
+
print(" 💡 Causas possíveis:")
|
| 30 |
+
print(" • Token HUGGINGFACE_TOKEN não configurado")
|
| 31 |
+
print(" • Erro no código da aplicação")
|
| 32 |
+
print(" • Modelo não conseguiu carregar")
|
| 33 |
+
return "error"
|
| 34 |
+
elif status_code == 404:
|
| 35 |
+
print("❌ NOT FOUND - Space não existe ou URL incorreta")
|
| 36 |
+
return "not_found"
|
| 37 |
+
elif status_code == 502:
|
| 38 |
+
print("⏳ BAD GATEWAY - Space está reiniciando")
|
| 39 |
+
return "restarting"
|
| 40 |
+
else:
|
| 41 |
+
print(f"❓ STATUS DESCONHECIDO: {status_code}")
|
| 42 |
+
return "unknown"
|
| 43 |
+
|
| 44 |
+
except requests.exceptions.Timeout:
|
| 45 |
+
print("⏰ TIMEOUT - Space não responde (pode estar carregando)")
|
| 46 |
+
return "timeout"
|
| 47 |
+
except requests.exceptions.ConnectionError:
|
| 48 |
+
print("❌ CONNECTION ERROR - Problema de rede ou space offline")
|
| 49 |
+
return "connection_error"
|
| 50 |
+
except Exception as e:
|
| 51 |
+
print(f"💥 ERRO INESPERADO: {e}")
|
| 52 |
+
return "unexpected_error"
|
| 53 |
+
|
| 54 |
+
def provide_solution(status):
|
| 55 |
+
"""Fornece soluções baseadas no status"""
|
| 56 |
+
print("\n🔧 PRÓXIMOS PASSOS:")
|
| 57 |
+
|
| 58 |
+
if status == "working":
|
| 59 |
+
print(" 🎉 Space funcionando perfeitamente!")
|
| 60 |
+
print(f" 🔗 Acesse: {SPACE_URL}")
|
| 61 |
+
|
| 62 |
+
elif status == "error":
|
| 63 |
+
print(" 🔑 Configurar token do Hugging Face:")
|
| 64 |
+
print(" 1. Acesse: https://huggingface.co/spaces/marcosremar2/pyannote-pt-diarization")
|
| 65 |
+
print(" 2. Vá em Settings → Variables and secrets")
|
| 66 |
+
print(" 3. Adicione HUGGINGFACE_TOKEN com o valor do seu token")
|
| 67 |
+
print(" 4. Aguarde 2-5 minutos para restart automático")
|
| 68 |
+
|
| 69 |
+
elif status == "not_found":
|
| 70 |
+
print(" ❗ Verificar se o space foi criado corretamente")
|
| 71 |
+
print(" 📝 URL esperada: https://huggingface.co/spaces/marcosremar2/pyannote-pt-diarization")
|
| 72 |
+
|
| 73 |
+
elif status in ["restarting", "timeout"]:
|
| 74 |
+
print(" ⏳ Aguardar alguns minutos e tentar novamente")
|
| 75 |
+
print(" 🔄 Space pode estar reiniciando após mudanças")
|
| 76 |
+
|
| 77 |
+
else:
|
| 78 |
+
print(" 🔍 Verificar logs do space no Hugging Face")
|
| 79 |
+
print(" 🆘 Se problema persistir, revisar configuração")
|
| 80 |
+
|
| 81 |
+
def main():
|
| 82 |
+
status = check_status()
|
| 83 |
+
provide_solution(status)
|
| 84 |
+
|
| 85 |
+
# Códigos de saída para automação
|
| 86 |
+
exit_codes = {
|
| 87 |
+
"working": 0,
|
| 88 |
+
"error": 1,
|
| 89 |
+
"not_found": 2,
|
| 90 |
+
"restarting": 1,
|
| 91 |
+
"timeout": 1,
|
| 92 |
+
"connection_error": 2,
|
| 93 |
+
"unexpected_error": 3
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
return exit_codes.get(status, 3)
|
| 97 |
+
|
| 98 |
+
if __name__ == "__main__":
|
| 99 |
+
exit_code = main()
|
| 100 |
+
print(f"\n📋 Exit Code: {exit_code}")
|
| 101 |
+
sys.exit(exit_code)
|