├── .env ├── opus-interpreter.py ├── readme.md └── requirements.txt /.env: -------------------------------------------------------------------------------- 1 | ANTHROPIC_API_KEY= 2 | E2B_API_KEY= 3 | -------------------------------------------------------------------------------- /opus-interpreter.py: -------------------------------------------------------------------------------- 1 | import os 2 | import base64 3 | from dotenv import load_dotenv 4 | import matplotlib.pyplot as plt 5 | import numpy as np 6 | from anthropic import Anthropic 7 | from typing import List, Tuple 8 | from e2b_code_interpreter import CodeInterpreter, Result 9 | from e2b_code_interpreter.models import Logs 10 | from e2b import Sandbox 11 | 12 | # Load the .env file 13 | load_dotenv() 14 | 15 | # Set up the Anthropic client 16 | client = Anthropic() 17 | 18 | # Initialize the Sandbox 19 | sandbox = Sandbox(template="base") 20 | 21 | # Define the model name, system prompt, and tools 22 | MODEL_NAME = "claude-3-opus-20240229" 23 | 24 | SYSTEM_PROMPT = """ 25 | ## your job & context 26 | you are a python data scientist. you are given tasks to complete and you run python code to solve them. 27 | - the python code runs in jupyter notebook. 28 | - every time you call `execute_python` tool, the python code is executed in a separate cell. it's okay to make multiple calls to `execute_python`. 29 | - display visualizations using matplotlib or any other visualization library directly in the notebook. don't worry about saving the visualizations to a file. 30 | - you have access to the internet and can make api requests. 31 | - you also have access to the filesystem and can read/write files. 32 | - you can install any pip package (if it exists) if you need to but the usual packages for data analysis are already preinstalled. 33 | - you can run any python code you want, everything is running in a secure sandbox environment. 34 | """ 35 | 36 | tools = [ 37 | { 38 | "name": "execute_python", 39 | "description": "Execute python code in a Jupyter notebook cell and returns any result, stdout, stderr, display_data, and error.", 40 | "input_schema": { 41 | "type": "object", 42 | "properties": { 43 | "code": { 44 | "type": "string", 45 | "description": "The python code to execute in a single cell." 46 | } 47 | }, 48 | "required": ["code"] 49 | } 50 | } 51 | ] 52 | 53 | def code_interpret(code_interpreter: CodeInterpreter, code: str): 54 | print(f"\n{'='*50}\n> Running following AI-generated code:\n{code}\n{'='*50}") 55 | execution = code_interpreter.notebook.exec_cell(code) 56 | 57 | if execution.error: 58 | error_message = f"There was an error during execution: {execution.error.name}: {execution.error.value}.\n{execution.error.traceback}" 59 | print("[Code Interpreter error]", error_message) 60 | return [], Logs(), error_message, [] 61 | 62 | result_message = "" 63 | saved_files = [] 64 | 65 | if execution.results: 66 | result_message = "These are results of the execution:\n" 67 | counter = 1 68 | for result in execution.results: 69 | result_message += f"Result {counter}:\n" 70 | if result.is_main_result: 71 | result_message += f"[Main result]: {result.text}\n" 72 | else: 73 | result_message += f"[Display data]: {result.text}\n" 74 | 75 | # Check if the result has any file data and dynamically decide the filename and format 76 | file_saved = False 77 | for file_type in ['png', 'jpeg', 'svg', 'pdf', 'html', 'json', 'javascript', 'markdown', 'latex']: 78 | if getattr(result, file_type, None): 79 | file_extension = file_type 80 | file_data = getattr(result, file_type) 81 | file_path = f"/home/user/output_file_{counter}.{file_extension}" 82 | local_filename = f"output_file_{counter}.{file_extension}" 83 | 84 | try: 85 | # Write file inside sandbox if it's not already a downloadable type 86 | if not file_saved: 87 | sandbox_path = f"/home/user/output_file_{counter}.{file_extension}" 88 | sandbox.filesystem.write_bytes(sandbox_path, base64.b64decode(file_data)) 89 | file_saved = True 90 | 91 | # Download file 92 | file_in_bytes = sandbox.download_file(sandbox_path) 93 | with open(local_filename, "wb") as file: 94 | file.write(file_in_bytes) 95 | saved_files.append(local_filename) 96 | print(f"Saved locally: {local_filename}") 97 | except Exception as e: 98 | print(f"Failed to download {sandbox_path}: {str(e)}") 99 | 100 | counter += 1 101 | 102 | print(result_message) 103 | 104 | if execution.logs.stdout or execution.logs.stderr: 105 | log_message = "Logs:\n" 106 | if execution.logs.stdout: 107 | log_message += f"Stdout: {' '.join(execution.logs.stdout)}\n" 108 | if execution.logs.stderr: 109 | log_message += f"Stderr: {' '.join(execution.logs.stderr)}\n" 110 | result_message += log_message 111 | print(log_message) 112 | 113 | if not result_message: 114 | result_message = "There was no output of the execution." 115 | print(result_message) 116 | 117 | return execution.results, execution.logs, result_message, saved_files 118 | 119 | def chat(code_interpreter: CodeInterpreter, user_message: str) -> Tuple[List[Result], Logs, str, List[str]]: 120 | print(f"\n{'='*50}\nUser Message: {user_message}\n{'='*50}") 121 | 122 | message = client.beta.tools.messages.create( 123 | model=MODEL_NAME, 124 | system=SYSTEM_PROMPT, 125 | max_tokens=4096, 126 | messages=[{"role": "user", "content": user_message}], 127 | tools=tools, 128 | ) 129 | 130 | print(f"\n{'='*50}\nModel response: {message.content}\n{'='*50}") 131 | 132 | if message.stop_reason == "tool_use": 133 | tool_use = next(block for block in message.content if block.type == "tool_use") 134 | tool_name = tool_use.name 135 | tool_input = tool_use.input 136 | 137 | print(f"\n{'='*50}\nUsing tool: {tool_name}\n{'='*50}") 138 | 139 | if tool_name == "execute_python": 140 | return code_interpret(code_interpreter, tool_input["code"]) 141 | return [], Logs(), "No code execution requested.", [] 142 | 143 | def main(): 144 | try: 145 | while True: 146 | user_message = input("Enter your message (or 'quit' to exit): ") 147 | if user_message.lower() == 'quit': 148 | break 149 | 150 | with CodeInterpreter() as code_interpreter: 151 | try: 152 | code_interpreter_results, code_interpreter_logs, result_message, saved_files = chat( 153 | code_interpreter, 154 | user_message, 155 | ) 156 | except ValueError as e: 157 | print(f"Error unpacking results: {e}") 158 | continue 159 | 160 | print(code_interpreter_logs) 161 | print(result_message) 162 | 163 | if saved_files: 164 | print("Saved files:") 165 | for file in saved_files: 166 | print(f"- {file}") 167 | finally: 168 | sandbox.close() 169 | 170 | if __name__ == "__main__": 171 | main() 172 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 🧙‍♂️ Opus Interpreter 2 | 3 | Welcome to **Opus Interpreter**! 🚀 A magical Python data science environment where you can use **Anthropic's Claude** in tandem with a **secure sandbox** to generate and execute Python code on the fly. This project leverages Claude and the **Code Interpreter API by e2b** to create a seamless, interactive data science experience. Say goodbye to repetitive coding and hello to effortless productivity! 🎩✨ 4 | 5 | The script as well this readme were created entirely by **im-a-good-gpt2-chatbot** 6 | 7 | ## Features 🌟 8 | ### 1. **Claude as a Python Data Scientist** 9 | - **Anthropic Claude API Integration**: Claude-3 is your AI data scientist. 10 | - **Dynamic Code Generation**: Generate Python code based on your user message. 11 | - **Interactive Execution**: 12 | - Execute Python code in a secure environment. 13 | - Fetch execution results, logs, and any visualizations. 14 | 15 | ### 2. **Powerful Code Interpreter API** 16 | - **Execute Python Code**: Run Python code in a Jupyter notebook-like environment. 17 | - **Files & Logs Management**: Save results, tracebacks, and logs for future reference. 18 | - **Tools Integration**: 19 | - **execute_python**: Execute Python code in a separate cell. 20 | 21 | ### 3. **Secure Sandbox Execution** 22 | - **Secure Python Sandbox**: Execute Python code in a controlled environment. 23 | - **Filesystem Access**: 24 | - Read/write files. 25 | - Download files generated during execution. 26 | 27 | ## Getting Started 🛠️ 28 | ### Prerequisites 29 | 1. **Python**: Ensure you have Python 3.8 or above installed. 30 | 2. **API Keys**: 31 | - **Anthropic Claude API Key**. 32 | - **E2B Code Interpreter API Key**. 33 | 34 | ### Installation 35 | 1. **Clone the Repository**: 36 | ```bash 37 | git clone https://github.com/Doriandarko/opus-interpreter.git 38 | cd opus-interpreter 39 | ``` 40 | 41 | 2. **Install Dependencies**: 42 | ```bash 43 | pip install -r requirements.txt 44 | ``` 45 | 46 | 3. **Create a `.env` File**: 47 | Add your API keys to a `.env` file in the root directory: 48 | ```ini 49 | # .env file 50 | ANTHROPIC_API_KEY= 51 | E2B_API_KEY= 52 | ``` 53 | 54 | ### Usage 55 | 1. **Run the Script**: 56 | ```bash 57 | python opus-interpreter.py 58 | ``` 59 | 60 | 2. **Chat with Claude**: 61 | - Enter your message to ask Claude for code snippets or analysis. 62 | - Use `quit` to exit. 63 | 64 | ## Sample Messages 💬 65 | - **Data Analysis**: "Analyze this dataset and show me a summary." 66 | - **Visualization**: "Create a scatter plot comparing columns X and Y." 67 | - **Code Generation**: "Write a Python function to calculate Fibonacci numbers." 68 | 69 | ## Behind the Magic 🎩 70 | ### How It Works 71 | 1. **System Prompt**: Sets up Claude as a Python data scientist. 72 | 2. **Tool Definition**: 73 | - `execute_python`: Executes Python code in a secure environment. 74 | 3. **Chat Functionality**: 75 | - **chat**: Handles user messages and interprets Claude's response. 76 | - **code_interpret**: Executes Python code and manages results, logs, and files. 77 | 78 | 79 | ## Contributing 80 | All wizards and data enthusiasts are welcome to contribute! Feel free to: 81 | - Open issues for bugs or feature requests. 82 | - Submit pull requests with improvements. 83 | 84 | ## License 85 | This project is licensed under the MIT License. 86 | 87 | Feel free to reach out with questions or suggestions. Remember, **Claude** and **Code Interpreter** are here to help you **level up your data science game**! 🎯 88 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | anthropic 2 | dotenv 3 | matplotlib 4 | numpy 5 | e2b 6 | e2b-code-interpreter 7 | --------------------------------------------------------------------------------