RaheelShah commited on
Commit
08bbb48
·
verified ·
1 Parent(s): 7085b3a

Upload 8 files

Browse files
Files changed (8) hide show
  1. ChatBOt.py +265 -0
  2. NaveedShahnawaz.png +0 -0
  3. Raheel.png +0 -0
  4. Sania.png +0 -0
  5. Tulaib.png +0 -0
  6. WAPDA_logo.png +0 -0
  7. WakeelAhmad.png +0 -0
  8. sanapic.png +0 -0
ChatBOt.py ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import streamlit as st
3
+ from PIL import Image, ImageOps, ImageDraw
4
+ from bs4 import BeautifulSoup
5
+ from gtts import gTTS
6
+ from langchain.prompts import (
7
+ ChatPromptTemplate,
8
+ HumanMessagePromptTemplate,
9
+ MessagesPlaceholder,
10
+ SystemMessagePromptTemplate,
11
+ )
12
+ from langchain.schema.output_parser import StrOutputParser
13
+ from langchain_community.chat_message_histories import StreamlitChatMessageHistory
14
+ from langchain_core.runnables.history import RunnableWithMessageHistory
15
+ from langchain_google_genai import ChatGoogleGenerativeAI
16
+ from streamlit_mic_recorder import speech_to_text
17
+
18
+ # Set the page configuration
19
+ st.set_page_config(page_title="AI Voice Assistant", page_icon="🤖")
20
+
21
+
22
+ # Function for cropping images into a circular shape
23
+ def crop_circle(image, crop_size):
24
+ img = ImageOps.fit(image, crop_size, centering=(0.5, 0.2))
25
+ mask = Image.new("L", crop_size, 0)
26
+ mask_draw = ImageDraw.Draw(mask)
27
+ mask_draw.ellipse((0, 0, crop_size[0], crop_size[1]), fill=255)
28
+ img.putalpha(mask)
29
+ return img
30
+
31
+
32
+ # Function for "About Team" section
33
+ def about_team():
34
+ st.title("About Team")
35
+ st.write("Welcome to the About Team page!")
36
+
37
+ # Load reference image for cropping size
38
+ reference_image_path = "Tulaib.png"
39
+ try:
40
+ reference_image = Image.open(reference_image_path)
41
+ crop_size = reference_image.size
42
+ except FileNotFoundError:
43
+ st.error(f"Reference image {reference_image_path} not found!")
44
+ return
45
+
46
+ team_members = [
47
+ {"image": "WakeelAhmad.png", "name": "Wakeel Ahmed", "discipline": "Electrical Engineer"},
48
+ {"image": "Raheel.png", "name": "Raheel Naveed", "discipline": "Mechatronics Engineer"},
49
+ {"image": "Tulaib.png", "name": "Muhammad Tulaib", "discipline": "Civil Engineer"},
50
+ {"image": "NaveedShahnawaz.png", "name": "Naveed Shahnawaz", "discipline": "Electrical Engineer"},
51
+ {"image": "Sania.png", "name": "Sania", "discipline": "Biomedical Engineer"},
52
+ {"image": "sanapic.png", "name": "Sana Tariq", "discipline": "Electronic Engineer"},
53
+ ]
54
+
55
+ for i in range(0, len(team_members), 3):
56
+ cols = st.columns(3)
57
+ for col, member in zip(cols, team_members[i:i + 3]):
58
+ with col:
59
+ try:
60
+ img = Image.open(member["image"])
61
+ circular_img = crop_circle(img, crop_size)
62
+ st.image(circular_img, use_container_width=True)
63
+ except FileNotFoundError:
64
+ st.error(f"Image not found: {member['image']}")
65
+ st.subheader(member["name"])
66
+ st.write(f"{member['discipline']}")
67
+
68
+
69
+ # Function for chatbot
70
+ def chatbot():
71
+ st.title("AI Voice Assistant 🎙️")
72
+ st.subheader("Interact in Urdu with Real-Time Voice Input")
73
+
74
+ api_key = "AIzaSyBsOwOK77hDyCAmr3Ce25E3F3rGh7okPb8"
75
+ prompt = ChatPromptTemplate(
76
+ messages=[
77
+ SystemMessagePromptTemplate.from_template(
78
+ "You are a helpful AI assistant for WAPDA Services In Pakistan called WAPDA CHATBOT. Please always respond to user queries in Pure Urdu language. And answer to questions regarding the WAPDA to help users, but always keep the responses short, help users to give tips about electricity"),
79
+ MessagesPlaceholder(variable_name="chat_history"),
80
+ HumanMessagePromptTemplate.from_template("{question}"),
81
+ ]
82
+ )
83
+
84
+ msgs = StreamlitChatMessageHistory(key="langchain_messages")
85
+ model = ChatGoogleGenerativeAI(model="gemini-1.5-flash", google_api_key=api_key)
86
+ chain = prompt | model | StrOutputParser()
87
+ chain_with_history = RunnableWithMessageHistory(
88
+ chain, lambda session_id: msgs, input_messages_key="question", history_messages_key="chat_history"
89
+ )
90
+
91
+ st.write("Press the button and start speaking in Urdu:")
92
+
93
+ with st.spinner("Converting Speech To Text..."):
94
+ text = speech_to_text(language="ur", use_container_width=True, just_once=True, key="STT")
95
+
96
+ if text:
97
+ st.chat_message("human").write(text)
98
+ with st.chat_message("assistant"):
99
+ message_placeholder = st.empty()
100
+ full_response = ""
101
+ response = chain_with_history.stream({"question": text}, {"configurable": {"session_id": "any"}})
102
+
103
+ for res in response:
104
+ full_response += res or ""
105
+ message_placeholder.markdown(full_response + "|")
106
+ message_placeholder.markdown(full_response)
107
+
108
+ with st.spinner("Converting Text To Speech..."):
109
+ tts = gTTS(text=full_response, lang="ur")
110
+ tts.save("output.mp3")
111
+ st.audio("output.mp3")
112
+ else:
113
+ st.warning("Please press the button and start speaking.")
114
+
115
+
116
+ # Function to fetch and parse bill details
117
+ def determine_url(num):
118
+ base_url = {"14": "iescobill", "12": "gepcobill", "11": "lescobill", "15": "mepcobill", "26": "pescobill"}
119
+ return f"https://bill.pitc.com.pk/{base_url.get(num[2:4])}/general?refno={num}" if len(
120
+ num) == 14 and num.isdigit() and num[2:4] in base_url else None
121
+
122
+ import requests
123
+ from bs4 import BeautifulSoup
124
+ import re
125
+ import streamlit as st
126
+
127
+ # Define the mapping of company codes to their corresponding URLs
128
+ company_codes = {
129
+ "1": "lesco",
130
+ "2": "gepco",
131
+ "3": "fesco",
132
+ "4": "iesco",
133
+ "5": "mepco",
134
+ }
135
+
136
+ # Function to fetch and parse the HTML content
137
+ def fetch_and_parse(url):
138
+ try:
139
+ response = requests.get(url)
140
+ response.raise_for_status() # Check if the request was successful
141
+ soup = BeautifulSoup(response.text, "html.parser")
142
+ return soup
143
+ except requests.exceptions.RequestException as e:
144
+ st.error(f"Error fetching the URL: {e}")
145
+ return None
146
+
147
+ # Function to extract key-value pairs from the table
148
+ # Function to extract key-value pairs from the table
149
+ def extract_key_value_pairs(soup):
150
+ print("Extracting key-value pairs from the soup object...")
151
+ if soup:
152
+ table = soup.find("table", style="text-align: center; width: 100%; border-collapse: collapse;")
153
+ if not table:
154
+ print("Table not found!")
155
+ return None
156
+
157
+ rows = table.find_all("tr")
158
+ header_cells = rows[0].find_all("td")
159
+ headers = [header.get_text(strip=True) for header in header_cells]
160
+
161
+ data_cells = rows[1].find_all("td")
162
+ values = [cell.get_text(strip=True).replace("\n", " ").strip() for cell in data_cells]
163
+
164
+ key_value_pairs = {
165
+ headers[0]: values[0],
166
+ headers[1]: values[1],
167
+ headers[2]: values[2],
168
+ headers[3]: headers[4],
169
+ values[3]: values[4]
170
+ }
171
+
172
+ print(f"Extracted key-value pairs: {key_value_pairs}")
173
+ return key_value_pairs
174
+ else:
175
+ print("Soup object is None. Couldn't parse the HTML.")
176
+ return None
177
+
178
+
179
+ def refine_dictionary(key_value_pairs):
180
+ print("Refining the key-value pairs...")
181
+ refined_dict = {}
182
+ for key, value in key_value_pairs.items():
183
+ refined_dict[key] = re.sub(r'\s+', ' ', value.strip())
184
+ print(f"Refined key-value pairs: {refined_dict}")
185
+ return refined_dict
186
+ # Function to generate a contextual paragraph from bill information
187
+ # Function to generate a contextual paragraph from bill information
188
+ def generate_context_paragraph(refined_key_value_pairs):
189
+ context_paragraph = (
190
+ f"The user has provided the following billing information:\n"
191
+ f"- The billing month for the user is: {refined_key_value_pairs['BILL MONTH']}.\n"
192
+ f"- The due date for the current bill is: {refined_key_value_pairs['DUE DATE']}.\n"
193
+ f"- The reference number associated with this bill is: {refined_key_value_pairs['REFERENCE NO']}.\n"
194
+ f"- The amount payable within the due date is: {refined_key_value_pairs['PAYABLE WITHIN DUE DATE']}.\n"
195
+ f"- If payment is delayed, the amount payable after the due date will be: {refined_key_value_pairs['PAYABLE AFTER DUE DATE']}.\n"
196
+ )
197
+ return context_paragraph
198
+ # Function to fetch bill details based on the reference number
199
+ def fetch_bill_details(reference_number):
200
+ if len(reference_number) < 4:
201
+ st.error("Invalid reference number. It must be at least 4 digits long.")
202
+ return None, None, None
203
+
204
+ fourth_digit = reference_number[3]
205
+ if fourth_digit in company_codes:
206
+ company_code = company_codes[fourth_digit]
207
+ url = f"https://bill.pitc.com.pk/{company_code}bill/general?refno={reference_number}"
208
+ soup = fetch_and_parse(url)
209
+
210
+ if soup:
211
+ key_value_pairs = extract_key_value_pairs(soup)
212
+ if key_value_pairs:
213
+ refined_key_value_pairs = refine_dictionary(key_value_pairs)
214
+
215
+ # Extract the correct payable amount within the due date
216
+ payable_within_due_date = refined_key_value_pairs.get('PAYABLE WITHIN DUE DATE', 'N/A')
217
+ if payable_within_due_date == 'PAYABLE AFTER DUE DATE':
218
+ refined_key_value_pairs['PAYABLE WITHIN DUE DATE'] = refined_key_value_pairs.get('PAYABLE AFTER DUE DATE', 'N/A')
219
+
220
+ context_paragraph = generate_context_paragraph(refined_key_value_pairs)
221
+ return refined_key_value_pairs, context_paragraph
222
+ return None, None
223
+
224
+
225
+
226
+ # Main function
227
+ def main():
228
+ st.sidebar.image("WAPDA_logo.png", width=100)
229
+ st.sidebar.markdown("Made with ❤️ by Flash Team")
230
+ app_selection = st.sidebar.radio("Go to", ["Welcome","About Team", "WAPDA Bill Checker", "Chat Bot"])
231
+
232
+ if app_selection == "Welcome":
233
+ st.markdown(
234
+ "<h1 style='font-size: 50px; font-weight: bold;'>Welcome to the WAPDA BillBOT</h1>",
235
+ unsafe_allow_html=True
236
+ )
237
+ st.markdown(
238
+ """
239
+ <p style='font-size: 18px;'>
240
+ The WAPDA BillBOT is your AI-powered assistant for managing electricity billing information with ease.
241
+ Whether you need to fetch bill details, interact using voice commands in Urdu, or learn more about our team,
242
+ this application is here to provide you with a seamless experience. Explore the features from the menu on the left,
243
+ and let us assist you in simplifying your billing tasks.
244
+ </p>
245
+ """,
246
+ unsafe_allow_html=True
247
+ )
248
+ elif app_selection == "About Team":
249
+ about_team()
250
+ elif app_selection == "WAPDA Bill Checker":
251
+ st.title("WAPDA Bill Checker")
252
+ reference_number = st.text_input("Enter your bill reference number:")
253
+ if st.button("Fetch Bill Details"):
254
+ refined_data, context = fetch_bill_details(reference_number)
255
+ if refined_data:
256
+ st.success("Bill details fetched successfully!")
257
+ st.write(context)
258
+ else:
259
+ st.error("Failed to fetch bill details.")
260
+ elif app_selection == "Chat Bot":
261
+ chatbot()
262
+
263
+
264
+ if __name__ == "__main__":
265
+ main()
NaveedShahnawaz.png ADDED
Raheel.png ADDED
Sania.png ADDED
Tulaib.png ADDED
WAPDA_logo.png ADDED
WakeelAhmad.png ADDED
sanapic.png ADDED