Generative AIBuilding with foundation modelsOpenAI platformOpenAI Assistants API

Code interpreter with the Assistant

6 minutes read

The Code Interpreter provides a secure and isolated environment for executing code. The sandboxed execution ensures that all operations remain contained, preventing any impact on the user's system. Going beyond code execution, the Code Interpreter offers native support for many data formats, making it suitable for tasks ranging from running basic scripts to performing data analysis. The Code Interpreter can generate code snippets based on user specifications, verify their accuracy, and iteratively refine them to match requirements. This combination streamlines various coding tasks, including debugging, analyzing datasets, and automating repetitive tasks.

In this topic, we explore how to use the Code Interpreter API with an OpenAI Assistant by simulating a scenario where a Finance Assistant processes a CSV file, generating a monthly sales summary and bar chart graph.

Setup

Our first step is to set up the environment by importing necessary libraries and creating a sample CSV file containing our example data.

import os
import csv
import time
from openai import OpenAI
from openai.types.beta.threads import (
    ImageFileContentBlock,
    TextContentBlock
)

csv_filename = "sales_data.csv"

with open(csv_filename, "w", newline="") as csvfile:
    fieldnames = ["Date", "Sales"]
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({"Date": "2023-03-15", "Sales": "1500"})
    writer.writerow({"Date": "2023-03-20", "Sales": "2300"})
    writer.writerow({"Date": "2023-04-10", "Sales": "1800"})
    writer.writerow({"Date": "2023-04-25", "Sales": "2100"})
    writer.writerow({"Date": "2023-05-05", "Sales": "3000"})

We initialize the OpenAI client which will be used for all future interactions with the Assistant API to create assistants, threads, and handle events.

client = OpenAI()

Before starting the analysis, the CSV file must be uploaded through the API for the assistant to access it.

with open(csv_filename, "rb") as f:
    uploaded_file = client.files.create(file=f, purpose="assistants")

print("Uploaded file ID:", uploaded_file.id)

Creating Assistant

An assistant is then created with Code Interpreter enabled. The uploaded CSV file is provided as part of the assistant’s context for the upcoming conversation.

assistant = client.beta.assistants.create(
    name="Finance Assistant",
    instructions="You are an expert sales data analyst. When given a sales CSV file, analyze the data and provide a monthly summary and a graph.",
    model="gpt-4o",
    tools=[{"type": "code_interpreter"}],
    tool_resources={
        "code_interpreter": {"file_ids": [uploaded_file.id]}
    },
)

print("Created assistant ID:", assistant.id)

When the assistant encounters a task that involves data processing (sales analysis in our case), or visualization, it can generate code snippets and pass them to the Code Interpreter, which executes them in isolated environment.

As the interpreter runs the code, it captures outputs, log messages, and generated artifacts (such as charts or modified files). These results are streamed back to the assistant, which then interprets and integrates them into its conversation with the user.

Now, we create a conversation thread and add an initial message from the user specifying the analysis requirement.

thread = client.beta.threads.create()

prompt = (
    "Please analyze the sales_data.csv file and produce a monthly sales"
    "summary and generate image file with a bar chart of monthly totals."
    "Save the chart as `monthly_sales.png`."
    "Make sure the report is clear and concise."
)

message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content=prompt
)

Running the Assistant

After all preparations we can start a run of the assistant on this thread.

run = client.beta.threads.runs.create(
    thread_id=thread.id,
    assistant_id=assistant.id
)

print(f"Started run: {run.id}, initial status: {run.status}")

Now we have to wait for the run to finish using periodic polling.

import time

while run.status in ("queued", "in_progress"):
    time.sleep(1)
    run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)

print("Run completed with status:", run.status)

This is the most basic way to wait for the result of the run. OpenAI SDKs also provides more sophisticated methods.

Once the run is finished, we can retrieve messages history and download all the files generated in the process.

# Retrieve all messages in the thread
messages = client.beta.threads.messages.list(thread_id=thread.id)

for msg in messages.data:
    print(f"{msg.role}:")

    for block in msg.content or []:
        if isinstance(block, TextContentBlock):
            print(f"{msg.role}: {block.text.value}")
        # If there are any attachments, download them
        # Our `monthly_sales.png` should be here
        if isinstance(block, ImageFileContentBlock):
            file_id = block.image_file.file_id
            filename = f"{file_id}.png"
            img_bytes = client.files.content(file_id).read()
            with open(filename, "wb") as f:
                f.write(img_bytes)
            print(f"Saved image to {filename}")

Conclusion

As a result, you are now familiar with the following aspects:

  • Code Interpreter provides a sandboxed environment for code execution with native support for various data formats;

  • The Code Interpreter generates, verifies, and refines code snippets based on user specifications for tasks like debugging and data analysis;

  • Code Interpreter processes uploaded files and generates output files including visualizations and operates within a thread-based conversation model with the user.

2 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo