Homelander-AI / app.py
Dhanush7080's picture
Upload 3 files
0f1fdb9 verified
Raw
History Blame Contribute Delete
6.45 kB
import os
import pandas as pd
import matplotlib.pyplot as plt
from langchain_ollama import OllamaLLM
import gradio as gr
from fpdf import FPDF
# Initialize Homelander AI
ollama = OllamaLLM(base_url='http://localhost:11434', model="Homelander")
# Directory for uploads
UPLOAD_FOLDER = './uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
# Function to upload and read the file
def upload_file(file):
"""Reads and returns a Pandas DataFrame from a file."""
try:
# Check if the input is a file-like object or string
if isinstance(file, str): # If it's already a file path
file_path = file
else: # Save the file-like object to the server
file_path = os.path.join(UPLOAD_FOLDER, file.name)
with open(file_path, "wb") as f:
f.write(file.read())
# Load the file into a Pandas DataFrame
if file_path.endswith('.csv'):
return pd.read_csv(file_path), file_path
elif file_path.endswith('.xlsx'):
return pd.read_excel(file_path), file_path
else:
raise ValueError("Unsupported file format. Please upload a CSV or Excel file.")
except Exception as e:
raise ValueError(f"Error loading file: {e}")
def generate_plots(df):
"""
Generates meaningfull plots for all numeric and categorical columns in the dataset.
- Numeric columns: Histograms.
- Categorical columns: Bar charts (if unique values < 20).
"""
try:
num_cols = df.select_dtypes(include=['number']).columns.tolist()
cat_cols = df.select_dtypes(include=['object', 'category']).columns.tolist()
# Define plot size based on the number of subplots
total_plots = len(num_cols) + len(cat_cols)
if total_plots == 0:
return "No suitable columns to plot."
plt.figure(figsize=(12, 6 * total_plots))
# Plot numeric columns
for i, col in enumerate(num_cols):
plt.subplot(total_plots, 1, i + 1)
df[col].plot(kind='hist', bins=30, color='lightblue', edgecolor='black')
plt.title(f"Histogram of '{col}'")
plt.xlabel(col)
plt.ylabel("Frequency")
plt.grid(True)
# Plot categorical columns (only if unique values < 20 for readability)
for j, col in enumerate(cat_cols):
if df[col].nunique() < 20:
plt.subplot(total_plots, 1, len(num_cols) + j + 1)
df[col].value_counts().plot(kind='bar', color='lightcoral')
plt.title(f"Bar Plot of '{col}'")
plt.xlabel(col)
plt.ylabel("Count")
plt.xticks(rotation=45)
plt.grid(axis='y')
plt.tight_layout()
plot_path = os.path.join(UPLOAD_FOLDER, "full_dataset_plots.png")
plt.savefig(plot_path, dpi=300)
plt.close()
return plot_path
except Exception as e:
return None
# Function to query Homelander AI for insights
def query_homelander(file_path, question):
"""
Query Homelander to generate insights based on the user's question.
"""
prompt = f"""
Analyze the file '{file_path}' and provide detailed insights for the following question:
{question}
Ensure the response contains insights only, without Python code.
"""
try:
response = ollama(prompt)
return response.encode('utf-8').decode('utf-8') # Ensure proper encoding
except Exception as e:
raise ValueError(f"Error querying Homelander: {e}")
# Main analysis function
def analyze_file_and_plot(file, question):
"""
Main function to handle file upload, analysis, and graph generation.
"""
try:
# Load the uploaded file
df, file_path = upload_file(file)
# Query Homelander for insights
insights = query_homelander(file_path, question)
# Generate and display a basic plot (customize as needed)
plt.figure(figsize=(10, 6))
df.iloc[:, 0].value_counts().plot(kind='bar', color='skyblue')
plt.title("Sample Bar Plot of the First Column")
plt.xlabel("Categories")
plt.ylabel("Counts")
plot_path = os.path.join(UPLOAD_FOLDER, "plot.png")
plt.savefig(plot_path)
plt.close()
return insights, plot_path
except Exception as e:
return str(e), None
def chat_with_homelander(file=None, question=""):
try:
if not question.strip():
return "Please provide a question.", None, None # Adjusted for 3 outputs
plot_path = None
pdf_path = None
if file is not None:
df, file_path = upload_file(file)
plot_path = generate_plots(df)
insights = query_homelander(file_path, question)
pdf_path = save_insights_as_pdf(insights) # Generate PDF from insights
else:
insights = ollama.invoke(question).strip() # Correct way to query the AI
# Handle potential Unicode issues
insights = insights.encode('utf-8', 'ignore').decode('utf-8')
return insights, plot_path, pdf_path
except Exception as e:
return f"Error: {str(e)}", None, None
def save_insights_as_pdf(insights_text):
"""Generate a PDF from the insights and return the file path."""
pdf = FPDF()
pdf.set_auto_page_break(auto=True, margin=15)
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.multi_cell(0, 10, insights_text)
pdf_path = os.path.join(UPLOAD_FOLDER, "insights_report.pdf")
pdf.output(pdf_path)
return pdf_path
interface = gr.Interface(
fn=chat_with_homelander,
inputs=[
gr.File(label="Upload CSV or Excel File (Optional)"),
gr.Textbox(lines=2, placeholder="Enter your question", label="Question"),
],
outputs=[
gr.Textbox(label="Insights"),
gr.Image(type="filepath", label="Generated Plot"),
gr.File(label="Download Insights PDF"),
],
title="🤖Homelander AI Assistant",
description="Ask Homelander any question or upload a file to analyze and gain insights. "
"You can download the insights as a PDF.",
)
# Launch the interface
interface.launch()