diff --git a/ai_agent_tutorials/ai_data_visualisation_agent/README.md b/ai_agent_tutorials/ai_data_visualisation_agent/README.md index e69de29..dc69328 100644 --- a/ai_agent_tutorials/ai_data_visualisation_agent/README.md +++ b/ai_agent_tutorials/ai_data_visualisation_agent/README.md @@ -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 + ``` + diff --git a/ai_agent_tutorials/ai_data_visualisation_agent/ai_data_visualisation_agent.py b/ai_agent_tutorials/ai_data_visualisation_agent/ai_data_visualisation_agent.py index 682cf09..5260b4e 100644 --- a/ai_agent_tutorials/ai_data_visualisation_agent/ai_data_visualisation_agent.py +++ b/ai_agent_tutorials/ai_data_visualisation_agent/ai_data_visualisation_agent.py @@ -6,7 +6,6 @@ import io import contextlib import warnings from typing import Optional, List, Any, Tuple -from dotenv import load_dotenv from PIL import Image import streamlit as st import pandas as pd @@ -15,40 +14,24 @@ from io import BytesIO from together import Together from e2b_code_interpreter import Sandbox -# Suppress Pydantic warnings globally warnings.filterwarnings("ignore", category=UserWarning, module="pydantic") -# Regex pattern to extract code from LLM response pattern = re.compile(r"```python\n(.*?)\n```", re.DOTALL) 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...'): - # Capture stdout and stderr stdout_capture = io.StringIO() stderr_capture = io.StringIO() with contextlib.redirect_stdout(stdout_capture), contextlib.redirect_stderr(stderr_capture): - # Suppress warnings during code execution with warnings.catch_warnings(): warnings.simplefilter("ignore") exec = e2b_code_interpreter.run_code(code) - # Log stderr (warnings and errors) to the terminal if stderr_capture.getvalue(): print("[Code Interpreter Warnings/Errors]", file=sys.stderr) print(stderr_capture.getvalue(), file=sys.stderr) - # Log stdout (normal output) to the terminal if stdout_capture.getvalue(): print("[Code Interpreter Output]", 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 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) if match: code = match.group(1) @@ -75,17 +49,6 @@ def match_code_blocks(llm_response: str) -> str: return "" 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 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. @@ -114,16 +77,6 @@ IMPORTANT: Always use the dataset path variable '{dataset_path}' in your code wh return None, response_message.content 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}" try: @@ -139,11 +92,22 @@ def main(): st.title("AI Data Visualization Agent") 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: 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.e2b_api_key = st.text_input("Enter E2B API Key", type="password") + st.session_state.together_api_key = st.sidebar.text_input("Together AI 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 model_options = { @@ -152,12 +116,12 @@ def main(): "Qwen 2.5 7B": "Qwen/Qwen2.5-7B-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", options=list(model_options.keys()), 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") diff --git a/ai_agent_tutorials/ai_data_visualisation_agent/requirements.txt b/ai_agent_tutorials/ai_data_visualisation_agent/requirements.txt index 8019c78..2ec4fbe 100644 --- a/ai_agent_tutorials/ai_data_visualisation_agent/requirements.txt +++ b/ai_agent_tutorials/ai_data_visualisation_agent/requirements.txt @@ -1,9 +1,7 @@ -together>=0.2.8 -e2b>=0.12.0 -python-dotenv -Pillow +together==1.3.10 +e2b-code-interpreter==1.0.3 +e2b==1.0.5 +Pillow==10.4.0 streamlit pandas matplotlib -plotly -seaborn>=0.12.0 \ No newline at end of file