DilshanKavinda's picture
Update app.py
7b13629 verified
raw
history blame contribute delete
No virus
13 kB
import streamlit as st
import os
import google.generativeai as genai
from datetime import datetime
import pandas as pd
# from credentials import GOOGLE_API_KEY,reporting_person
import json
import requests
GOOGLE_API_KEY = st.secrets["GOOGLE_API_KEY"]
reporting_person = 'herath'
st.set_page_config(
page_title="LeavePal-Leave request Co-Pilot",
page_icon=":robot_face:", # Set your desired favicon
)
# generation_config = {
# "temperature": 0.0,
# "top_p": 1,
# "top_k": 1,
# "max_output_tokens": 2048
# }
safety_settings = [
{
"category": "HARM_CATEGORY_HARASSMENT",
"threshold": "BLOCK_ONLY_HIGH"
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_ONLY_HIGH"
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_ONLY_HIGH"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_ONLY_HIGH"
},
]
# Initialize Gemini-Pro
genai.configure(api_key=GOOGLE_API_KEY)
model = genai.GenerativeModel(model_name="gemini-pro",
generation_config = {"temperature": 0.0,},
safety_settings=safety_settings)
# Define the Flask API endpoint for user details
FLASK_API_ENDPOINT = 'https://dilshankavinda-login-app.hf.space/get_user_details'
def get_user_details():
response = requests.get(FLASK_API_ENDPOINT)
return response.json()
user_details = get_user_details()
try:
employee_id = int(user_details[-1]['Employee ID'])
employee_name = user_details[-1]['Name']
rpd = pd.read_csv('employees.csv')
rpd = rpd[rpd['Employee ID'] == employee_id]
rp = rpd["RP"]
reporting_person = rp.values[0]
# Get the current date and time
current_date_time = datetime.now()
# # Extract the date from the datetime object
# current_date = current_date_time.date()
# current_time = current_date_time.time()
# --------------------------INSIGHTS GENERATION----------------------------------
leave_data = pd.read_csv('leave_data.csv')
leave_allocation = pd.read_csv("Leave_Allocation.csv")
def leave_insights(employee_id,leave_data,leave_allocation):
filtered_df = leave_data[leave_data['Employee ID'] == employee_id]
merged_df = pd.merge(leave_allocation,filtered_df, left_on='LeaveTypeCode', right_on='Leave Type',how='left')
result_df = merged_df.groupby('LeaveTypeName')['No Days Used'].sum().reset_index()
final_df = pd.merge(result_df, leave_allocation, left_on='LeaveTypeName', right_on='LeaveTypeName')
final_df['Remaining days'] = final_df['AllocatedNoOfDays']-final_df['No Days Used']
new_final_df = final_df[['LeaveTypeName','AllocatedNoOfDays','No Days Used','Remaining days']]
return new_final_df
insights = leave_insights(employee_id,leave_data,leave_allocation)
text_insights = '**LEAVE BALANCE:**\n\n'
for index, row in insights.iterrows():
leave_type = row['LeaveTypeName']
actual_days = row['No Days Used']
allocated_days = row['AllocatedNoOfDays']
if actual_days <= allocated_days:
# insight = f"For {leave_type} leave, you took {actual_days} days out of {allocated_days} allocated days. No overuse."
insight =f"- **{leave_type}:** You can have ***{allocated_days-actual_days} leaves.*** ({actual_days} days out of {allocated_days} allocated days were used.)\n"
else:
overuse = actual_days - allocated_days
insight = f"For {leave_type} leave, you exceeded the allocated days by {overuse} days. Please review."
text_insights = text_insights+'\n'+insight
# ----------------------------------------------------------------------------------------------------
print(current_date_time)
# Gemini uses 'model' for assistant; Streamlit uses 'assistant'
def role_to_streamlit(role):
if role == "model":
return "assistant"
else:
return role
prompt = """
You are a friendly leave request copilot.your job is tocapture the following details from the user and give them as a Jason file.
extract the following information one after another and get confirmed by the user.
1.Leave type (these are the only leave types available. Annual leave, Casual leave, Lieu Leave, Maternity leave, Medical leave)
2.Starting date (in the format YYYY-MM-DD)
3.Ending date (in the format YYYY-MM-DD)
4.No Days (How many days take for leave can be calculated 'ending date-starting date')
5.Full day (This is for full day leave)
6.HalfDay (This is for half day leave)
7.Reason for leave (brief explanation)
8.Description (optional, for additional details)
9. generate remark using above data as following example
For a full day leave:'Dear [reporting person],I am writing to request leave from [Starting date] to [Ending date] due to [reason for leave].
I understand the importance of my responsibilities and will ensure that my work is up to date before my departure.
I will also make sure to provide any necessary handovers to my colleagues.Thank you for considering my request.
I look forward to your approval.'
For a half day leave:'Dear [Recipient's Name],I am writing to request half-day leave on [Starting date] due to [reason for leave].
I would like to take leave for [halfday] of the day.I understand the importance of my responsibilities and will ensure that my work is up to date before my departure.
Thank you for considering my request. I look forward to your approval.'
Example JSON Format for Full Day Leave:
{{  \"Leave Type\": \"Annual Leave\",  \"From\": \"2023-09-06\",  \"To\": \"2023-09-10\",  \"No Days\": 5,  \"FullDay\": \"Full Day\",  \"HalfDay\": None,  \"Leave Reason\": \"Wedding\",  \"Remark\":'Dear Dilshan Kavinda,I am writing to request leave from 2023-09-06 to 2023-09-10 due to a Wedding.I understand the importance of my responsibilities and will ensure that my work is up to date before my departure. Thank you for considering my request. I look forward to your approval.'}} 
Example JSON Format for Half Day Leave:
{{  \"Leave Type\": \"Casual Leave\",  \"From\": \"2023-09-06\",  \"To\": \"2023-09-06\",  \"No Days\": 0.5,  \"FullDay\": None,  \"HalfDay\": \"1st Half\",  \"Leave Reason\": \"Family Need\",  \"Remark\":'Dear Dilshan Kavinda,I am writing to request half-day leave on 2023-09-06 due to personal reasons. I would like to take leave for first half of the day.I understand the importance of my responsibilities and will ensure that my work is up to date before my departure. Thank you for considering my request. I look forward to your approval.'}}
-If any information is missing or unclear, prompt the user again for specific details
-If any information is missing or unclear,just ask to provide the missing information asking questions one by one.
-If the dates are invalid or the reason is too vague, ask for clarification.
-If user ask a leave on saturday or sunday remind user to it is already not a workday.
-VERY IMPORTANT: Make sure you Do not make up or guess ANY extra information.
-Only extract what exactly is in the user request.
-You respond in a short, very conversational friendly style.
Once you create the json ask user to save the leave request.To do that ask user to type 'SAVE'."""
history = [
{
"role": "user",
"parts": [prompt]
},
{
"role": "model",
"parts": ["Sure, I can help you with that. Here's the information I need from you to generate the JSON file:\n\n1. Leave Type:\n2. Starting Date (YYYY-MM-DD):\n3. Ending Date (YYYY-MM-DD):\n4. No of Days:\n5. Full Day (Full Day/None):\n6. Half Day (1st Half/2nd Half/None):\n7. Reason for Leave:\n8. Description (optional):\n\nOnce you provide me with this information, I'll generate a JSON file and a remark for you. Just let me know when you're ready.\n\nPlease provide the above information."]
},
{
"role": "user",
"parts": [f'today is {current_date_time} and reporting person is {reporting_person}']
},
{
"role": "model",
"parts": ["Thank you for providing the current date.Here's the information I need from you to generate the JSON file:\n\n1. Leave Type:\n2. Starting Date (YYYY-MM-DD):\n3. Ending Date (YYYY-MM-DD):\n4. No of Days:\n5. Full Day (Full Day/None):\n6. Half Day (1st Half/2nd Half/None):\n7. Reason for Leave:\n8. Description (optional):\n\nOnce you provide me with this information, I'll generate a JSON file and a remark for you. Just let me know when you're ready.\n\nPlease provide the above information."]
},
{
"role": "user",
"parts": [f'{text_insights}.These are the leave details belongs to employee_id{employee_id}']
},
{
"role": "model",
"parts": ["Thank you for providing the leave data.I will use those data to decide whether you are able to take the leave."]
},
{
"role": "user",
"parts": [f"Hi!,my name is {employee_name}"]
},
{
"role": "model",
"parts": [f"Hello {employee_name}, Do you want to take a leave ?"]
},
]
# Add a Gemini Chat history object to Streamlit session state
if "chat" not in st.session_state:
st.session_state.chat = model.start_chat(history = history)
# Display Form Title
st.title("Chat with LeavePal!")
st.subheader('I am your leave request co-pilot')
st.dataframe(insights)
# st.chat_message("assistant").markdown("Hi, How may I assit with you today?")
prompt_parts = [
f"{text_insights} give some recommendations using this context.summarize those recommendations for 5-10 points.",
]
response = model.generate_content(prompt_parts)
st.success(response.text)
# # Display chat messages from history above current input box
for message in st.session_state.chat.history[7:]:
with st.chat_message(role_to_streamlit(message.role)):
st.markdown(message.parts[0].text)
# Accept user's next message, add to context, resubmit context to Gemini
if prompt := st.chat_input("I am your leave request co-pilot. How may I assit you?"):
# Display user's last message
st.chat_message("user").markdown(prompt)
if prompt == 'SAVE':
try:
final_message = st.session_state.chat.history[-1]
input_string = final_message.parts[0].text
print(input_string)
# Extract JSON data from the string
json_start = input_string.find('{')
json_end = input_string.rfind('}')
json_data = input_string[json_start:json_end + 1]
# Load JSON data into a Python dictionary
leave_data_row = json.loads(json_data)
# Save the DataFrame to a CSV file
csv_filename = 'leave_data.csv'
print('test 1')
if os.path.isfile(csv_filename):
dfsize = pd.read_csv(csv_filename)
leave_data_row['Leave ID'] = dfsize.shape[0]+1 # Replace with an appropriate leave ID
else:
leave_data_row['Leave ID'] = 1
leave_data_row['Employee ID'] = employee_id # Replace with an appropriate employee ID
print('test 2')
# Map leave types to numerical values
leave_type_mapping = {
"annual leave": 1,
"casual leave": 2,
"lieu leave": 3,
"maternity leave": 4,
"medical leave": 5
}
# Check if the word is present in the leave type and map accordingly
for leave_type, value in leave_type_mapping.items():
if leave_type in leave_data_row['Leave Type'].lower():
leave_data_row['Leave Type'] = value
break
else:
# Default value if none of the conditions match
leave_data_row['Leave Type'] = leave_data_row['Leave Type']
print('test 3')
# Create a Pandas DataFrame
df = pd.DataFrame([leave_data_row])
if not os.path.isfile(csv_filename):
df.to_csv(csv_filename, index=False, mode='w')
else:
# Append the DataFrame to the existing CSV file
df.to_csv(csv_filename, mode='a', header=not pd.read_csv(csv_filename).shape[0] > 0, index=False)
print('test 4')
st.success(f'Leave request was submitted.')
except:
st.warning('If you have not already generated the json file, first generate it.')
st.info('If you have generated the json file ask me to show it again.Then type "SAVE"')
else:
# Send user entry to Gemini and read the response
response = st.session_state.chat.send_message(prompt)
# Display last
with st.chat_message("assistant"):
st.markdown(response.text)
except:
st.warning("Please login to the system")