ruslanmv commited on
Commit
120d6fd
1 Parent(s): 4bae090
Files changed (3) hide show
  1. app.py +29 -111
  2. styles.css +61 -0
  3. utils.py +36 -0
app.py CHANGED
@@ -1,112 +1,17 @@
1
- # For reading credentials from the .env file
2
  import os
3
  from dotenv import load_dotenv
4
  import streamlit as st
5
  import webchat
6
-
7
  # URL of the hosted LLMs is hardcoded because at this time all LLMs share the same endpoint
8
  url = "https://us-south.ml.cloud.ibm.com"
9
-
10
  # These global variables will be updated in get_credentials() function
11
  watsonx_project_id = ""
12
- # Replace with your IBM Cloud key
13
  api_key = ""
14
-
15
- def get_credentials():
16
- load_dotenv()
17
- # Update the global variables that will be used for authentication in another function
18
- globals()["api_key"] = os.getenv("api_key", None)
19
- globals()["watsonx_project_id"] = os.getenv("project_id", None)
20
-
21
-
22
- def set_theme():
23
- st.markdown("""
24
- <style>
25
- .reportview-container, .main {
26
- background: #ffffff;
27
- color: #000000;
28
- }
29
- .sidebar .sidebar-content {
30
- background: #f0f2f6;
31
- color: #000000;
32
- }
33
- .stButton>button {
34
- background-color: #0D62FE;
35
- color: white;
36
- }
37
- .stTextInput>div>div>input {
38
- color: #000000;
39
- background-color: #ffffff;
40
- }
41
- tTextArea>div>textarea {
42
- color: #000000;
43
- background-color: #ffffff;
44
- }
45
- label, .stTextInput>label, .stTextArea>label {
46
- color: #000000;
47
- }
48
- h1, h2, h3, h4, h5, h6 {
49
- color: #000000;
50
- }
51
- .sidebar .sidebar-content h2, .sidebar .sidebar-content h3, .sidebar .sidebar-content h4, .sidebar .sidebar-content h5, .sidebar .sidebar-content h6,
52
- .sidebar .sidebar-content label, .sidebar .sidebar-content .stTextInput>label, .sidebar .sidebar-content .stTextArea>label {
53
- color: #000000;
54
- }
55
- .navbar {
56
- overflow: hidden;
57
- background-color: #000000;
58
- position: fixed;
59
- top: 0;
60
- width: 100%;
61
- z-index: 1000;
62
- }
63
- .navbar h1 {
64
- float: left;
65
- display: block;
66
- color: #ffffff;
67
- text-align: center;
68
- padding: 14px 1x;
69
- text-decoration: none;
70
- font-size: 17px;
71
- margin: 0;
72
- }
73
- .menu-bar {
74
- background-color: #000000;
75
- padding: 10px;
76
- display: flex;
77
- justify-content: space-between;
78
- align-items: center;
79
- }
80
- .menu-bar h1 {
81
- color: #ffffff;
82
- margin: 0;
83
- font-size: 18px; /* Reduced font size */
84
- font-family: 'IBM Plex Sans', sans-serif; /* IBM font */
85
- }
86
- </style>
87
- """, unsafe_allow_html=True)
88
-
89
-
90
- from urllib.parse import urlparse
91
-
92
- def create_collection_name(url):
93
- parsed_url = urlparse(url)
94
- domain_parts = parsed_url.netloc.split('.')
95
- if len(domain_parts) >= 2:
96
- return domain_parts[-2] # Extracting the second-level domain
97
- else:
98
- return "base"
99
-
100
  def main():
101
- # Get the API key and project id and update global variables
102
- get_credentials()
103
-
104
- # Use the full page instead of a narrow central column
105
  st.set_page_config(layout="wide", page_title="RAG Web Demo", page_icon="")
106
-
107
- # Set the theme
108
- set_theme()
109
-
110
  # Streamlit app title with style
111
  st.markdown("""
112
  <div class="menu-bar">
@@ -115,37 +20,50 @@ def main():
115
  <div style="margin-top: 20px;"><p>Insert the website you want to chat with and ask your question.</p></div>
116
 
117
  """, unsafe_allow_html=True)
118
-
119
  # Sidebar for settings
120
  st.sidebar.header("Settings")
121
- st.sidebar.markdown("Insert your credentials of [IBM Cloud](https://cloud.ibm.com/login) for watsonx.ai", unsafe_allow_html=True)
122
  st.sidebar.markdown("<hr>", unsafe_allow_html=True)
123
  api_key_input = st.sidebar.text_input("API Key", api_key, type="password")
124
  project_id_input = st.sidebar.text_input("Project ID", watsonx_project_id)
125
-
126
  # Update credentials if provided by the user
127
  if api_key_input:
128
  globals()["api_key"] = api_key_input
129
  if project_id_input:
130
  globals()["watsonx_project_id"] = project_id_input
131
-
132
  # Main input area
133
- #st.markdown("<hr>", unsafe_allow_html=True)
134
  user_url = st.text_input('Provide a URL')
135
- # Provide a unique name for this website (lower case). Use the same name for the same URL to avoid loading data multiple times.
136
- collection_name = create_collection_name(user_url)
137
  # UI component to enter the question
138
  question = st.text_area('Question', height=100)
139
  button_clicked = st.button("Answer the question")
140
-
141
  st.markdown("<hr>", unsafe_allow_html=True)
142
  st.subheader("Response")
 
 
 
 
 
 
 
 
 
 
143
 
144
- # Invoke the LLM when the button is clicked
145
- if button_clicked:
146
- response = webchat.answer_questions_from_web(api_key, watsonx_project_id, user_url, question, collection_name)
147
- st.write(response)
148
-
 
 
 
 
 
 
 
 
 
 
149
 
150
  if __name__ == "__main__":
151
  main()
 
 
1
  import os
2
  from dotenv import load_dotenv
3
  import streamlit as st
4
  import webchat
5
+ import utils
6
  # URL of the hosted LLMs is hardcoded because at this time all LLMs share the same endpoint
7
  url = "https://us-south.ml.cloud.ibm.com"
 
8
  # These global variables will be updated in get_credentials() function
9
  watsonx_project_id = ""
 
10
  api_key = ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  def main():
12
+ utils.get_credentials()
 
 
 
13
  st.set_page_config(layout="wide", page_title="RAG Web Demo", page_icon="")
14
+ utils.load_css("styles.css")
 
 
 
15
  # Streamlit app title with style
16
  st.markdown("""
17
  <div class="menu-bar">
 
20
  <div style="margin-top: 20px;"><p>Insert the website you want to chat with and ask your question.</p></div>
21
 
22
  """, unsafe_allow_html=True)
 
23
  # Sidebar for settings
24
  st.sidebar.header("Settings")
25
+ st.sidebar.markdown("Insert your credentials of [IBM Cloud](https://cloud.ibm.com/login) for watsonx.ai \n The data is not saved in th server. Your data is secured.", unsafe_allow_html=True)
26
  st.sidebar.markdown("<hr>", unsafe_allow_html=True)
27
  api_key_input = st.sidebar.text_input("API Key", api_key, type="password")
28
  project_id_input = st.sidebar.text_input("Project ID", watsonx_project_id)
 
29
  # Update credentials if provided by the user
30
  if api_key_input:
31
  globals()["api_key"] = api_key_input
32
  if project_id_input:
33
  globals()["watsonx_project_id"] = project_id_input
 
34
  # Main input area
 
35
  user_url = st.text_input('Provide a URL')
 
 
36
  # UI component to enter the question
37
  question = st.text_area('Question', height=100)
38
  button_clicked = st.button("Answer the question")
 
39
  st.markdown("<hr>", unsafe_allow_html=True)
40
  st.subheader("Response")
41
+ collection_name="base"
42
+ ## Cleaning Vector Database
43
+ #utils.clear_collection(collection_name)
44
+ if globals()["api_key"] and globals()["watsonx_project_id"]:
45
+ # Provide a unique name for this website (lower case). Use the same name for the same URL to avoid loading data multiple times.
46
+ #collection_name = utils.create_collection_name(user_url)
47
+ if button_clicked and user_url:
48
+ # Invoke the LLM when the button is clicked
49
+ response = webchat.answer_questions_from_web(api_key, watsonx_project_id, user_url, question, collection_name)
50
+ st.write(response)
51
 
52
+ else:
53
+ st.warning("Please provide API Key and Project ID in the sidebar.")
54
+
55
+ # Cleaning Vector Database
56
+ st.sidebar.markdown("<hr>", unsafe_allow_html=True)
57
+ st.sidebar.header("Memory")
58
+ clean_button_clicked = st.sidebar.button("Clean Memory")
59
+ if clean_button_clicked :
60
+ if collection_name: # Check if collection_name is defined and not empty
61
+ utils.clear_collection(collection_name)
62
+ st.sidebar.success("Memory cleared successfully!")
63
+ #st.sidebar.markdown(collection_name, unsafe_allow_html=True)
64
+ print("Memory cleared successfully!")
65
+ else:
66
+ st.sidebar.error("Collection name is not defined or empty.")
67
 
68
  if __name__ == "__main__":
69
  main()
styles.css ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .reportview-container, .main {
2
+ background: #ffffff;
3
+ color: #000000;
4
+ }
5
+ .sidebar .sidebar-content {
6
+ background: #f0f2f6;
7
+ color: #000000;
8
+ }
9
+ .stButton>button {
10
+ background-color: #0D62FE;
11
+ color: white;
12
+ }
13
+ .stTextInput>div>div>input {
14
+ color: #000000;
15
+ background-color: #ffffff;
16
+ }
17
+ .tTextArea>div>textarea {
18
+ color: #000000;
19
+ background-color: #ffffff;
20
+ }
21
+ label, .stTextInput>label, .stTextArea>label {
22
+ color: #000000;
23
+ }
24
+ h1, h2, h3, h4, h5, h6 {
25
+ color: #000000;
26
+ }
27
+ .sidebar .sidebar-content h2, .sidebar .sidebar-content h3, .sidebar .sidebar-content h4, .sidebar .sidebar-content h5, .sidebar .sidebar-content h6,
28
+ .sidebar .sidebar-content label, .sidebar .sidebar-content .stTextInput>label, .sidebar .sidebar-content .stTextArea>label {
29
+ color: #000000;
30
+ }
31
+ .navbar {
32
+ overflow: hidden;
33
+ background-color: #000000;
34
+ position: fixed;
35
+ top: 0;
36
+ width: 100%;
37
+ z-index: 1000;
38
+ }
39
+ .navbar h1 {
40
+ float: left;
41
+ display: block;
42
+ color: #ffffff;
43
+ text-align: center;
44
+ padding: 14px 1x;
45
+ text-decoration: none;
46
+ font-size: 17px;
47
+ margin: 0;
48
+ }
49
+ .menu-bar {
50
+ background-color: #000000;
51
+ padding: 10px;
52
+ display: flex;
53
+ justify-content: space-between;
54
+ align-items: center;
55
+ }
56
+ .menu-bar h1 {
57
+ color: #ffffff;
58
+ margin: 0;
59
+ font-size: 18px;
60
+ font-family: 'IBM Plex Sans', sans-serif;
61
+ }
utils.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from urllib.parse import urlparse
2
+ from dotenv import load_dotenv
3
+ import os
4
+ import chromadb
5
+ import streamlit as st
6
+ def get_credentials():
7
+ load_dotenv()
8
+ globals()["api_key"] = os.getenv("api_key", None)
9
+ globals()["watsonx_project_id"] = os.getenv("project_id", None)
10
+
11
+ def load_css(file_name):
12
+ with open(file_name) as file:
13
+ st.markdown(f'<style>{file.read()}</style>', unsafe_allow_html=True)
14
+
15
+ def create_collection_name(url):
16
+ parsed_url = urlparse(url)
17
+ domain_parts = parsed_url.netloc.split('.')
18
+ if len(domain_parts) >= 2:
19
+ return domain_parts[-2] # Extracting the second-level domain
20
+ else:
21
+ return "base"
22
+
23
+
24
+
25
+ def clear_collection(collection_name):
26
+ client = chromadb.Client()
27
+ try:
28
+ collection = client.get_collection(collection_name)
29
+ if collection:
30
+ collection.delete()
31
+ print(f"Collection '{collection_name}' cleared successfully!")
32
+ except ValueError:
33
+ pass # collection does not exist, do nothing
34
+
35
+
36
+