completed all files
This commit is contained in:
parent
9fd044b81e
commit
e2eec7e80f
3 changed files with 59 additions and 58 deletions
|
|
@ -0,0 +1,39 @@
|
||||||
|
# AI Data Visualization Agent
|
||||||
|
|
||||||
|
This Assistant is designed to help anyone create and visualize data using natural language commands, and it is built using Together AI and E2B Code Interpreter. User gets to upload a dataset and ask questions to the LLM to get the data visualized. This demo can be considered as a demo for the E2B Code Interpreter and Together AI, for anyone who's getting started with these libraries!
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- 🎨 Natural language-driven visualization creation
|
||||||
|
- 📊 Support for multiple chart types (line, bar, scatter, pie, bubble)
|
||||||
|
- 📈 Automatic data preprocessing and cleaning
|
||||||
|
- 🎯 Available Models:
|
||||||
|
- Meta-Llama 3.1 405B
|
||||||
|
- DeepSeek V3
|
||||||
|
- Qwen 2.5 7B
|
||||||
|
- Meta-Llama 3.3 70B
|
||||||
|
- 📱 The Code runs in the E2B Sandbox environment, so it is secure and fast
|
||||||
|
- Streamlit for clear and interactive user interface
|
||||||
|
|
||||||
|
## How to Run
|
||||||
|
|
||||||
|
Follow the steps below to set up and run the application:
|
||||||
|
Before anything else, Please get a free Together AI API Key here: https://api.together.ai/signin
|
||||||
|
Get a free E2B API Key here: https://e2b.dev/ ; https://e2b.dev/docs/legacy/getting-started/api-key
|
||||||
|
|
||||||
|
1. **Clone the Repository**:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/Shubhamsaboo/awesome-llm-apps.git
|
||||||
|
cd ai_agent_tutorials/ai_data_visualisation_agent
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install the dependencies**
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Run the Streamlit app**
|
||||||
|
```bash
|
||||||
|
streamlit run ai_data_visualisation_agent.py
|
||||||
|
```
|
||||||
|
|
||||||
|
|
@ -6,7 +6,6 @@ import io
|
||||||
import contextlib
|
import contextlib
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Optional, List, Any, Tuple
|
from typing import Optional, List, Any, Tuple
|
||||||
from dotenv import load_dotenv
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
@ -15,40 +14,24 @@ from io import BytesIO
|
||||||
from together import Together
|
from together import Together
|
||||||
from e2b_code_interpreter import Sandbox
|
from e2b_code_interpreter import Sandbox
|
||||||
|
|
||||||
# Suppress Pydantic warnings globally
|
|
||||||
warnings.filterwarnings("ignore", category=UserWarning, module="pydantic")
|
warnings.filterwarnings("ignore", category=UserWarning, module="pydantic")
|
||||||
|
|
||||||
# Regex pattern to extract code from LLM response
|
|
||||||
pattern = re.compile(r"```python\n(.*?)\n```", re.DOTALL)
|
pattern = re.compile(r"```python\n(.*?)\n```", re.DOTALL)
|
||||||
|
|
||||||
def code_interpret(e2b_code_interpreter: Sandbox, code: str) -> Optional[List[Any]]:
|
def code_interpret(e2b_code_interpreter: Sandbox, code: str) -> Optional[List[Any]]:
|
||||||
"""
|
|
||||||
Runs the given Python code in the E2B sandbox.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
e2b_code_interpreter: The E2B sandbox instance
|
|
||||||
code: Python code to execute
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Optional[List[Any]]: Results from code execution
|
|
||||||
"""
|
|
||||||
with st.spinner('Executing code in E2B sandbox...'):
|
with st.spinner('Executing code in E2B sandbox...'):
|
||||||
# Capture stdout and stderr
|
|
||||||
stdout_capture = io.StringIO()
|
stdout_capture = io.StringIO()
|
||||||
stderr_capture = io.StringIO()
|
stderr_capture = io.StringIO()
|
||||||
|
|
||||||
with contextlib.redirect_stdout(stdout_capture), contextlib.redirect_stderr(stderr_capture):
|
with contextlib.redirect_stdout(stdout_capture), contextlib.redirect_stderr(stderr_capture):
|
||||||
# Suppress warnings during code execution
|
|
||||||
with warnings.catch_warnings():
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter("ignore")
|
warnings.simplefilter("ignore")
|
||||||
exec = e2b_code_interpreter.run_code(code)
|
exec = e2b_code_interpreter.run_code(code)
|
||||||
|
|
||||||
# Log stderr (warnings and errors) to the terminal
|
|
||||||
if stderr_capture.getvalue():
|
if stderr_capture.getvalue():
|
||||||
print("[Code Interpreter Warnings/Errors]", file=sys.stderr)
|
print("[Code Interpreter Warnings/Errors]", file=sys.stderr)
|
||||||
print(stderr_capture.getvalue(), file=sys.stderr)
|
print(stderr_capture.getvalue(), file=sys.stderr)
|
||||||
|
|
||||||
# Log stdout (normal output) to the terminal
|
|
||||||
if stdout_capture.getvalue():
|
if stdout_capture.getvalue():
|
||||||
print("[Code Interpreter Output]", file=sys.stdout)
|
print("[Code Interpreter Output]", file=sys.stdout)
|
||||||
print(stdout_capture.getvalue(), file=sys.stdout)
|
print(stdout_capture.getvalue(), file=sys.stdout)
|
||||||
|
|
@ -59,15 +42,6 @@ def code_interpret(e2b_code_interpreter: Sandbox, code: str) -> Optional[List[An
|
||||||
return exec.results
|
return exec.results
|
||||||
|
|
||||||
def match_code_blocks(llm_response: str) -> str:
|
def match_code_blocks(llm_response: str) -> str:
|
||||||
"""
|
|
||||||
Extracts Python code blocks from the LLM response.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
llm_response: The response from the LLM
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Extracted Python code or empty string
|
|
||||||
"""
|
|
||||||
match = pattern.search(llm_response)
|
match = pattern.search(llm_response)
|
||||||
if match:
|
if match:
|
||||||
code = match.group(1)
|
code = match.group(1)
|
||||||
|
|
@ -75,17 +49,6 @@ def match_code_blocks(llm_response: str) -> str:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def chat_with_llm(e2b_code_interpreter: Sandbox, user_message: str, dataset_path: str) -> Tuple[Optional[List[Any]], str]:
|
def chat_with_llm(e2b_code_interpreter: Sandbox, user_message: str, dataset_path: str) -> Tuple[Optional[List[Any]], str]:
|
||||||
"""
|
|
||||||
Sends the user message to the LLM and executes the generated code.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
e2b_code_interpreter: The E2B sandbox instance
|
|
||||||
user_message: User's query message
|
|
||||||
dataset_path: Path to the uploaded dataset
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Tuple[Optional[List[Any]], str]: Code execution results and LLM response
|
|
||||||
"""
|
|
||||||
# Update system prompt to include dataset path information
|
# Update system prompt to include dataset path information
|
||||||
system_prompt = f"""You're a Python data scientist and data visualization expert. You are given a dataset at path '{dataset_path}' and also the user's query.
|
system_prompt = f"""You're a Python data scientist and data visualization expert. You are given a dataset at path '{dataset_path}' and also the user's query.
|
||||||
You need to analyze the dataset and answer the user's query with a response and you run Python code to solve them.
|
You need to analyze the dataset and answer the user's query with a response and you run Python code to solve them.
|
||||||
|
|
@ -114,16 +77,6 @@ IMPORTANT: Always use the dataset path variable '{dataset_path}' in your code wh
|
||||||
return None, response_message.content
|
return None, response_message.content
|
||||||
|
|
||||||
def upload_dataset(code_interpreter: Sandbox, uploaded_file) -> str:
|
def upload_dataset(code_interpreter: Sandbox, uploaded_file) -> str:
|
||||||
"""
|
|
||||||
Uploads the dataset to the E2B sandbox.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
code_interpreter: The E2B sandbox instance
|
|
||||||
uploaded_file: Streamlit uploaded file
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Path where file was uploaded
|
|
||||||
"""
|
|
||||||
dataset_path = f"./{uploaded_file.name}"
|
dataset_path = f"./{uploaded_file.name}"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -139,11 +92,22 @@ def main():
|
||||||
st.title("AI Data Visualization Agent")
|
st.title("AI Data Visualization Agent")
|
||||||
st.write("Upload your dataset and ask questions about it!")
|
st.write("Upload your dataset and ask questions about it!")
|
||||||
|
|
||||||
# Sidebar for API keys and model selection
|
# Initialize session state variables
|
||||||
|
if 'together_api_key' not in st.session_state:
|
||||||
|
st.session_state.together_api_key = ''
|
||||||
|
if 'e2b_api_key' not in st.session_state:
|
||||||
|
st.session_state.e2b_api_key = ''
|
||||||
|
if 'model_name' not in st.session_state:
|
||||||
|
st.session_state.model_name = ''
|
||||||
|
|
||||||
with st.sidebar:
|
with st.sidebar:
|
||||||
st.header("API Keys and Model Configuration")
|
st.header("API Keys and Model Configuration")
|
||||||
st.session_state.together_api_key = st.text_input("Enter Together API Key", type="password")
|
st.session_state.together_api_key = st.sidebar.text_input("Together AI API Key", type="password")
|
||||||
st.session_state.e2b_api_key = st.text_input("Enter E2B API Key", type="password")
|
st.sidebar.info("💡 Everyone gets a free $1 credit by Together AI - AI Acceleration Cloud platform")
|
||||||
|
st.sidebar.markdown("[Get Together AI API Key](https://api.together.ai/signin)")
|
||||||
|
|
||||||
|
st.session_state.e2b_api_key = st.sidebar.text_input("Enter E2B API Key", type="password")
|
||||||
|
st.sidebar.markdown("[Get E2B API Key](https://e2b.dev/docs/legacy/getting-started/api-key)")
|
||||||
|
|
||||||
# Add model selection dropdown
|
# Add model selection dropdown
|
||||||
model_options = {
|
model_options = {
|
||||||
|
|
@ -152,12 +116,12 @@ def main():
|
||||||
"Qwen 2.5 7B": "Qwen/Qwen2.5-7B-Instruct-Turbo",
|
"Qwen 2.5 7B": "Qwen/Qwen2.5-7B-Instruct-Turbo",
|
||||||
"Meta-Llama 3.3 70B": "meta-llama/Llama-3.3-70B-Instruct-Turbo"
|
"Meta-Llama 3.3 70B": "meta-llama/Llama-3.3-70B-Instruct-Turbo"
|
||||||
}
|
}
|
||||||
selected_model = st.selectbox(
|
st.session_state.model_name = st.selectbox(
|
||||||
"Select Model",
|
"Select Model",
|
||||||
options=list(model_options.keys()),
|
options=list(model_options.keys()),
|
||||||
index=0 # Default to first option
|
index=0 # Default to first option
|
||||||
)
|
)
|
||||||
st.session_state.model_name = model_options[selected_model]
|
st.session_state.model_name = model_options[st.session_state.model_name]
|
||||||
|
|
||||||
uploaded_file = st.file_uploader("Choose a CSV file", type="csv")
|
uploaded_file = st.file_uploader("Choose a CSV file", type="csv")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
together>=0.2.8
|
together==1.3.10
|
||||||
e2b>=0.12.0
|
e2b-code-interpreter==1.0.3
|
||||||
python-dotenv
|
e2b==1.0.5
|
||||||
Pillow
|
Pillow==10.4.0
|
||||||
streamlit
|
streamlit
|
||||||
pandas
|
pandas
|
||||||
matplotlib
|
matplotlib
|
||||||
plotly
|
|
||||||
seaborn>=0.12.0
|
|
||||||
Loading…
Reference in a new issue