Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chat: flake fixes #1301

Merged
merged 1 commit into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions MAVProxy/modules/mavproxy_chat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
OpenAI Assistant API: https://platform.openai.com/docs/api-reference/assistants
OpenAI Assistant Playground: https://platform.openai.com/playground
MAVProxy chat wiki: https://ardupilot.org/mavproxy/docs/modules/chat.html

AP_FLAKE8_CLEAN
'''

from MAVProxy.modules.lib import mp_module
Expand All @@ -16,6 +18,7 @@
from threading import Thread
import time


class chat(mp_module.MPModule):
def __init__(self, mpstate):

Expand Down Expand Up @@ -110,6 +113,7 @@ def wait_for_command_ack(self, mav_cmd, timeout=1):
del self.command_ack_waiting[mav_cmd]
return False


# initialise module
def init(mpstate):
return chat(mpstate)
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,35 @@

OpenAI Assistant API: https://platform.openai.com/docs/api-reference/assistants
OpenAI Assistant Playground: https://platform.openai.com/playground

AP_FLAKE8_CLEAN
'''

import datetime, os
import datetime
import os

try:
from openai import OpenAI
except:
except Exception:
print("chat: failed to import openai. See https://ardupilot.org/mavproxy/docs/modules/chat.html")
exit()


# main function
def main(openai_api_key=None, delete_unused=False):

print("Starting Assistant File checker")

# create connection object
try:
# if api key is provided, use it to create connection object
if openai_api_key is not None:
client = OpenAI(api_key=openai_api_key)
else:
# if no api key is provided, attempt to create connection object without it
# user may have set the OPENAI_API_KEY environment variable
client = OpenAI()
except:
# if no api key is provided, attempt to create connection object without it
# user may have set the OPENAI_API_KEY environment variable
client = OpenAI()
except Exception:
# if connection object creation fails, exit with error message
print("assistant_file_checker: failed to connect to OpenAI. Perhaps the API key was incorrect?")
exit()
Expand All @@ -41,7 +45,7 @@ def main(openai_api_key=None, delete_unused=False):
print("File list:")
file_found = False
for file in existing_files.data:
print(" id:" + file.id + " name:" + file.filename + " size:" + str(file.bytes) + " date:" + str(datetime.datetime.fromtimestamp(file.created_at)))
print(" id:" + file.id + " name:" + file.filename + " size:" + str(file.bytes) + " date:" + str(datetime.datetime.fromtimestamp(file.created_at))) # noqa
file_found = True
if not file_found:
print(" no files found")
Expand All @@ -64,20 +68,20 @@ def main(openai_api_key=None, delete_unused=False):
for assistant_file in client.beta.assistants.files.list(assistant_id=assistant.id):
file_assistant_count[assistant_file.id] = file_assistant_count.get(assistant_file.id, 0) + 1
filename_size_date = get_filename_size_date_from_id(existing_files, assistant_file.id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pull the result apart directly here instead of indexing filename_size_date:

Suggested change
filename_size_date = get_filename_size_date_from_id(existing_files, assistant_file.id)
(file_name, file_size, file_date) = get_filename_size_date_from_id(existing_files, assistant_file.id)

print(" id:" + assistant_file.id + " name:" + filename_size_date[0] + " size:" + str(filename_size_date[1]) + " date:" + filename_size_date[2])
print(" id:" + assistant_file.id + " name:" + filename_size_date[0] + " size:" + str(filename_size_date[1]) + " date:" + filename_size_date[2]) # noqa
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f-strings can make your code a little more readable:

Suggested change
print(" id:" + assistant_file.id + " name:" + filename_size_date[0] + " size:" + str(filename_size_date[1]) + " date:" + filename_size_date[2]) # noqa
print(f" id:{assistant_file.id} name:{filename_size_date[0]} size:{str(filename_size_date[1])} date:{filename_size_date[2]}) # noqa


# display the list of files which are not used by any Assistants
print_unused_files_header = True
for existing_file in existing_files:
if not existing_file.id in file_assistant_count.keys():
if existing_file.id not in file_assistant_count.keys():
# print header if this is the first unused file
if print_unused_files_header:
print("Files not used by any Assistants:")
print_unused_files_header = False

# print file attributes
filename_size_date = get_filename_size_date_from_id(existing_files, existing_file.id)
print(" id:" + existing_file.id + " name:" + filename_size_date[0] + " size:" + str(filename_size_date[1]) + " date:" + filename_size_date[2])
print(" id:" + existing_file.id + " name:" + filename_size_date[0] + " size:" + str(filename_size_date[1]) + " date:" + filename_size_date[2]) # noqa

# delete the unused file if specified by the user
if delete_unused:
Expand All @@ -87,6 +91,7 @@ def main(openai_api_key=None, delete_unused=False):
# print completion message
print("Assistant File check complete")


# searches the files_list for the specified file id and retuns the filename, size and creation date (as a string) if found
# returns None if not found
def get_filename_size_date_from_id(files_list, file_id):
Expand All @@ -95,17 +100,18 @@ def get_filename_size_date_from_id(files_list, file_id):
return file.filename, file.bytes, str(datetime.datetime.fromtimestamp(file.created_at))
return "not found", "unknown", "unknown"


# call main function if this is run as standalone script
if __name__ == "__main__":

# parse command line arguments
from argparse import ArgumentParser
parser = ArgumentParser(description="MAVProxy Chat Module Assistant File Checker")
parser.add_argument("--api-key", default=None, help="OpenAI API Key")
parser.add_argument("--delete-unused", action='store_true', help="delete unused files")
try:
args = parser.parse_args()
except AttributeError as err:
except AttributeError:
parser.print_help()
os.sys.exit(0)
main(openai_api_key=args.api_key, delete_unused=args.delete_unused)
49 changes: 27 additions & 22 deletions MAVProxy/modules/mavproxy_chat/assistant_setup/setup_assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

OpenAI Assistant API: https://platform.openai.com/docs/api-reference/assistants
OpenAI Assistant Playground: https://platform.openai.com/playground

AP_FLAKE8_CLEAN
'''

import requests
Expand All @@ -15,25 +17,26 @@

try:
from openai import OpenAI
except:
except Exception:
print("chat: failed to import openai. See https://ardupilot.org/mavproxy/docs/modules/chat.html")
exit()


# main function
def main(openai_api_key=None, assistant_name=None, model_name=None, upgrade=False):

print("Starting assistant setup")

# create connection object
try:
# if api key is provided, use it to create connection object
if openai_api_key is not None:
client = OpenAI(api_key=openai_api_key)
else:
# if no api key is provided, attempt to create connection object without it
# user may have set the OPENAI_API_KEY environment variable
client = OpenAI()
except:
# if no api key is provided, attempt to create connection object without it
# user may have set the OPENAI_API_KEY environment variable
client = OpenAI()
except Exception:
# if connection object creation fails, exit with error message
print("setup_assistant: failed to connect to OpenAI. Perhaps the API key was incorrect?")
exit()
Expand All @@ -49,7 +52,7 @@ def main(openai_api_key=None, assistant_name=None, model_name=None, upgrade=Fals
# check that assistant_instructions.txt file exists
instructions_filename = os.path.join(os.getcwd(), "assistant_instructions.txt")
if not os.path.isfile(instructions_filename):
print("setup_assistant: " + instructions_filename +" not found")
print("setup_assistant: " + instructions_filename + " not found")
exit()

# check that at least one text file exists. E.g. text files holding the flight mode number to name mappings
Expand All @@ -72,7 +75,7 @@ def main(openai_api_key=None, assistant_name=None, model_name=None, upgrade=Fals
function_object = json.load(function_file)
function_tools.append(function_object)
print("setup_assistant: parsed function file: " + os.path.basename(function_filename))
except:
except Exception:
print("setup_assistant: failed to parse json file: " + function_filename)
exit()

Expand All @@ -84,15 +87,15 @@ def main(openai_api_key=None, assistant_name=None, model_name=None, upgrade=Fals
# download latest MAVLink files from ardupilot MAVLink repo, minimal.xml, common.xml and ardupilotmega.xml
mavlink_filenames = ["minimal.xml", "common.xml", "ardupilotmega.xml"]
for mavlink_filename in mavlink_filenames:
if not download_file("https://raw.githubusercontent.com/ArduPilot/mavlink/master/message_definitions/v1.0/" + mavlink_filename, mavlink_filename):
if not download_file("https://raw.githubusercontent.com/ArduPilot/mavlink/master/message_definitions/v1.0/" + mavlink_filename, mavlink_filename): # noqa
exit()

# download latest vehicle parameter definition files from ardupilot server
paramdef_file_info = [
{"url": "https://autotest.ardupilot.org/Parameters/ArduCopter/apm.pdef.xml", "filename": "copter_parameter_definitions.xml"},
{"url": "https://autotest.ardupilot.org/Parameters/ArduPlane/apm.pdef.xml", "filename": "plane_parameter_definitions.xml"},
{"url": "https://autotest.ardupilot.org/Parameters/APMrover2/apm.pdef.xml", "filename": "rover_parameter_definitions.xml"},
{"url": "https://autotest.ardupilot.org/Parameters/ArduSub/apm.pdef.xml", "filename": "sub_parameter_definitions.xml"}]
{"url": "https://autotest.ardupilot.org/Parameters/ArduCopter/apm.pdef.xml", "filename": "copter_parameter_definitions.xml"}, # noqa
{"url": "https://autotest.ardupilot.org/Parameters/ArduPlane/apm.pdef.xml", "filename": "plane_parameter_definitions.xml"}, # noqa
{"url": "https://autotest.ardupilot.org/Parameters/APMrover2/apm.pdef.xml", "filename": "rover_parameter_definitions.xml"}, # noqa
{"url": "https://autotest.ardupilot.org/Parameters/ArduSub/apm.pdef.xml", "filename": "sub_parameter_definitions.xml"}] # noqa
paramdef_filenames = []
for pdef_file_info in paramdef_file_info:
if not download_file(pdef_file_info["url"], pdef_file_info["filename"]):
Expand Down Expand Up @@ -124,7 +127,7 @@ def main(openai_api_key=None, assistant_name=None, model_name=None, upgrade=Fals
try:
instructions_content = open(instructions_filename, 'r').read()
client.beta.assistants.update(assistant.id, instructions=instructions_content, tools=function_tools)
except:
except Exception:
print("setup_assistant: failed to update assistant instructions")
exit()

Expand All @@ -136,7 +139,7 @@ def main(openai_api_key=None, assistant_name=None, model_name=None, upgrade=Fals
try:
# open local file as read-only
file = open(filename, 'rb')
except:
except Exception:
print("setup_assistant: failed to open file: " + filename)
exit()

Expand All @@ -155,7 +158,7 @@ def main(openai_api_key=None, assistant_name=None, model_name=None, upgrade=Fals
try:
client.files.delete(existing_file.id)
print("setup_assistant: deleted existing file: " + filename)
except:
except Exception:
print("setup_assistant: failed to delete file from OpenAI: " + filename)
exit()

Expand All @@ -165,14 +168,14 @@ def main(openai_api_key=None, assistant_name=None, model_name=None, upgrade=Fals
uploaded_file = client.files.create(file=file, purpose="assistants")
uploaded_file_ids.append(uploaded_file.id)
print("setup_assistant: uploaded: " + filename)
except:
except Exception:
print("setup_assistant: failed to upload file to OpenAI: " + filename)
exit()

# update assistant's accessible files
try:
client.beta.assistants.update(assistant.id, file_ids=uploaded_file_ids)
except:
except Exception:
print("setup_assistant: failed to update assistant accessible files")
exit()

Expand All @@ -181,12 +184,13 @@ def main(openai_api_key=None, assistant_name=None, model_name=None, upgrade=Fals
try:
os.remove(mavlink_filename)
print("setup_assistant: deleted local file: " + mavlink_filename)
except:
except Exception:
print("setup_assistant: failed to delete file: " + mavlink_filename)

# print completion message
print("Assistant setup complete")


def download_file(url, filename):
# download file from url to filename
# return True if successful, False if not
Expand All @@ -201,13 +205,14 @@ def download_file(url, filename):
else:
print("setup_assistant: failed to download file: " + url)
return False
except:
except Exception:
print("setup_assistant: failed to download file: " + url)
return False


# call main function if this is run as standalone script
if __name__ == "__main__":

# parse command line arguments
from argparse import ArgumentParser
parser = ArgumentParser(description="MAVProxy AI chat module OpenAI Assistant setup script")
Expand Down
Loading