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

Adding Functions guide for performing #37

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
360 changes: 360 additions & 0 deletions Basic_Samples/Functions/functions_to_perform_actions.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,360 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Working with Functions To Perform a Service\n",
"\n",
"This notebook shows how you can use functions to perform external tasks such as sending an email. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## API Configuration"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import openai\n",
"import json\n",
"import os\n",
"\n",
"# Load config values\n",
"with open(r'config.json') as config_file:\n",
" config_details = json.load(config_file)\n",
"\n",
"# The API key for your Azure OpenAI resource.\n",
"openai.api_key = os.getenv(\"OPENAI_API_KEY\")\n",
"\n",
"# Currently Chat Completion API have the following versions available: 2023-07-01-preview\n",
"openai.api_version = config_details['OPENAI_API_VERSION']\n",
"\n",
"# This is set to `azure`\n",
"openai.api_type = \"azure\"\n",
"\n",
"# The base URL for your Azure OpenAI resource. e.g. \"https://<your resource name>.openai.azure.com\"\n",
"openai.api_base = config_details['OPENAI_API_BASE']\n",
"\n",
"# Setting up the deployment name\n",
"deployment_id = config_details['DEPLOYMENT_NAME'] # You need to use the 0613 version of gpt-35-turbo or gpt-4 to work with functions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define the function"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Send Email"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import smtplib \n",
"from email.mime.multipart import MIMEMultipart \n",
"from email.mime.text import MIMEText \n",
"\n",
"def send_email(smtp_server, smtp_port, sender_email, sender_password, recipient_email, subject, body): \n",
" msg = MIMEMultipart() \n",
" msg['From'] = sender_email \n",
" msg['To'] = recipient_email \n",
" msg['Subject'] = subject \n",
" msg.attach(MIMEText(body, 'plain')) \n",
"\n",
" try: \n",
" server = smtplib.SMTP(smtp_server, smtp_port) \n",
" server.starttls() # Secure the connection \n",
" server.login(sender_email, sender_password) \n",
" text = msg.as_string() \n",
" server.sendmail(sender_email, recipient_email, text) \n",
" server.quit() \n",
" return \"Email sent successfully!\" \n",
"\n",
" except Exception as e: \n",
" return f\"Failed to send email: {str(e)}\" "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\"Failed to send email: (535, b'5.7.8 Username and Password not accepted. Learn more at\\\\n5.7.8 https://support.google.com/mail/?p=BadCredentials f22-20020a17090ac29600b00263f41a655esm237986pjt.43 - gsmtp')\""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Define your SMTP server details \n",
"smtp_server = 'smtp.gmail.com' # Replace with your SMTP server this is for gmail \n",
"smtp_port = 587 # Replace with your SMTP server port number this is the port for gmail \n",
"\n",
"# Define your email details \n",
"sender_email = '[email protected]' # Replace with your email username \n",
"sender_password = 'yourpassword' # Replace with your email password. For gmail accounts, you need to create an app password \n",
"recipient_email = '[email protected]' # Replace with recipient's email address \n",
"\n",
"# Define your email content \n",
"subject = 'Hello!' # Replace with your subject line \n",
"body = 'This is a test email' # Replace with your email body text \n",
"\n",
"# Call the send_email function \n",
"send_email(smtp_server, smtp_port, sender_email, sender_password, recipient_email, subject, body) \n",
"\n",
"# Steps to create an app password for your gmail account \n",
"# Visit this page: https://myaccount.google.com/security \n",
"# Under the section \"2-Step Verification\", click on \"App passwords\". \n",
"# Under \"Select app\", choose \"Mail\". \n",
"# Under \"Select device\", choose the one you're using. \n",
"# Click on \"Generate\". You will see a 16-digit password. Use this password in your Python script where you'd normally use your Gmail password."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Using GPT to perform a service \n",
"In this example, GPT is used to call a function that sends an email. Before the email is sent, the user must confirm it likes the content generated by the model."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Helper Method\n",
"Checks for invalid arguments."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import inspect\n",
"\n",
"# helper method used to check if the correct arguments are provided to a function\n",
"def check_args(function, args):\n",
" sig = inspect.signature(function)\n",
" params = sig.parameters\n",
"\n",
" # Check if there are extra arguments\n",
" for name in args:\n",
" if name not in params:\n",
" return False\n",
" # Check if the required arguments are provided \n",
" for name, param in params.items():\n",
" if param.default is param.empty and name not in args:\n",
" return False\n",
"\n",
" return True"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Replace the user message with your email, your password, the recipient email, the subject, and the body."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Response from GPT:\n",
"{\n",
" \"role\": \"assistant\",\n",
" \"content\": \"Of course! Please provide me with the necessary details.\"\n",
"}\n",
"\n",
"The subject of the email is: Fun Facts of the Day\n",
"The body of the email is: Here are some fun facts for you:\n",
"\n",
"1. A single strand of spaghetti is called a spaghetto.\n",
"2. The average person spends about 6 months of their life waiting for red lights to turn green.\n",
"3. Only 2% of the world's population has green eyes.\n",
"4. The shortest war in history lasted only 38 to 45 minutes.\n",
"\n",
"Enjoy!\n",
"\n",
"Do you want to send this email? (yes/no)\n"
]
}
],
"source": [
"def perform_service(): \n",
" # Step 1: send the conversation and available functions to GPT \n",
" messages = [] \n",
" messages.append({\"role\": \"system\", \"content\": \"Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous. You are able to help send emails using a function.\"}) \n",
" messages.append({\"role\": \"system\", \"content\": \"After you generate the content of the email ask the user to confirm the draft before sending it.\"}) \n",
"\n",
" messages = [{\"role\": \"user\", \"content\": \"Can you send an email for me?\"}] \n",
" functions = [ \n",
" { \n",
" \"name\": \"send_email\", \n",
" \"description\": \"Send an email\", \n",
" \"parameters\": { \n",
" \"type\": \"object\", \n",
" \"properties\": { \n",
" \"smtp_server\": { \n",
" \"type\": \"string\", \n",
" \"description\": \"The SMTP server to use to send the email. For example, smtp.office365.com is the server for outlook accounts, smtp.gmail.com is the server for gmail accounts, and smtp.mail.att.net is for AT&T accounts.\", \n",
" }, \n",
" \"smtp_port\": { \n",
" \"type\": \"integer\", \n",
" \"description\": \"The SMTP port to use to send the email. For example, 587 is the port for outlook and gmail accounts. 465 is the port for AT&T accounts.\", \n",
" }, \n",
" \"sender_email\": { \n",
" \"type\": \"string\", \n",
" \"description\": \"The email address of the sender.\", \n",
" }, \n",
" \"sender_password\": { \n",
" \"type\": \"string\", \n",
" \"description\": \"The password of the sender.\", \n",
" }, \n",
" \"recipient_email\": { \n",
" \"type\": \"string\", \n",
" \"description\": \"The email address of the recipient.\", \n",
" }, \n",
" \"subject\": { \n",
" \"type\": \"string\", \n",
" \"description\": \"The subject of the email.\", \n",
" }, \n",
" \"body\": { \n",
" \"type\": \"string\", \n",
" \"description\": \"The body of the email.\", \n",
" }, \n",
" }, \n",
" \"required\": [\"smtp_server\", \"smtp_port\", \"sender_email\", \"sender_password\", \"recipient_email\", \"subject\", \"body\"], \n",
" }, \n",
" } \n",
" ] \n",
" response = openai.ChatCompletion.create( \n",
" deployment_id=deployment_id, \n",
" messages=messages, \n",
" functions=functions, \n",
" function_call=\"auto\", \n",
" ) \n",
" response_message = response[\"choices\"][0][\"message\"] \n",
"\n",
" print(\"Response from GPT:\") \n",
" print(response_message) \n",
" print() \n",
"\n",
" # Provide more details to GPT about the email to send\n",
" # Replace the sender email, sender password, and recipient email with the user's actual email addresses\n",
" # Replace the subject and body with whatever you want\n",
" messages.append({\"role\": \"user\", \"content\": \"My email is [email protected]. My password is yourpassword. I am sending an email to [email protected]. I want the subject line to be Fun Facts of the Day. For the body of the email I want you to generate fun facts.\"}) \n",
"\n",
" response = openai.ChatCompletion.create( \n",
" deployment_id=deployment_id, \n",
" messages=messages, \n",
" functions=functions, \n",
" function_call={\"name\": \"send_email\"}, \n",
" ) \n",
" response_message = response[\"choices\"][0][\"message\"] \n",
"\n",
" # Parsing out the generated email parts\n",
" email_args = response_message[\"function_call\"][\"arguments\"]\n",
" arguments_dict = json.loads(email_args)\n",
" email_subject = arguments_dict[\"subject\"]\n",
" email_body = arguments_dict[\"body\"]\n",
" print(\"The subject of the email is: \" + email_subject)\n",
" print(\"The body of the email is: \" + email_body)\n",
" print()\n",
"\n",
" # Verifying user wants to send the generated email\n",
" print(\"Do you want to send this email? (yes/no)\")\n",
" user_response = input()\n",
" user_response.lower()\n",
"\n",
" # Step 2: check if user confirmed they want to call the function\n",
" if response_message.get(\"function_call\"): \n",
" if user_response == \"yes\":\n",
" print(\"Recommended Function call:\") \n",
" print(response_message.get(\"function_call\")) \n",
" print() \n",
"\n",
" # Step 3: call the function \n",
" # Note: the JSON response may not always be valid; be sure to handle errors \n",
" available_functions = { \n",
" \"send_email\": send_email, \n",
" } \n",
" function_name = response_message[\"function_call\"][\"name\"] \n",
"\n",
" # verify function exists \n",
" if function_name not in available_functions: \n",
" return \"Function \" + function_name + \" does not exist\" \n",
" fuction_to_call = available_functions[function_name] \n",
"\n",
" # verify function has correct number of arguments \n",
" function_args = json.loads(response_message[\"function_call\"][\"arguments\"]) \n",
" if check_args(fuction_to_call, function_args) is False: \n",
" return \"Invalid number of arguments for function: \" + function_name \n",
"\n",
" # Call the function and return the response \n",
" function_response = fuction_to_call(**function_args) \n",
" print(function_response) \n",
" return function_response \n",
" else:\n",
" return \"Email not sent.\"\n",
"service_response = perform_service() "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}