""" DataCrew AI - Interface Gradio para Hugging Face Spaces Análise Inteligente de Dados com IA Desenvolvido por: Gleison Leoni """ import gradio as gr import pandas as pd import os import requests import json import plotly.express as px import plotly.graph_objects as go # API Key Groq (será configurada pelo usuário) groq_api_key = None def initialize_groq(api_key): """Inicializa/valida a API key do Groq""" global groq_api_key if not api_key or not api_key.startswith('gsk_'): return "❌ API Key inválida! Deve começar com 'gsk_'" try: # Testar a API key com uma chamada simples headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } response = requests.post( "https://api.groq.com/openai/v1/chat/completions", headers=headers, json={ "model": "llama-3.3-70b-versatile", "messages": [{"role": "user", "content": "test"}], "max_tokens": 5 }, timeout=10 ) if response.status_code == 200: groq_api_key = api_key return "✅ API Key configurada com sucesso!" elif response.status_code == 401: return "❌ API Key inválida ou expirada" else: return f"❌ Erro: {response.status_code} - {response.text[:100]}" except requests.exceptions.Timeout: return "❌ Timeout - Verifique sua conexão" except Exception as e: return f"❌ Erro ao validar API Key: {str(e)}" def analyze_csv(file): """Analisa o arquivo CSV e retorna estatísticas""" if file is None: return "⚠️ Por favor, faça upload de um arquivo CSV primeiro.", None try: # Ler CSV df = pd.read_csv(file.name) # Análise básica analysis = f""" 📊 **Análise Automática do Dataset** **Dimensões:** - Linhas: {len(df):,} - Colunas: {len(df.columns)} - Tamanho: {df.memory_usage(deep=True).sum() / 1024:.2f} KB **Colunas ({len(df.columns)}):** {chr(10).join([f"• {col} ({df[col].dtype})" for col in df.columns])} **Valores Ausentes:** {df.isnull().sum().to_string() if df.isnull().sum().sum() > 0 else "✅ Nenhum valor ausente"} **Duplicatas:** {"✅ Nenhuma duplicata encontrada" if df.duplicated().sum() == 0 else f"⚠️ {df.duplicated().sum()} linhas duplicadas"} **Primeiras 10 Linhas:** """ # Retornar análise + preview dos dados return analysis, df.head(10) except Exception as e: return f"❌ Erro ao analisar CSV: {str(e)}", None def get_statistics(file): """Retorna estatísticas descritivas""" if file is None: return "⚠️ Faça upload de um CSV primeiro." try: df = pd.read_csv(file.name) # Estatísticas numéricas numeric_cols = df.select_dtypes(include=['number']).columns if len(numeric_cols) == 0: return "⚠️ Nenhuma coluna numérica encontrada no dataset." stats = f""" 📈 **Estatísticas Descritivas** **Colunas Numéricas: {len(numeric_cols)}** """ for col in numeric_cols: stats += f""" **{col}:** - Média: {df[col].mean():.2f} - Mediana: {df[col].median():.2f} - Desvio Padrão: {df[col].std():.2f} - Mínimo: {df[col].min():.2f} - Máximo: {df[col].max():.2f} - Q1 (25%): {df[col].quantile(0.25):.2f} - Q3 (75%): {df[col].quantile(0.75):.2f} """ return stats except Exception as e: return f"❌ Erro: {str(e)}" def create_visualization(file, chart_type, x_col, y_col): """Cria visualizações com Plotly""" if file is None: return None, "⚠️ Faça upload de um CSV primeiro." try: df = pd.read_csv(file.name) if x_col not in df.columns: return None, f"❌ Coluna '{x_col}' não encontrada no dataset.\n\nColunas disponíveis: {', '.join(df.columns)}" # Criar gráfico baseado no tipo if chart_type == "Histograma": fig = px.histogram(df, x=x_col, title=f"Distribuição de {x_col}", color_discrete_sequence=['#3B82F6']) elif chart_type == "Gráfico de Barras": value_counts = df[x_col].value_counts().head(20) fig = px.bar(x=value_counts.index, y=value_counts.values, labels={'x': x_col, 'y': 'Contagem'}, title=f"Contagem de {x_col}", color_discrete_sequence=['#8B5CF6']) elif chart_type == "Scatter Plot": if y_col and y_col in df.columns: fig = px.scatter(df, x=x_col, y=y_col, title=f"{x_col} vs {y_col}", color_discrete_sequence=['#EC4899']) else: return None, "❌ Para Scatter Plot, selecione duas colunas numéricas." elif chart_type == "Box Plot": fig = px.box(df, y=x_col, title=f"Box Plot de {x_col}", color_discrete_sequence=['#10B981']) elif chart_type == "Matriz de Correlação": numeric_df = df.select_dtypes(include=['number']) if len(numeric_df.columns) < 2: return None, "❌ Necessário pelo menos 2 colunas numéricas para matriz de correlação." corr = numeric_df.corr() fig = px.imshow(corr, text_auto=True, aspect="auto", title="Matriz de Correlação", color_continuous_scale='RdBu_r') else: return None, "❌ Tipo de gráfico não reconhecido." fig.update_layout( template="plotly_white", height=500, font=dict(size=12) ) return fig, f"✅ Gráfico '{chart_type}' gerado com sucesso!" except Exception as e: return None, f"❌ Erro ao criar visualização: {str(e)}" def ask_question(file, question, api_key): """Responde perguntas usando Groq via API HTTP""" global groq_api_key if not api_key: return "⚠️ Por favor, configure sua API Key do Groq primeiro na seção acima." if file is None: return "⚠️ Faça upload de um CSV primeiro." if not question: return "⚠️ Digite uma pergunta." try: # Atualizar API key se mudou if api_key != groq_api_key: result = initialize_groq(api_key) if "❌" in result: return result # Ler dados df = pd.read_csv(file.name) # Preparar contexto context = f""" Você é um analista de dados especializado. Responda a pergunta do usuário sobre este dataset de forma clara e objetiva. **Dataset:** {os.path.basename(file.name)} **Dimensões:** {len(df)} linhas × {len(df.columns)} colunas **Colunas e Tipos:** {chr(10).join([f"- {col}: {df[col].dtype} ({df[col].nunique()} valores únicos)" for col in df.columns])} **Amostra dos dados (5 primeiras linhas):** {df.head(5).to_string()} **Estatísticas das colunas numéricas:** {df.describe().to_string()} **Pergunta do usuário:** {question} Instruções para resposta: - Seja claro e objetivo - Use markdown para formatação - Destaque insights importantes com **negrito** - Se relevante, mencione números e estatísticas - Responda em português brasileiro """ # Chamar API Groq via HTTP headers = { "Authorization": f"Bearer {groq_api_key}", "Content-Type": "application/json" } payload = { "model": "llama-3.3-70b-versatile", "messages": [ {"role": "system", "content": "Você é um assistente especializado em análise de dados. Forneça respostas claras, objetivas e baseadas em dados."}, {"role": "user", "content": context} ], "temperature": 0.7, "max_tokens": 2000 } response = requests.post( "https://api.groq.com/openai/v1/chat/completions", headers=headers, json=payload, timeout=30 ) if response.status_code == 200: answer = response.json()['choices'][0]['message']['content'] return f"🤖 **Resposta da IA:**\n\n{answer}" else: return f"❌ Erro na API Groq ({response.status_code}): {response.text[:200]}" except requests.exceptions.Timeout: return "❌ Timeout - A IA demorou muito para responder. Tente novamente." except Exception as e: return f"❌ Erro ao processar pergunta: {str(e)}\n\nVerifique se sua API Key está correta." # ============================================================================ # Interface Gradio # ============================================================================ with gr.Blocks( theme=gr.themes.Soft( primary_hue="blue", secondary_hue="purple", ), title="DataCrew AI - Análise Inteligente de Dados", css=""" .gradio-container { font-family: 'Inter', sans-serif; } """ ) as demo: # Header gr.Markdown(""" # 🧠 DataCrew AI ### Análise Inteligente de Dados com Inteligência Artificial **Desenvolvido por:** Gleison Leoni | **Tecnologia:** Groq (LLaMA 3.3) + Pandas + Plotly Faça upload de um arquivo CSV e converse com seus dados usando IA de última geração! """) gr.Markdown("---") # API Key gr.Markdown("### 🔑 Configuração") gr.Markdown("Obtenha sua chave gratuita em: [console.groq.com](https://console.groq.com)") with gr.Row(): api_key_input = gr.Textbox( label="API Key do Groq", placeholder="gsk_...", type="password", scale=3 ) api_status = gr.Textbox(label="Status", interactive=False, scale=1) api_key_input.change( fn=initialize_groq, inputs=[api_key_input], outputs=[api_status] ) gr.Markdown("---") # Upload de arquivo gr.Markdown("### 📁 Upload do Dataset") file_input = gr.File( label="Arraste seu arquivo CSV aqui ou clique para fazer upload", file_types=[".csv"], type="filepath" ) gr.Markdown("---") # Tabs with gr.Tabs(): # Tab 1: Análise Automática with gr.Tab("📊 Análise Automática"): gr.Markdown(""" Clique no botão abaixo para obter uma análise completa do seu dataset: - Dimensões (linhas e colunas) - Tipos de dados - Valores ausentes e duplicatas - Preview dos dados """) analyze_btn = gr.Button("🔍 Analisar Dataset", variant="primary", size="lg") with gr.Row(): analysis_output = gr.Markdown(label="Análise") with gr.Row(): data_preview = gr.DataFrame(label="Preview dos Dados (10 primeiras linhas)") analyze_btn.click( fn=analyze_csv, inputs=[file_input], outputs=[analysis_output, data_preview] ) # Tab 2: Estatísticas with gr.Tab("📈 Estatísticas Descritivas"): gr.Markdown(""" Obtenha estatísticas detalhadas das colunas numéricas: - Média, mediana, desvio padrão - Valores mínimo e máximo - Quartis (25%, 75%) """) stats_btn = gr.Button("📊 Calcular Estatísticas", variant="primary", size="lg") stats_output = gr.Markdown(label="Estatísticas") stats_btn.click( fn=get_statistics, inputs=[file_input], outputs=[stats_output] ) # Tab 3: Visualizações with gr.Tab("📉 Gráficos e Visualizações"): gr.Markdown(""" Crie gráficos interativos dos seus dados: 1. Escolha o tipo de gráfico 2. Digite o nome da coluna (exatamente como aparece no CSV) 3. Clique em "Gerar Gráfico" """) with gr.Row(): chart_type = gr.Dropdown( choices=[ "Histograma", "Gráfico de Barras", "Scatter Plot", "Box Plot", "Matriz de Correlação" ], label="Tipo de Gráfico", value="Histograma" ) with gr.Row(): x_column = gr.Textbox( label="Coluna X", placeholder="Digite o nome exato da coluna", info="Para Histograma, Barras e Box Plot" ) y_column = gr.Textbox( label="Coluna Y (opcional)", placeholder="Apenas para Scatter Plot", info="Segunda coluna para comparação" ) create_chart_btn = gr.Button("📊 Gerar Gráfico", variant="primary", size="lg") chart_status = gr.Textbox(label="Status", interactive=False) with gr.Row(): chart_output = gr.Plot(label="Gráfico Interativo") create_chart_btn.click( fn=create_visualization, inputs=[file_input, chart_type, x_column, y_column], outputs=[chart_output, chart_status] ) # Tab 4: Chat com IA with gr.Tab("💬 Chat com IA"): gr.Markdown(""" ### Faça perguntas sobre seus dados em linguagem natural! A IA (LLaMA 3.3 70B via Groq) irá analisar seus dados e responder suas perguntas de forma inteligente. **💡 Exemplos de perguntas:** - "Quais são as principais estatísticas deste dataset?" - "Qual coluna tem mais valores ausentes?" - "Identifique possíveis outliers nos dados" - "Mostre insights sobre correlações entre variáveis" - "Faça uma análise exploratória completa" - "Sugira próximos passos para análise" """) question_input = gr.Textbox( label="❓ Sua Pergunta", placeholder="Digite sua pergunta sobre os dados...", lines=3 ) ask_btn = gr.Button("🤖 Perguntar à IA", variant="primary", size="lg") answer_output = gr.Markdown(label="Resposta da IA") # Exemplos de perguntas gr.Examples( examples=[ "Quais são as 5 principais estatísticas deste dataset?", "Identifique outliers nas colunas numéricas", "Mostre correlações entre as variáveis", "Faça uma análise exploratória completa dos dados", ], inputs=question_input, label="Clique em um exemplo para testar:" ) ask_btn.click( fn=ask_question, inputs=[file_input, question_input, api_key_input], outputs=[answer_output] ) # Footer gr.Markdown(""" --- ### 📚 Sobre este Projeto **DataCrew AI** é uma plataforma de análise inteligente de dados desenvolvida como parte do curso de Inteligência Artificial. **Tecnologias:** - 🤖 Groq (LLaMA 3.3 70B) - Processamento de linguagem natural - 🐼 Pandas - Manipulação de dados - 📊 Plotly - Visualizações interativas - 🎨 Gradio - Interface web **Desenvolvedor:** Gleison Leoni **Código Fonte:** [GitHub](https://github.com/gleison-leoni/datacrew-ai) """) # ============================================================================ # Executar # ============================================================================ if __name__ == "__main__": demo.launch()