Download utils.py from ArduinoYuri/Pandas_CSV_Analyzer-LlamaIndex: direct link, hf CLI and curl.
- Browser
- Download file 3.67 kB
-
https://huggingface.co/spaces/ArduinoYuri/Pandas_CSV_Analyzer-LlamaIndex/resolve/main/utils.py
- Command line
-
hf download hf://spaces/ArduinoYuri/Pandas_CSV_Analyzer-LlamaIndex/utils.py
-
curl -L -o utils.py https://huggingface.co/spaces/ArduinoYuri/Pandas_CSV_Analyzer-LlamaIndex/resolve/main/utils.py
3.67 kB
| # utils.py | |
| import pandas as pd | |
| import re | |
| import os | |
| import requests | |
| import matplotlib.font_manager as fm | |
| from pydantic import BaseModel, Field, ConfigDict | |
| from typing import List, Tuple, Optional | |
| from fpdf import FPDF | |
| from datetime import datetime | |
| # --- MODELOS PYDANTIC --- | |
| class Historico(BaseModel): | |
| entradas: List[Tuple[str, str]] = [] | |
| def adicionar(self, pergunta: str, resposta: str): | |
| if pergunta and resposta: | |
| self.entradas.append((pergunta, resposta)) | |
| # --- FUNÇÕES DE PROCESSAMENTO DE TEXTO E DADOS --- | |
| def descricao_colunas(df: pd.DataFrame) -> str: | |
| descricao = "\n".join([f"`{col}`: {str(df[col].dtype)}" for col in df.columns]) | |
| return "Colunas do DataFrame:\n" + descricao | |
| def limpar_codigo_pandas(codigo: str) -> str: | |
| codigo = re.sub(r'```(?:python)?\n?', '', codigo) | |
| codigo = re.sub(r'```', '', codigo) | |
| linhas = [linha.strip() for linha in codigo.split('\n') if linha.strip()] | |
| codigo_filtrado = [l for l in linhas if not (l.startswith('#') or 'resposta:' in l.lower())] | |
| return codigo_filtrado[-1] if codigo_filtrado else "" | |
| # --- LÓGICA DE PREPARAÇÃO DE FONTES --- | |
| FONT_PATH = "" | |
| def setup_font(): | |
| global FONT_PATH | |
| FONT_NAME_TO_FIND = "DejaVu Sans" | |
| try: | |
| FONT_PATH = fm.findfont(FONT_NAME_TO_FIND, fallback_to_default=True) | |
| if not os.path.exists(FONT_PATH): raise FileNotFoundError | |
| print(f"✅ Fonte encontrada localmente: {FONT_PATH}") | |
| except Exception: | |
| print(f"⚠️ Fonte '{FONT_NAME_TO_FIND}' não encontrada. Baixando alternativa (Roboto)...") | |
| FONT_FILE_NAME = "Roboto-Regular.ttf" | |
| FONT_URL = "https://github.com/google/fonts/raw/main/ofl/roboto/Roboto-Regular.ttf" | |
| if not os.path.exists(FONT_FILE_NAME): | |
| try: | |
| response = requests.get(FONT_URL) | |
| response.raise_for_status() | |
| with open(FONT_FILE_NAME, "wb") as f: f.write(response.content) | |
| FONT_PATH = FONT_FILE_NAME | |
| print(f"✅ Fonte alternativa baixada!") | |
| except Exception as e: | |
| print(f"❌ FALHA CRÍTICA ao baixar fonte: {e}") | |
| FONT_PATH = "" | |
| else: | |
| FONT_PATH = FONT_FILE_NAME | |
| print(f"✅ Fonte alternativa já existe.") | |
| return FONT_PATH | |
| # --- GERAÇÃO DE PDF --- | |
| def gerar_pdf_report(historico: Historico, font_path: str): | |
| if not historico or not historico.entradas: | |
| print("⚠️ Tentativa de gerar PDF com histórico vazio.") | |
| return None | |
| if not font_path or not os.path.exists(font_path): | |
| print(f"❌ Erro ao gerar PDF: Arquivo da fonte não encontrado em '{font_path}'.") | |
| return None | |
| try: | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| caminho_pdf = f"relatorio_consultas_{timestamp}.pdf" | |
| pdf = FPDF() | |
| pdf.add_page() | |
| pdf.add_font('CustomFont', '', font_path, uni=True) | |
| pdf.set_font('CustomFont', '', 16) | |
| pdf.cell(0, 10, "Relatório de Consultas ao CSV", ln=True, align="C") | |
| pdf.ln(10) | |
| for i, (pergunta, resposta) in enumerate(historico.entradas, 1): | |
| pdf.set_font('CustomFont', '', 12) | |
| pdf.multi_cell(0, 8, f"Pergunta {i}: {pergunta}") | |
| pdf.ln(2) | |
| pdf.set_font('CustomFont', '', 10) | |
| pdf.multi_cell(0, 6, f"Resposta: {resposta}") | |
| pdf.ln(8) | |
| pdf.cell(0, 0, '', 'T'); pdf.ln(8) | |
| pdf.output(caminho_pdf) | |
| print(f"✅ PDF gerado: {caminho_pdf}") | |
| return caminho_pdf | |
| except Exception as e: | |
| print(f"❌ Erro crítico ao gerar PDF: {e}") | |
| return None |