Spaces:
Running
Running
| import gradio as gr | |
| import requests | |
| import os | |
| import json | |
| from typing import Dict, Any | |
| # Configuração da API | |
| HF_TOKEN = os.getenv("HF_TOKEN") | |
| if not HF_TOKEN: | |
| raise ValueError("Token HF_TOKEN não encontrado nas variáveis de ambiente") | |
| # Modelos disponíveis via API (testados e funcionais) | |
| MODELS = { | |
| "phi3-mini": "microsoft/Phi-3-mini-4k-instruct", | |
| "llama3.1-8b": "meta-llama/Llama-3.1-8B-Instruct", | |
| "gemma2-2b": "google/gemma-2-2b-it", | |
| "mistral-7b": "mistralai/Mistral-7B-Instruct-v0.3", | |
| } | |
| # Modelo padrão (mais confiável) | |
| DEFAULT_MODEL = MODELS["qwen2.5-3b"] | |
| class HuggingFaceAPIClient: | |
| def __init__(self, token: str): | |
| self.token = token | |
| self.headers = { | |
| "Authorization": f"Bearer {token}", | |
| "Content-Type": "application/json" | |
| } | |
| def query_model(self, model_name: str, messages: list, max_tokens: int = 500) -> str: | |
| """Faz requisição para a API do Hugging Face""" | |
| url = f"https://api-inference.huggingface.co/models/{model_name}/v1/chat/completions" | |
| payload = { | |
| "model": model_name, | |
| "messages": messages, | |
| "max_tokens": max_tokens, | |
| "temperature": 0.7, | |
| "top_p": 0.9, | |
| "stream": False | |
| } | |
| try: | |
| response = requests.post(url, headers=self.headers, json=payload, timeout=30) | |
| if response.status_code == 200: | |
| result = response.json() | |
| return result["choices"][0]["message"]["content"] | |
| else: | |
| # Fallback para API de texto simples se a API de chat não funcionar | |
| return self._fallback_text_generation(model_name, messages, max_tokens) | |
| except Exception as e: | |
| return f"Erro na API: {str(e)}" | |
| def _fallback_text_generation(self, model_name: str, messages: list, max_tokens: int) -> str: | |
| """Fallback usando API de geração de texto simples""" | |
| url = f"https://api-inference.huggingface.co/models/{model_name}" | |
| # Converte mensagens para prompt simples | |
| prompt = self._messages_to_prompt(messages) | |
| payload = { | |
| "inputs": prompt, | |
| "parameters": { | |
| "max_new_tokens": max_tokens, | |
| "temperature": 0.7, | |
| "top_p": 0.9, | |
| "do_sample": True, | |
| "return_full_text": False | |
| }, | |
| "options": { | |
| "wait_for_model": True, # Espera modelo carregar | |
| "use_cache": False | |
| } | |
| } | |
| try: | |
| response = requests.post(url, headers=self.headers, json=payload, timeout=60) | |
| if response.status_code == 200: | |
| result = response.json() | |
| if isinstance(result, list) and len(result) > 0: | |
| generated_text = result[0].get("generated_text", "") | |
| # Limpa o texto gerado | |
| if generated_text: | |
| # Remove o prompt original da resposta | |
| if "Assistente: " in generated_text: | |
| parts = generated_text.split("Assistente: ") | |
| if len(parts) > 1: | |
| return parts[-1].strip() | |
| return generated_text.strip() | |
| return "Resposta vazia" | |
| elif isinstance(result, dict): | |
| if "error" in result: | |
| return f"Erro do modelo: {result['error']}" | |
| elif "generated_text" in result: | |
| return result["generated_text"].strip() | |
| return "Formato de resposta inesperado" | |
| elif response.status_code == 404: | |
| return f"❌ Modelo '{model_name}' não encontrado. Tente outro modelo." | |
| elif response.status_code == 503: | |
| return "⏳ Modelo carregando... Aguarde alguns segundos e tente novamente." | |
| elif response.status_code == 429: | |
| return "⚠️ Muitas requisições. Aguarde um momento antes de tentar novamente." | |
| else: | |
| return f"Erro HTTP {response.status_code}: {response.text[:200]}..." | |
| except requests.Timeout: | |
| return "⏰ Timeout - Modelo demorou muito para responder. Tente novamente." | |
| except Exception as e: | |
| return f"Erro na requisição: {str(e)}" | |
| def _messages_to_prompt(self, messages: list) -> str: | |
| """Converte mensagens para formato de prompt""" | |
| prompt = "" | |
| for msg in messages: | |
| if msg["role"] == "system": | |
| prompt += f"Sistema: {msg['content']}\n\n" | |
| elif msg["role"] == "user": | |
| prompt += f"Usuário: {msg['content']}\n\n" | |
| elif msg["role"] == "assistant": | |
| prompt += f"Assistente: {msg['content']}\n\n" | |
| prompt += "Assistente: " | |
| return prompt | |
| # Inicializar cliente da API | |
| api_client = HuggingFaceAPIClient(HF_TOKEN) | |
| def responder_como_aldo(pergunta: str, modelo_escolhido: str = "qwen2.5-7b") -> str: | |
| """Função principal para gerar respostas via API""" | |
| if not pergunta.strip(): | |
| return "Por favor, faça uma pergunta." | |
| try: | |
| # Preparar mensagens | |
| pergunta += "Não responda nada se a pergunta não for sobre o universo de programação e tecnologia, informe que o Dr. Aldo Henrique só tem domínio em TI. Você é o Professor Dr. Aldo Henrique, foque em explicar e não em só mostrar o resultado. "+pergunta | |
| messages = [ | |
| { | |
| "role": "system", | |
| "content": "Você é o professor Dr. Aldo Henrique, especialista em C, Java, desenvolvimento web e inteligência artificial. Responda com clareza, profundidade e tom acadêmico, como um professor experiente. Evite respostas genéricas e forneça exemplos práticos quando aplicável. Foque em explicar e não em só mostrar o resultado. Responda sempre em português brasileiro. Não responda nada se a pergunta não for sobre o universo de programação e tecnologia" | |
| }, | |
| { | |
| "role": "user", | |
| "content": pergunta | |
| } | |
| ] | |
| # Escolher modelo | |
| model_name = MODELS.get(modelo_escolhido, DEFAULT_MODEL) | |
| # Fazer requisição | |
| resposta = api_client.query_model(model_name, messages, max_tokens=500) | |
| # Limpar resposta se necessário | |
| if resposta.startswith("Assistente: "): | |
| resposta = resposta.replace("Assistente: ", "") | |
| return resposta.strip() | |
| except Exception as e: | |
| return f"Erro ao processar sua pergunta: {str(e)}" | |
| def verificar_modelo_disponivel(model_name: str) -> str: | |
| """Verifica se um modelo está disponível na API""" | |
| try: | |
| url = f"https://api-inference.huggingface.co/models/{model_name}" | |
| headers = {"Authorization": f"Bearer {HF_TOKEN}"} | |
| # Teste simples | |
| payload = { | |
| "inputs": "Hello", | |
| "parameters": {"max_new_tokens": 5} | |
| } | |
| response = requests.post(url, headers=headers, json=payload, timeout=10) | |
| if response.status_code == 200: | |
| return "✅ Disponível" | |
| elif response.status_code == 404: | |
| return "❌ Não encontrado" | |
| elif response.status_code == 503: | |
| return "⏳ Carregando..." | |
| else: | |
| return f"⚠️ Status {response.status_code}" | |
| except Exception as e: | |
| return f"❌ Erro: {str(e)[:50]}..." | |
| def testar_todos_modelos(): | |
| """Testa todos os modelos disponíveis""" | |
| resultados = [] | |
| for nome, modelo in MODELS.items(): | |
| status = verificar_modelo_disponivel(modelo) | |
| resultados.append(f"{nome}: {status}") | |
| return "\n".join(resultados) | |
| # Interface Gradio | |
| with gr.Blocks(title="Dr. Aldo Henrique - API Externa", theme=gr.themes.Soft()) as interface: | |
| gr.Markdown("# 🤖 Pergunte ao Dr. Aldo Henrique") | |
| gr.Markdown("### Powered by Hugging Face API - Processamento na nuvem!") | |
| gr.Markdown("Dúvidas sobre C, Java, desenvolvimento web ou IA? O Dr. Aldo responde com clareza e profundidade.") | |
| with gr.Row(): | |
| with gr.Column(scale=3): | |
| entrada = gr.Textbox( | |
| label="Sua Pergunta", | |
| placeholder="Ex: Como usar ponteiros em C?", | |
| lines=4 | |
| ) | |
| modelo_select = gr.Dropdown( | |
| choices=list(MODELS.keys()), | |
| value="qwen2.5-7b", | |
| label="Modelo de IA", | |
| info="Escolha o modelo para responder" | |
| ) | |
| with gr.Row(): | |
| botao_perguntar = gr.Button("🤔 Perguntar", variant="primary") | |
| botao_testar = gr.Button("🔍 Testar Modelos", variant="secondary") | |
| with gr.Column(scale=4): | |
| saida = gr.Textbox( | |
| label="Resposta do Dr. Aldo", | |
| lines=12, | |
| interactive=False | |
| ) | |
| # Exemplos | |
| gr.Examples( | |
| examples=[ | |
| ["Como implementar uma lista ligada em C?", "qwen2.5-3b"], | |
| ["Qual a diferença entre == e equals() em Java?", "phi3-mini"], | |
| ["Como funciona o machine learning?", "llama3.2-3b"], | |
| ["Explique os conceitos de HTML, CSS e JavaScript", "mistral-7b"], | |
| ["O que são algoritmos de ordenação e qual é mais eficiente?", "gemma2-2b"] | |
| ], | |
| inputs=[entrada, modelo_select] | |
| ) | |
| # Status da API | |
| status_api = gr.Textbox( | |
| label="Status da API", | |
| interactive=False, | |
| visible=False | |
| ) | |
| # Eventos | |
| botao_perguntar.click( | |
| fn=responder_como_aldo, | |
| inputs=[entrada, modelo_select], | |
| outputs=saida | |
| ) | |
| botao_testar.click( | |
| fn=testar_todos_modelos, | |
| outputs=status_api | |
| ).then( | |
| lambda: gr.update(visible=True), | |
| outputs=status_api | |
| ) | |
| # Lançar aplicação | |
| if __name__ == "__main__": | |
| print("🚀 Iniciando Dr. Aldo Henrique com API Externa...") | |
| print(f"🔑 Token HF encontrado: {HF_TOKEN[:8]}...") | |
| print("🌐 Teste a conexão antes de usar!") | |
| interface.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| max_threads=8 # Pode aumentar já que não há processamento local pesado | |
| ) |