Error 404 "No run found with id ...."

I wrote this program:
import openai
import json
import time
import yfinance as yf
from dotenv import load_dotenv

load_dotenv()

client = openai.OpenAI()
model = “gpt-4o”

def print_client_parameters(assistant_manager):
print("Assistant ID is: ",assistant_manager.assistant_id)
print("Thread ID is: ",assistant_manager.thread_id, “\n”)

def yfinance_stock_data(ticker):
stock_obj = yf.Ticker(ticker)
return stock_obj

def main():
ticker = “MSFT”
MSFT = yfinance_stock_data(ticker)

assistant_manager = AssistantManager()
assistant_manager.create_assistant("Stock Assistant", "You are a helpful stock market assistant.", [{"type": "code_interpreter"}])
assistant_manager.create_thread()
assistant_manager.add_message_to_thread("user", f"Here's the stock data for {ticker}: {MSFT}")
assistant_manager.run_assistant("Analyze this stock data and provide insights.")
assistant_manager.wait_for_completed()

class AssistantManager:
thread_id = None
assistant_id = None

def __init__(self, model: str = model):
    self.client = client
    self.model = model
    self.assistant = None,
    self.thread = None,
    self.run =  None
    self.stock = None   
    
    # Retrieve existing assistant and thread if IDs exist
    if AssistantManager.assistant_id:
        self.assistant = self.client.beta.assistants.retrieve(
            assistant_id=AssistantManager.assistant_id
        )
    if AssistantManager.thread_id:
        self.thread = self.client.beta.threads.retrieve(
            thread_id=AssistantManager.thread_id
        )
def create_assistant(self, name, instructions, tools):
    assistant_obj = self.client.beta.assistants.create(
        name= name,
        instructions= instructions,
        tools= tools,
        model= self.model
    )
    AssistantManager.assistant_id = assistant_obj.id  
    print(f"AssisID:::: {assistant_obj.id}")
def create_thread(self):
    thread_obj = self.client.beta.threads.create()
    AssistantManager.thread_id = thread_obj.id
    self.thread = thread_obj
    print(f"ThreadID:::: {self.thread.id}")
def add_message_to_thread(self, role, content):
        self.client.beta.threads.messages.create(
        thread_id=self.thread_id,
        role= role,
        content= content 
    )
def run_assistant(self, instructions):
       self.run = self.client.beta.threads.runs.create(
            thread_id= self.thread_id,
            assistant_id= self.assistant_id,
            instructions= instructions
        )
       print(f"RunID:::: {self.run.id}")    
def process_message(self):
    if not self.thread == None:
        messeges = self.client.beta.threads.messages.list(thread_id= self.thread.id)
        stock_summery = []

        last_message = messeges.data[0]
        role = last_message.role
        response = last_message.content[0].text.value
        stock_summery.append(response)

        self.summary = "\n".join(stock_summery)
        print(f"SUMMARY----> {role.capitalize()}: ==> {response}")
    return stock_summery
def call_required_functions(self, requires_action):
    if not self.run:
       return
    tools_outputs = []

    for action in requires_action["tool_calls"]:
        func_name = action["function"]["name"]
        print(func_name)
        arguments = json.loads(action["function"]["arguments"])

        if func_name == "yfinance_stock_data":
            output = yfinance_stock_data(arguments["ticker"])
            tools_outputs.append({
             "tool_call_id": action["id"],
             "output": json.dumps(output)
            })

    self.client.beta.threads.runs.submit_tool_outputs(
        thread_id=self.thread.id,
        run_id=self.run.id,
        tool_outputs=tools_outputs
    )
def wait_for_completed(self):
    if self.thread and self.run:
       while True:
           time.sleep(5)
           run_status = self.client.beta.threads.runs.retrieve(
                 thread_id= self.thread.id,
                 run_id= self.run 
            )
           print(f"RUN STATUS:: {run_status.model_dump_json(indent=4)}")

           if run_status.status == "completed":
               self.process_message()
               break
           else:
              print("run_status.status in not completed. run_status is: ", run_status.status)
              break

if name == “main”:
main()
when running the program i receive from openai:
AssisID:::: asst_NyUCYHfOI51Vm8Pk2nDD2iQ4
ThreadID:::: thread_Dx4MH2TU0RHsZRgbGQpqNXFV
RunID:::: run_WDVuKBG9sMdTrzeeGzrtvT5S

but still the run status retrieve
run_status = self.client.beta.threads.runs.retrieve(
thread_id= self.thread.id,
run_id= self.run
)
gives error 404: “No run found with id …”
Can someone explain to me what am i doing wrong?

It looks like there are a few potential issues with your code that could be causing the 404: “No run found with id …” error. Here’s a detailed review and suggested fixes:

Issues and Fixes

  1. Initialization Order:
    The AssistantManager class is defined after the main() function, but the main() function uses it. Make sure the class definition comes before its usage.

  2. Instance Initialization:
    The client initialization should be adjusted. Replace client = openai.OpenAI() with client = openai.Client().

  3. Model Name:
    The model name is defined as model = “gpt-4o”. Ensure this is a valid model name. It should be gpt-4 or another available model name.

  4. run_id Retrieval:
    The run_id used in the retrieve call might not be properly accessed. self.run is a response object, not an ID. Use self.run.id directly when calling retrieve.

  5. Improper Use of the Client API:
    Ensure that self.client.beta.threads.runs.retrieve is called with correct parameters and that the API supports the endpoint you’re trying to use.

  6. Handling AssistantManager Object Initialization:
    Make sure you correctly initialize AssistantManager and use the methods after its instantiation.

Revised Code

Here’s a revised version of your script with these adjustments:

import openai
import json
import time
import yfinance as yf
from dotenv import load_dotenv

load_dotenv()

client = openai.Client()  # Use the correct client initialization
model = "gpt-4"  # Ensure the model name is correct

class AssistantManager:
    thread_id = None
    assistant_id = None

    def __init__(self, model: str = model):
        self.client = client
        self.model = model
        self.assistant = None
        self.thread = None
        self.run = None
        self.stock = None   

        # Retrieve existing assistant and thread if IDs exist
        if AssistantManager.assistant_id:
            self.assistant = self.client.beta.assistants.retrieve(
                assistant_id=AssistantManager.assistant_id
            )
        if AssistantManager.thread_id:
            self.thread = self.client.beta.threads.retrieve(
                thread_id=AssistantManager.thread_id
            )

    def create_assistant(self, name, instructions, tools):
        assistant_obj = self.client.beta.assistants.create(
            name=name,
            instructions=instructions,
            tools=tools,
            model=self.model
        )
        AssistantManager.assistant_id = assistant_obj.id  
        print(f"AssisID:::: {assistant_obj.id}")

    def create_thread(self):
        thread_obj = self.client.beta.threads.create()
        AssistantManager.thread_id = thread_obj.id
        self.thread = thread_obj
        print(f"ThreadID:::: {self.thread.id}")

    def add_message_to_thread(self, role, content):
        self.client.beta.threads.messages.create(
            thread_id=self.thread_id,
            role=role,
            content=content 
        )

    def run_assistant(self, instructions):
        self.run = self.client.beta.threads.runs.create(
            thread_id=self.thread_id,
            assistant_id=self.assistant_id,
            instructions=instructions
        )
        print(f"RunID:::: {self.run.id}")

    def process_message(self):
        if not self.thread:
            return []
        messages = self.client.beta.threads.messages.list(thread_id=self.thread.id)
        stock_summary = []

        last_message = messages.data[0]
        role = last_message.role
        response = last_message.content[0].text.value
        stock_summary.append(response)

        self.summary = "\n".join(stock_summary)
        print(f"SUMMARY----> {role.capitalize()}: ==> {response}")
        return stock_summary

    def call_required_functions(self, requires_action):
        if not self.run:
            return
        tools_outputs = []

        for action in requires_action["tool_calls"]:
            func_name = action["function"]["name"]
            print(func_name)
            arguments = json.loads(action["function"]["arguments"])

            if func_name == "yfinance_stock_data":
                output = yfinance_stock_data(arguments["ticker"])
                tools_outputs.append({
                    "tool_call_id": action["id"],
                    "output": json.dumps(output)
                })

        self.client.beta.threads.runs.submit_tool_outputs(
            thread_id=self.thread.id,
            run_id=self.run.id,
            tool_outputs=tools_outputs
        )

    def wait_for_completed(self):
        if self.thread and self.run:
            while True:
                time.sleep(5)
                run_status = self.client.beta.threads.runs.retrieve(
                    thread_id=self.thread.id,
                    run_id=self.run.id  # Use `self.run.id` to access the ID
                )
                print(f"RUN STATUS:: {run_status.model_dump_json(indent=4)}")

                if run_status.status == "completed":
                    self.process_message()
                    break
                else:
                    print("run_status.status is not completed. run_status is: ", run_status.status)
                    break

def yfinance_stock_data(ticker):
    stock_obj = yf.Ticker(ticker)
    return stock_obj.info  # Use stock_obj.info to get stock data

def main():
    ticker = "MSFT"
    assistant_manager = AssistantManager()
    assistant_manager.create_assistant("Stock Assistant", "You are a helpful stock market assistant.", [{"type": "code_interpreter"}])
    assistant_manager.create_thread()
    assistant_manager.add_message_to_thread("user", f"Here's the stock data for {ticker}: {yfinance_stock_data(ticker)}")
    assistant_manager.run_assistant("Analyze this stock data and provide insights.")
    assistant_manager.wait_for_completed()

if __name__ == "__main__":
    main()

Summary

  1. Reorder Class and Function Definitions: Ensure the class is defined before being used.
  2. Correct Client Initialization: Use

    openai.Client().
  3. Model Name: Verify the correct model name.
  4. Run ID Handling: Use self.run.id for accessing run_id.
  5. API Usage: Ensure the API methods are called correctly.

Make these adjustments, and your code should work as expected.

Sorry about double image for model examples

Thanks a bunch. Great help.
Sincerely,
Ran

1 Like