datachadd / app.py
namaai's picture
Update app.py
cf60754 verified
import os
import pandas as pd
import streamlit as st
from pandasai import SmartDataframe
from pandasai.responses.response_parser import ResponseParser
from pandasai.connectors import (
PostgreSQLConnector, MySQLConnector, SqliteConnector, SQLConnector
)
from pandasai.ee.connectors import SnowFlakeConnector,DatabricksConnector
from langchain_groq import ChatGroq
from groq import Groq
import chardet # For automatic encoding detection
# Set environment variable for Groq API key
os.environ["GROQ_API_KEY"] = os.getenv("GROQ_KEY")
# Initialize Groq client and ChatGroq model
client = Groq()
model = ChatGroq(temperature=0, model_name="llama-3.3-70b-versatile")
class StreamlitResponse(ResponseParser):
def __init__(self, context) -> None:
super().__init__(context)
def format_dataframe(self, result):
st.dataframe(result["value"])
return
def format_plot(self, result):
st.image(result["value"], width=900, use_column_width=True)
return
def format_other(self, result):
st.write(result["value"])
return
def detect_encoding(file):
# Detect file encoding
raw_data = file.read(1024) # Read a small portion of the file
result = chardet.detect(raw_data)
file.seek(0) # Reset file pointer to the beginning
return result['encoding']
def read_csv_with_encoding(file):
encodings = ['utf-8', 'latin1', 'iso-8859-1', 'utf-16', 'cp1252']
for encoding in encodings:
try:
file.seek(0)
df = pd.read_csv(file, encoding=encoding)
if not df.empty:
return df
except UnicodeDecodeError:
continue
except pd.errors.EmptyDataError:
st.error("The CSV file is empty or malformed.")
return None
except Exception as e:
st.error(f"An error occurred: {e}")
return None
st.error("Unable to decode the CSV file with common encodings.")
return None
def load_file(file) -> pd.DataFrame:
if file.type == "text/csv":
df = read_csv_with_encoding(file)
elif file.type == "application/json":
try:
df = pd.read_json(file)
except ValueError as e:
st.error(f"An error occurred while reading JSON file: {e}")
return None
except Exception as e:
st.error(f"An error occurred: {e}")
return None
elif file.type in ["application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]:
try:
df = pd.read_excel(file, engine='openpyxl') # Use engine for xlsx files
except Exception as e:
st.error(f"An error occurred while reading Excel file: {e}")
return None
else:
st.error("Unsupported file type. Please upload a CSV, JSON, or Excel file.")
return None
return df
# Initialize session state variables
if "show_db" not in st.session_state:
st.session_state.show_db = False
if "df" not in st.session_state:
st.session_state.df = None
# Streamlit application
st.write("# DATA CHAD")
st.write("This product belongs to NAMA AI")
# Sidebar for toggling between database and file upload
st.sidebar.title("Navigation")
option = st.sidebar.radio("Select Option", ["File Upload", "Database Connection"])
# Sidebar for toggling between database and file upload
if option == "File Upload":
st.session_state.show_db = False
uploaded_file = st.file_uploader("Upload your CSV, JSON, or Excel file", type=["csv", "xlsx", "xls"])
if uploaded_file:
# Load and display data
df = load_file(uploaded_file)
if df is not None:
with st.expander("🔎 Dataframe Preview"):
st.write(df)
# User input for chat query
query = st.text_area("🗣️ Chat with Dataframe")
container = st.container()
if query:
try:
llm = model
query_engine = SmartDataframe(
df,
config={
"llm": llm,
"response_parser": StreamlitResponse,
"code_to_run":True
},
)
except Exception as e:
st.error(f"An error occurred while processing the query: {e}")
if st.button("GENERATE"):
# Process query and display result
answer = query_engine.chat(f"provide formatted answer as you are business analyst {query} and provide most suitabole plot, and also explain plots and provide complete plot ignore null and irrelevant values")
if answer is not None:
st.title(f"👾 Here is your Analysis: {answer}")
else:
st.info("Please upload a CSV, JSON, or Excel file to get started.")
elif option == "Database Connection":
st.session_state.show_db = True
st.sidebar.title("Database Connection Configuration")
db_type = st.sidebar.selectbox("Select Database Type", ["PostgreSQL", "MySQL", "SQLite", "SQL", "Snowflake", "Databricks"])
# Database connection logic goes here (unchanged)
if db_type == "PostgreSQL":
host = st.sidebar.text_input("Host", "postgres")
port = st.sidebar.number_input("Port", 5432)
database = st.sidebar.text_input("Database", "mydb")
username = st.sidebar.text_input("Username", "root")
password = st.sidebar.text_input("Password", "root", type="password")
table = st.sidebar.text_input("Table", "payments")
where = st.sidebar.text_input("Filter (optional)", "[['payment_status', '=', 'PAIDOFF']]")
query= st.sidebar.text_input("Enter your Query")
if st.sidebar.button("Connect PostgreSQL"):
try:
where_clause = eval(where) if where else None
postgres_connector = PostgreSQLConnector(
config={
"host": host,
"port": port,
"database": database,
"username": username,
"password": password,
"table": table,
"where": where_clause,
}
)
df = SmartDataframe(postgres_connector)
st.session_state.df = df
st.success("Connected to PostgreSQL")
answer = df.chat(query)
st.title(answer)
except Exception as e:
st.error(f"An unexpected error occurred: {e}")
elif db_type == "MySQL":
host = st.sidebar.text_input("Host", "localhost")
port = st.sidebar.number_input("Port", 3306)
database = st.sidebar.text_input("Database", "mydb")
username = st.sidebar.text_input("Username", "root")
password = st.sidebar.text_input("Password", "root", type="password")
table = st.sidebar.text_input("Table", "loans")
where = st.sidebar.text_input("Filter (optional)", "[['loan_status', '=', 'PAIDOFF']]")
query= st.sidebar.text_input("Enter your Query")
if st.sidebar.button("Connect MySQL"):
try:
mysql_connector = MySQLConnector(
config={
"host": host,
"port": port,
"database": database,
"username": username,
"password": password,
"table": table,
"where": eval(where),
}
)
df = SmartDataframe(mysql_connector)
st.success("Connected to MySQL")
answer = df.chat(query)
st.title(answer)
except Exception as e :
st.error(f"An error occurred: {e}")
elif db_type == "SQLite":
database = st.sidebar.text_input("Database Path", "path_to_db")
table = st.sidebar.text_input("Table", "actor")
where = st.sidebar.text_input("Filter (optional)", "[['first_name', '=', 'PENELOPE']]")
query= st.sidebar.text_input("Enter your Query")
if st.sidebar.button("Connect SQLite"):
try:
sqlite_connector = SqliteConnector(
config={
"database": database,
"table": table,
"where": eval(where),
}
)
df = SmartDataframe(sqlite_connector)
st.success("Connected to SQLite")
except Exception as e:
st.error(f"An error occurred: {e}")
elif db_type == "SQL":
dialect = st.sidebar.text_input("Dialect", "sqlite")
driver = st.sidebar.text_input("Driver", "pysqlite")
host = st.sidebar.text_input("Host", "localhost")
port = st.sidebar.number_input("Port", 3306)
database = st.sidebar.text_input("Database", "mydb")
username = st.sidebar.text_input("Username", "root")
password = st.sidebar.text_input("Password", "root", type="password")
table = st.sidebar.text_input("Table", "loans")
where = st.sidebar.text_input("Filter (optional)", "[['loan_status', '=', 'PAIDOFF']]")
query= st.sidebar.text_input("Enter your Query")
if st.sidebar.button("Connect SQL"):
try:
sql_connector = SQLConnector(
config={
"dialect": dialect,
"driver": driver,
"host": host,
"port": port,
"database": database,
"username": username,
"password": password,
"table": table,
"where": eval(where),
}
)
df = SmartDataframe(sql_connector)
st.success("Connected to SQL")
answer = df.chat(query)
st.title(answer)
except Exception as e:
st.error(f"An error occurred: {e}")
elif db_type == "Snowflake":
account = st.sidebar.text_input("Account", "your_account")
database = st.sidebar.text_input("Database", "SNOWFLAKE_SAMPLE_DATA")
username = st.sidebar.text_input("Username", "test")
password = st.sidebar.text_input("Password", "*****", type="password")
table = st.sidebar.text_input("Table", "lineitem")
warehouse = st.sidebar.text_input("Warehouse", "COMPUTE_WH")
dbSchema = st.sidebar.text_input("Schema", "tpch_sf1")
where = st.sidebar.text_input("Filter (optional)", "[['l_quantity', '>', '49']]")
query= st.sidebar.text_input("Enter your Query")
if st.sidebar.button("Connect Snowflake"):
try:
snowflake_connector = SnowFlakeConnector(
config={
"account": account,
"database": database,
"username": username,
"password": password,
"table": table,
"warehouse": warehouse,
"dbSchema": dbSchema,
"where": eval(where),
}
)
df = SmartDataframe(snowflake_connector)
st.success("Connected to Snowflake")
answer = df.chat(query)
st.title(answer)
except Exception as e:
st.error(f"An error occurred: {e}")
elif db_type == "Databricks":
host = st.sidebar.text_input("Host", "adb-*****.azuredatabricks.net")
database = st.sidebar.text_input("Database", "default")
token = st.sidebar.text_input("Token", "dapidfd412321", type="password")
port = st.sidebar.number_input("Port", 443)
table = st.sidebar.text_input("Table", "loan_payments_data")
httpPath = st.sidebar.text_input("HTTP Path", "/sql/1.0/warehouses/213421312")
where = st.sidebar.text_input("Filter (optional)", "[['loan_status', '=', 'PAIDOFF']]")
query= st.sidebar.text_input("Enter your Query")
if st.sidebar.button("Connect Databricks"):
try:
databricks_connector = DatabricksConnector(
config={
"host": host,
"database": database,
"token": token,
"port": port,
"table": table,
"httpPath": httpPath,
"where": eval(where),
}
)
df = SmartDataframe(databricks_connector)
st.success("Connected to Databricks")
answer = df.chat(query)
st.title(answer)
except Exception as e:
st.error(f"An error occurred: {e}")
# Similar logic for other databases...
if st.session_state.df is not None:
with st.container():
query = st.text_area("🗣️ Chat with Dataframe")
if query:
try:
llm = model
query_engine = SmartDataframe(
st.session_state.df,
config={
"llm": llm,
"response_parser": StreamlitResponse,
"code_to_run": True
},
)
if st.button("GENERATE"):
answer = query_engine.chat(f"Provide formatted answer as you are a business analyst: {query} and provide the most suitable plot. Also, explain plots and provide a complete plot, ignoring null and irrelevant values.")
if answer is not None:
st.title(f"👾 Here is your Analysis: {answer}")
except Exception as e:
st.error(f"An error occurred while processing the query: {e}")