marcosremar2 commited on
Commit
37b89b9
·
1 Parent(s): cca5942

Add basic test script for space connectivity

Browse files
Files changed (5) hide show
  1. .gitignore +20 -0
  2. README_TESTS.md +173 -0
  3. test_app.py +292 -0
  4. test_simple.py +234 -0
  5. 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)