fccoelho aider (anthropic/claude-sonnet-4-20250514) commited on
Commit
e998be0
·
1 Parent(s): 577fcf1

feat: implementar extrator de referências de PDFs com interface Gradio

Browse files

Co-authored-by: aider (anthropic/claude-sonnet-4-20250514) <aider@aider.chat>

Files changed (2) hide show
  1. app.py +136 -2
  2. pyproject.toml +7 -1
app.py CHANGED
@@ -1,6 +1,140 @@
1
- def main():
2
- print("Hello from reference-extractor!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  if __name__ == "__main__":
6
  main()
 
1
+ import gradio as gr
2
+ import PyPDF2
3
+ import pandas as pd
4
+ import openai
5
+ import os
6
+ from dotenv import load_dotenv
7
+ import io
8
+ import json
9
+ import re
10
+
11
+ def extract_pdf_text(pdf_file):
12
+ """Extrai texto e metadados básicos do PDF"""
13
+ try:
14
+ pdf_reader = PyPDF2.PdfReader(pdf_file)
15
+
16
+ # Extrair texto de todas as páginas
17
+ full_text = ""
18
+ for page in pdf_reader.pages:
19
+ full_text += page.extract_text() + "\n"
20
+
21
+ # Extrair metadados básicos
22
+ metadata = {
23
+ "num_pages": len(pdf_reader.pages),
24
+ "title": pdf_reader.metadata.get('/Title', 'Não disponível') if pdf_reader.metadata else 'Não disponível',
25
+ "author": pdf_reader.metadata.get('/Author', 'Não disponível') if pdf_reader.metadata else 'Não disponível'
26
+ }
27
+
28
+ return full_text, metadata
29
+ except Exception as e:
30
+ return None, {"error": f"Erro ao processar PDF: {str(e)}"}
31
+
32
+ def extract_references_with_llm(text):
33
+ """Usa OpenAI para extrair e estruturar referências"""
34
+ try:
35
+ client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
36
+
37
+ prompt = f"""
38
+ Analise o texto do artigo científico abaixo e extraia APENAS a seção de referências bibliográficas.
39
+
40
+ Para cada referência encontrada, extraia as seguintes informações em formato JSON:
41
+ - authors: lista de autores
42
+ - title: título do trabalho
43
+ - journal: nome da revista/conferência
44
+ - year: ano de publicação
45
+ - volume: volume (se disponível)
46
+ - pages: páginas (se disponível)
47
+ - doi: DOI (se disponível)
48
+
49
+ Retorne um array JSON com todas as referências encontradas.
50
+
51
+ Texto do artigo:
52
+ {text[:8000]} # Limita o texto para evitar exceder limites da API
53
+ """
54
+
55
+ response = client.chat.completions.create(
56
+ model="gpt-3.5-turbo",
57
+ messages=[{"role": "user", "content": prompt}],
58
+ temperature=0.1
59
+ )
60
+
61
+ # Extrair JSON da resposta
62
+ content = response.choices[0].message.content
63
+ # Procurar por JSON na resposta
64
+ json_match = re.search(r'\[.*\]', content, re.DOTALL)
65
+ if json_match:
66
+ references_data = json.loads(json_match.group())
67
+ return references_data
68
+ else:
69
+ return []
70
+
71
+ except Exception as e:
72
+ return [{"error": f"Erro ao processar com LLM: {str(e)}"}]
73
 
74
+ def process_pdf(pdf_file):
75
+ """Função principal que processa o PDF e retorna resultados"""
76
+ if pdf_file is None:
77
+ return {"error": "Nenhum arquivo enviado"}, pd.DataFrame()
78
+
79
+ # Extrair texto do PDF
80
+ text, metadata = extract_pdf_text(pdf_file)
81
+
82
+ if text is None:
83
+ return metadata, pd.DataFrame()
84
+
85
+ # Extrair referências com LLM
86
+ references = extract_references_with_llm(text)
87
+
88
+ # Converter para DataFrame
89
+ if references and not any("error" in ref for ref in references):
90
+ df = pd.DataFrame(references)
91
+ else:
92
+ df = pd.DataFrame({"Erro": ["Não foi possível extrair referências"]})
93
+
94
+ return metadata, df
95
+
96
+ def create_interface():
97
+ """Cria a interface Gradio"""
98
+ with gr.Blocks(title="Extrator de Referências") as interface:
99
+ gr.Markdown("# 📚 Extrator de Referências de Artigos Científicos")
100
+ gr.Markdown("Faça upload de um PDF de artigo científico para extrair automaticamente a lista de referências.")
101
+
102
+ with gr.Row():
103
+ pdf_input = gr.File(
104
+ label="📄 Upload do PDF",
105
+ file_types=[".pdf"],
106
+ type="binary"
107
+ )
108
+
109
+ extract_btn = gr.Button("🔍 Extrair Referências", variant="primary")
110
+
111
+ with gr.Row():
112
+ with gr.Column():
113
+ metadata_output = gr.JSON(label="📋 Metadados do Artigo")
114
+ with gr.Column():
115
+ references_output = gr.Dataframe(
116
+ label="📖 Lista de Referências",
117
+ wrap=True
118
+ )
119
+
120
+ extract_btn.click(
121
+ process_pdf,
122
+ inputs=[pdf_input],
123
+ outputs=[metadata_output, references_output]
124
+ )
125
+
126
+ return interface
127
+
128
+ def main():
129
+ load_dotenv() # Carrega variáveis de ambiente do arquivo .env
130
+
131
+ # Verificar se a chave da API está configurada
132
+ if not os.getenv("OPENAI_API_KEY"):
133
+ print("⚠️ AVISO: Chave da API OpenAI não encontrada!")
134
+ print("Crie um arquivo .env com: OPENAI_API_KEY=sua_chave_aqui")
135
+
136
+ interface = create_interface()
137
+ interface.launch(share=True)
138
 
139
  if __name__ == "__main__":
140
  main()
pyproject.toml CHANGED
@@ -4,4 +4,10 @@ version = "0.1.0"
4
  description = "Add your description here"
5
  readme = "README.md"
6
  requires-python = ">=3.12"
7
- dependencies = []
 
 
 
 
 
 
 
4
  description = "Add your description here"
5
  readme = "README.md"
6
  requires-python = ">=3.12"
7
+ dependencies = [
8
+ "gradio>=4.0.0",
9
+ "PyPDF2>=3.0.0",
10
+ "pandas>=2.0.0",
11
+ "openai>=1.0.0",
12
+ "python-dotenv>=1.0.0"
13
+ ]