chatbot / functions.py
vmoras's picture
Fix error. Chat not opening
b05d3be
import os
import csv
import time
import openai
import gradio as gr
def get_countries():
"""
Returns a list with the countries from a CSV
"""
with open('assets/data/paises.csv', encoding='utf-8') as file:
reader = csv.reader(file)
countries = [row[0] for row in reader]
return countries
def check_info(name: gr.Textbox, age: gr.Number, country: gr.Dropdown):
"""
Checks if the given info is complete (no empty strings) and if the
user is old enough (> 18). If so, opens the chatbot, if not
"""
# Name or country is not provided or the age is not an integer
if name == '' or country == '' or not isinstance(age, float):
new_image = 'assets/images/pregunta.jpg'
keep_asking, keep_open, open_chat = True, True, False
msg_history = []
# User is underage
elif age < 18:
new_image = 'assets/images/despedida.jpg'
keep_asking, keep_open, open_chat = False, True, False
msg_history = []
# User is old enough and gave all the necessary data
else:
new_image = 'assets/images/feliz.jpg'
keep_asking, keep_open, open_chat = False, False, True
msg_history = innit_bot()
# Update layout depending on the previous values
new_button = gr.Button.update(interactive=keep_asking)
new_img = gr.Image.update(value=new_image)
new_welcoming = gr.Row.update(visible=keep_open)
new_chat = gr.Row.update(visible=open_chat)
return new_button, new_img, new_welcoming, new_chat, msg_history
def innit_bot():
"""
Initialize the bot by adding the prompt from the txt file to the messages history
"""
openai.api_key = os.environ.get('API_KEY')
with open('assets/data/prompt.txt', encoding='utf-8') as file:
prompt = file.read()
message_history = [{"role": "system", "content": prompt}]
return message_history
def call_api(msg_history: gr.State):
"""
Returns the APIs response
"""
response = openai.ChatCompletion.create(
model="gpt-4",
temperature=1,
messages=msg_history
)
return response
def handle_call(msg_history: gr.State):
"""
Returns the status of the response (False if there was an error, True otherwise), the response and
waiting time of the AI. It also handles the possible errors
"""
tries, max_tries = 0, 9
while True:
try:
start_time = time.time()
response = call_api(msg_history)
end_time = time.time()
break
except Exception as e:
print(e)
if tries == max_tries:
return True, '', ''
tries += 1
time.sleep(20)
needed_time = end_time - start_time
return False, response, needed_time
def get_ai_answer(msg: str, msg_history: gr.State):
"""
Returns the response given by the model, all the message history so far and the seconds
the api took to retrieve such response. It can also return an empty string if there was an
error
"""
msg_history.append({"role": "user", "content": msg})
error, response, needed_time = handle_call(msg_history)
# There was an error with the API, abort everything
if error:
return '', msg_history, -1
AI_response = response["choices"][0]["message"]["content"]
msg_history.append({'role': 'assistant', 'content': AI_response})
return AI_response, msg_history, needed_time
def get_answer(msg: str, msg_history: gr.State, chatbot_history: gr.Chatbot, waiting_time: gr.State):
"""
Cleans msg box, adds the new message to the message history,
gets the answer from the bot and adds it to the chatbot history
and gets the time needed to get such answer and saves it
"""
# Get bot answer (output), messages history and waiting time
AI_response, msg_history, needed_time = get_ai_answer(msg, msg_history)
# There was an error
if AI_response == '':
waiting_time.append(needed_time)
chatbot_history.append((msg, ''))
return "", msg_history, chatbot_history, waiting_time, False
# Make sure the AI_response is short, if not make it shorter
if len(AI_response) > 260:
new_msg = 'El mensaje esta muy largo. Da la misma idea (mandando el link, pregunta y/o promocion que hayas ' \
'dado) pero usando 40 palabras.'
AI_response, msg_history, needed_time = get_ai_answer(new_msg, msg_history)
# Make sure the AI_response has at least one question
if '?' not in AI_response:
new_msg = 'Incluye 1 pregunta dentro del mensaje. Puede estar relacionada a lo que se hablo antes o algo nuevo.'
AI_response, msg_history, needed_time = get_ai_answer(new_msg, msg_history)
# Save waiting time
waiting_time.append(needed_time)
# Save output in the chat
chatbot_history.append((msg, AI_response))
return "", msg_history, chatbot_history, waiting_time, True
def check_closing(is_working: gr.State):
"""
If is_working is False (it means the API had an error), then close the chat
"""
if is_working:
return gr.Column.update(visible=True), gr.Column.update(visible=False)
return gr.Column.update(visible=False), gr.Column.update(visible=True)