Spaces:
Sleeping
Sleeping
File size: 8,262 Bytes
9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 4aff160 9c22a69 | 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 | import requests
import gradio as gr
import os
import uuid
import PyPDF2
from PIL import Image
import imageio
import random
from gtts import gTTS
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.styles import getSampleStyleSheet
# Configuração da API do Google Gemini
API_KEYS = [
'AIzaSyAgmf1ZvNrvzAmlNCQvQbyZDJJPdMwecqY',
'AIzaSyB18Z-Ct2-IKYGZ9vKaChcee-BDVS77Ksg',
'AIzaSyBB5Tp0xdXcemLMGDm8_cL6L37wTe_8sjg',
'AIzaSyCefvhXMsgHmAF_0KVkZ0UAeZ5nNC41v-A',
]
def escolher_chave_api():
return random.choice(API_KEYS)
GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={}"
class AssistenteAcademico:
def __init__(self):
self.contexto_atual = {}
self.ultima_imagem_path = None
self.pasta_temp = 'assistente_temp'
for pasta in [self.pasta_temp, 'audios_assistente', 'pdfs_respostas']:
os.makedirs(pasta, exist_ok=True)
def gerar_pdf_resposta(self, texto, nome_arquivo=None):
try:
nome_arquivo = nome_arquivo or f'resposta_{uuid.uuid4()}.pdf'
caminho_pdf = os.path.join('pdfs_respostas', nome_arquivo)
doc = SimpleDocTemplate(caminho_pdf, pagesize=letter)
styles = getSampleStyleSheet()
story = [Paragraph(texto.replace('\n', '<br/>'), styles['Normal'])]
doc.build(story)
return caminho_pdf
except Exception as e:
return f"Erro ao criar PDF: {str(e)}"
def texto_para_audio(self, texto, nome_arquivo=None):
try:
nome_arquivo = nome_arquivo or f'audio_{uuid.uuid4()}.mp3'
caminho_audio = os.path.join('audios_assistente', nome_arquivo)
tts = gTTS(texto, lang='pt-br')
tts.save(caminho_audio)
return caminho_audio
except Exception as e:
return f"Erro ao criar áudio: {str(e)}"
def codificar_imagem(self, imagem_path):
try:
if not os.path.exists(imagem_path):
raise ValueError("Arquivo de imagem não encontrado")
extensao = os.path.splitext(imagem_path)[1].lower()
formatos_suportados = {'.png', '.jpg', '.jpeg', '.bmp', '.gif', '.tiff', '.webp'}
if extensao not in formatos_suportados:
raise ValueError(f"Formato de imagem não suportado: {extensao}")
imagem = imageio.imread(imagem_path)
imagem_pil = Image.fromarray(imagem)
imagem_pil.thumbnail((800, 800), Image.Resampling.LANCZOS)
temp_path = os.path.join(self.pasta_temp, f'temp_image_{uuid.uuid4()}{extensao}')
imagem_pil.convert('RGB').save(temp_path, quality=95)
return temp_path
except Exception as e:
return f"Erro ao codificar imagem: {str(e)}"
def extrair_texto_pdf(self, arquivo_pdf):
try:
if not arquivo_pdf or not os.path.exists(arquivo_pdf):
return "Nenhum PDF válido fornecido"
leitor_pdf = PyPDF2.PdfReader(arquivo_pdf)
texto = "\n".join(pagina.extract_text() or "" for pagina in leitor_pdf.pages)
return texto if texto.strip() else "Nenhum texto extraído do PDF"
except Exception as e:
return f"Erro ao extrair texto do PDF: {str(e)}"
def processar_input(self, pergunta, pdf=None, imagem=None):
try:
if not pergunta:
return "Por favor, forneça uma pergunta", None, None
# Preparar o conteúdo para a API
conteudo = [{"role": "user", "parts": [{"text": self.contexto_atual.get('pdf_texto', '')}]}]
if pdf:
texto_pdf = self.extrair_texto_pdf(pdf)
self.contexto_atual['pdf_texto'] = texto_pdf
conteudo[0]["parts"].append({"text": texto_pdf})
if imagem:
if self.ultima_imagem_path and os.path.exists(self.ultima_imagem_path):
os.remove(self.ultima_imagem_path)
imagem_path = self.codificar_imagem(imagem)
if isinstance(imagem_path, str) and os.path.exists(imagem_path):
self.ultima_imagem_path = imagem_path
with open(imagem_path, "rb") as img_file:
conteudo[0]["parts"].append({
"inline_data": {
"mime_type": f"image/{os.path.splitext(imagem_path)[1][1:]}",
"data": base64.b64encode(img_file.read()).decode('utf-8')
}
})
prompt = f"""Como um assistente acadêmico avançado:
- Seja objetivo e acadêmico
- Forneça explicações claras
- Use linguagem técnica quando apropriado
- Cite referências se possível
- Mantenha a explicação acessível
Pergunta atual: {pergunta}
"""
conteudo[0]["parts"].append({"text": prompt})
# Fazer a requisição à API
headers = {"Content-Type": "application/json"}
api_key = escolher_chave_api()
response = requests.post(
GEMINI_API_URL.format(api_key),
json={"contents": conteudo},
headers=headers
)
if response.status_code != 200:
return f"Erro na API: {response.status_code} - {response.text}", None, None
resposta_json = response.json()
texto_resposta = resposta_json["candidates"][0]["content"]["parts"][0]["text"]
caminho_audio = self.texto_para_audio(texto_resposta)
caminho_pdf = self.gerar_pdf_resposta(texto_resposta)
return texto_resposta, caminho_audio, caminho_pdf
except Exception as e:
return f"Erro no processamento: {str(e)}", None, None
def limpar_arquivos_temporarios(self):
import time
pastas = [self.pasta_temp, 'audios_assistente', 'pdfs_respostas']
for pasta in pastas:
for arquivo in os.listdir(pasta):
caminho = os.path.join(pasta, arquivo)
if os.path.isfile(caminho) and time.time() - os.path.getctime(caminho) > 3600:
try:
os.remove(caminho)
except:
pass
def chatbot_interface(self):
with gr.Blocks(title="Assistente Acadêmico") as interface:
gr.Markdown("# 🎓 Assistente Acadêmico\nFaça suas perguntas e carregue arquivos para análise.")
chatbot = gr.Chatbot(label="Conversa")
with gr.Row():
audio_output = gr.Audio(label="Resposta em Áudio")
pdf_output = gr.File(label="Resposta em PDF")
with gr.Row():
msg = gr.Textbox(label="Pergunta", placeholder="Digite sua pergunta...")
pdf_input = gr.File(file_types=['.pdf'], label="Carregar PDF")
img_input = gr.File(file_types=['.png', '.jpg', '.jpeg', '.bmp', '.gif', '.tiff', '.webp'],
label="Carregar Imagem")
submit_btn = gr.Button("Enviar")
def responder(mensagem, historico, pdf=None, imagem=None):
resposta, audio, pdf_file = self.processar_input(mensagem, pdf, imagem)
historico.append((mensagem, resposta))
self.limpar_arquivos_temporarios()
return "", historico, audio, pdf_file
submit_btn.click(
fn=responder,
inputs=[msg, chatbot, pdf_input, img_input],
outputs=[msg, chatbot, audio_output, pdf_output]
)
return interface
if __name__ == "__main__":
assistente = AssistenteAcademico()
interface = assistente.chatbot_interface()
print("🚀 Assistente Acadêmico inicializado!")
interface.launch(debug=True, share=True) |