shaileshjadhavSS commited on
Commit
20b2575
·
1 Parent(s): 246a4b8

Added cloudinary api for file storage

Browse files
.gitignore CHANGED
@@ -1,3 +1,10 @@
1
  **/__pycache__/
2
  *.env
3
- app.log
 
 
 
 
 
 
 
 
1
  **/__pycache__/
2
  *.env
3
+ app.log
4
+ *.jpg
5
+ *.jpeg
6
+ *.png
7
+ *.mp4
8
+ *.mp3
9
+ *.json
10
+ debug.log
README.md CHANGED
@@ -1,13 +1,74 @@
1
- ---
2
- title: WellnessAI
3
- emoji: 🚀
4
- colorFrom: purple
5
- colorTo: indigo
6
- sdk: streamlit
7
- sdk_version: 1.36.0
8
- app_file: app.py
9
- pinned: false
10
- license: apache-2.0
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # iConcierge Chatbot
2
+ The iConcierge chatbot is designed to assist users in tracking their meals, identifying recent meals, providing nutritional information, and suggesting the next meal of the day. The chatbot takes into account the user's profile, meal history, and other relevant factors to offer personalized meal suggestions.
3
+
4
+ ## Clone the repository
5
+ Clone the repository:
6
+ ```
7
+ $ git clone https://nonstop-development@bitbucket.org/nonstopio-dev/iconcierge.git
8
+
9
+ $ cd iconcierge
10
+ ```
11
+
12
+ ## Installation
13
+
14
+ ### Environment Configuration
15
+ First, create an env.sh file with the following content to set up your
16
+ environment variables:
17
+
18
+ ```
19
+ export GOOGLE_API_KEY="API_KEY"
20
+ export DB_NAME="DATABASE_NAME"
21
+ export DB_USER="USERNAME"
22
+ export DB_PASSWORD="PASSWORD"
23
+ export DB_HOST="localhost"
24
+ export DB_PORT="5432"
25
+ export CLOUDINARY_CLOUD_NAME="CLOUD_NAM"
26
+ export CLOUDINARY_API_KEY="CLOUDINARY_API_KEY"
27
+ export CLOUDINARY_API_SECRET="CLOUDINARY_API_SECRET"
28
+ ```
29
+
30
+ To apply these environment variables, run the following command in your console:
31
+ ```
32
+ source env.sh
33
+ ```
34
+
35
+ ### Package Installation
36
+
37
+ Next, install the required packages by running:
38
+ ```
39
+ pip install -r requirements.txt
40
+ ```
41
+
42
+ ### Execution
43
+ To run the iConcierge chatbot application, use the following command:
44
+ ```
45
+ streamlit run app.py
46
+ ```
47
+ The application will be available at http://localhost:8501.
48
+
49
+
50
+ ## Docker Setup
51
+
52
+ ## Prerequisites
53
+ To run this project using Docker, you need to have Docker installed on your machine. You can download and install Docker from the official Docker installation guide.
54
+
55
+ ## Installation
56
+
57
+ ## Build the Docker Image
58
+ Build the Docker image using the following command:
59
+ ```
60
+ docker build -t <image_name> .
61
+ ```
62
+
63
+ ## Run the Docker Container
64
+ Run the Docker container with the following command:
65
+ ```
66
+ docker run -p 8501:8501 <image_name>
67
+ ```
68
+ The application will be available at http://localhost:8501.
69
+
70
+ ## PostgreSQL (User Details)
71
+ We used Retool PostgreSQL to store user details, ensuring efficient and secure management of user data. Make sure your PostgreSQL database is properly configured and the credentials are correctly set in the env.sh file.
72
+
73
+ For more detailed documentation on how to configure and manage your PostgreSQL database, refer to the [official PostgreSQL documentation](https://www.postgresql.org/docs/).
74
+
app.py CHANGED
@@ -30,7 +30,7 @@ if 'model' not in st.session_state:
30
 
31
 
32
 
33
- def save_chat_history(user_name, chat_history):
34
  """
35
  Save chat history to a file in a user-specific directory with a timestamp.
36
  """
@@ -45,10 +45,18 @@ def save_chat_history(user_name, chat_history):
45
  serializable_history = []
46
  for entry in chat_history:
47
  if entry['role'] == 'user':
48
- user_entry = {
49
- 'role': 'user',
50
- 'parts': entry['parts'][1] if len(entry['parts']) > 1 else entry['parts'][0]
51
- }
 
 
 
 
 
 
 
 
52
  serializable_history.append(user_entry)
53
  elif entry['role'] == 'model':
54
  model_entry = {
@@ -60,8 +68,11 @@ def save_chat_history(user_name, chat_history):
60
  with open(file_path, "w") as f:
61
  json.dump(serializable_history, f, indent=4)
62
 
63
- logger.info(f"Chat history saved to {file_path}")
64
 
 
 
 
65
 
66
  def authenticate_user(email, password):
67
  """
@@ -72,7 +83,7 @@ def authenticate_user(email, password):
72
  authenticated = auth_manager.authenticate_user(email, password)
73
  return authenticated
74
 
75
- def conversation_chat(file_path, text_prompt):
76
  """
77
  Handle the conversation with the chat session using the provided file path and text prompt.
78
  """
@@ -89,7 +100,7 @@ def conversation_chat(file_path, text_prompt):
89
 
90
  logger.info(f"Successfully saved uploaded file: {file_path.name}")
91
 
92
- file = genai.upload_file(path=temp_file_path, display_name=file_path.name)
93
  user_entry = {
94
  "role": "user",
95
  "parts": [file, user_input]
@@ -117,7 +128,7 @@ def conversation_chat(file_path, text_prompt):
117
  logger.error(f"Error processing file: {e}")
118
  st.session_state.history.append("Error")
119
 
120
- def display_chat():
121
  """
122
  Display chat input and responses.
123
  """
@@ -131,7 +142,7 @@ def display_chat():
131
  if st.button('Logout'):
132
 
133
  # Save chat history before logging out
134
- save_chat_history(st.session_state.email, st.session_state.history)
135
 
136
  st.session_state.authenticated = False
137
  st.session_state.email = ""
@@ -149,7 +160,7 @@ def display_chat():
149
  submit_button = st.form_submit_button(label='Send ⬆️')
150
 
151
  if submit_button:
152
- conversation_chat(file_path, text_prompt)
153
 
154
  if clear_chat_button:
155
  st.session_state.history = []
@@ -162,9 +173,10 @@ def display_chat():
162
  if entry['role'] == 'user':
163
  if len(entry['parts']) > 1:
164
  uploaded_file = entry['parts'][0]
 
165
  if uploaded_file.mime_type.startswith("image/"):
166
  file_name= uploaded_file.display_name
167
- with open(os.path.join("temp", file_name), "rb") as file:
168
  encoded_img = base64.b64encode(file.read()).decode('utf-8')
169
  img_html = f'<img src="data:image/png;base64,{encoded_img}" width="200" style="margin-top: 5px;"/>'
170
  st.markdown(f"""
@@ -177,7 +189,7 @@ def display_chat():
177
  </div>
178
  """, unsafe_allow_html=True)
179
  else:
180
- message(uploaded_file.display_name, is_user=True, key=f"{i}_user", avatar_style="adventurer")
181
 
182
  if entry['parts'][1] != "":
183
  message(entry['parts'][1], is_user=True, key=f"{i}_user", avatar_style="adventurer")
@@ -199,7 +211,7 @@ def main():
199
  st.session_state.profile = user_manager.get_user(st.session_state.email).profile
200
  st.session_state.model = create_model(GOOGLE_API_KEY, st.session_state.profile)
201
 
202
- display_chat()
203
  else:
204
  st.title("Wellness Bot 🦾🤖 \n\nLogin/SignUp")
205
 
 
30
 
31
 
32
 
33
+ def save_chat_history(user_name, chat_history, user_manager):
34
  """
35
  Save chat history to a file in a user-specific directory with a timestamp.
36
  """
 
45
  serializable_history = []
46
  for entry in chat_history:
47
  if entry['role'] == 'user':
48
+ if len(entry['parts']) > 1:
49
+ uploaded_file = entry['parts'][0]
50
+ uploaded_file_url = user_manager.upload_to_cloudinary(uploaded_file.display_name)
51
+ user_entry = {
52
+ 'role': 'user',
53
+ 'parts': f"file_api: {uploaded_file.uri}, file_temp: {uploaded_file_url}, {entry['parts'][1]}"
54
+ }
55
+ else:
56
+ user_entry = {
57
+ 'role': 'user',
58
+ 'parts': entry['parts'][0]
59
+ }
60
  serializable_history.append(user_entry)
61
  elif entry['role'] == 'model':
62
  model_entry = {
 
68
  with open(file_path, "w") as f:
69
  json.dump(serializable_history, f, indent=4)
70
 
71
+ history_json = json.dumps(serializable_history)
72
 
73
+ user_manager.save_history(user_name, history_json)
74
+
75
+ logger.info(f"Chat history saved to {file_path}")
76
 
77
  def authenticate_user(email, password):
78
  """
 
83
  authenticated = auth_manager.authenticate_user(email, password)
84
  return authenticated
85
 
86
+ def conversation_chat(file_path, text_prompt, user_manager):
87
  """
88
  Handle the conversation with the chat session using the provided file path and text prompt.
89
  """
 
100
 
101
  logger.info(f"Successfully saved uploaded file: {file_path.name}")
102
 
103
+ file = genai.upload_file(path=temp_file_path, display_name=temp_file_path)
104
  user_entry = {
105
  "role": "user",
106
  "parts": [file, user_input]
 
128
  logger.error(f"Error processing file: {e}")
129
  st.session_state.history.append("Error")
130
 
131
+ def display_chat(user_manager):
132
  """
133
  Display chat input and responses.
134
  """
 
142
  if st.button('Logout'):
143
 
144
  # Save chat history before logging out
145
+ save_chat_history(st.session_state.email, st.session_state.history, user_manager)
146
 
147
  st.session_state.authenticated = False
148
  st.session_state.email = ""
 
160
  submit_button = st.form_submit_button(label='Send ⬆️')
161
 
162
  if submit_button:
163
+ conversation_chat(file_path, text_prompt, user_manager)
164
 
165
  if clear_chat_button:
166
  st.session_state.history = []
 
173
  if entry['role'] == 'user':
174
  if len(entry['parts']) > 1:
175
  uploaded_file = entry['parts'][0]
176
+ base_file_name = os.path.basename(uploaded_file.display_name)
177
  if uploaded_file.mime_type.startswith("image/"):
178
  file_name= uploaded_file.display_name
179
+ with open(file_name, "rb") as file:
180
  encoded_img = base64.b64encode(file.read()).decode('utf-8')
181
  img_html = f'<img src="data:image/png;base64,{encoded_img}" width="200" style="margin-top: 5px;"/>'
182
  st.markdown(f"""
 
189
  </div>
190
  """, unsafe_allow_html=True)
191
  else:
192
+ message(base_file_name, is_user=True, key=f"{i}_user", avatar_style="adventurer")
193
 
194
  if entry['parts'][1] != "":
195
  message(entry['parts'][1], is_user=True, key=f"{i}_user", avatar_style="adventurer")
 
211
  st.session_state.profile = user_manager.get_user(st.session_state.email).profile
212
  st.session_state.model = create_model(GOOGLE_API_KEY, st.session_state.profile)
213
 
214
+ display_chat(user_manager)
215
  else:
216
  st.title("Wellness Bot 🦾🤖 \n\nLogin/SignUp")
217
 
requirements.txt CHANGED
@@ -8,6 +8,7 @@ cachetools==5.3.3
8
  certifi==2024.6.2
9
  charset-normalizer==3.3.2
10
  click==8.1.7
 
11
  Flask==3.0.3
12
  Flask-Session==0.8.0
13
  gitdb==4.0.11
@@ -38,6 +39,7 @@ pillow==10.3.0
38
  proto-plus==1.24.0
39
  protobuf==4.25.3
40
  psycopg2-binary==2.9.9
 
41
  pyarrow==16.1.0
42
  pyasn1==0.6.0
43
  pyasn1_modules==0.4.0
 
8
  certifi==2024.6.2
9
  charset-normalizer==3.3.2
10
  click==8.1.7
11
+ cloudinary==1.40.0
12
  Flask==3.0.3
13
  Flask-Session==0.8.0
14
  gitdb==4.0.11
 
39
  proto-plus==1.24.0
40
  protobuf==4.25.3
41
  psycopg2-binary==2.9.9
42
+ psycopg2-binary==2.9.9
43
  pyarrow==16.1.0
44
  pyasn1==0.6.0
45
  pyasn1_modules==0.4.0
services/cloudinary_api.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ import cloudinary
2
+
3
+ def upload_image(file_path):
4
+ response = cloudinary.uploader.upload(file_path)
5
+ return response['url']
settings/base.py CHANGED
@@ -1,5 +1,6 @@
1
  import os
2
  import logging
 
3
 
4
  GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
5
 
@@ -9,6 +10,12 @@ DB_PASSWORD = os.environ.get("DB_PASSWORD")
9
  DB_HOST = os.environ.get("DB_HOST")
10
  DB_PORT = os.environ.get("DB_PORT")
11
 
 
 
 
 
 
 
12
  def setup_logger():
13
  logger = logging.getLogger('app_logger')
14
  logger.setLevel(logging.DEBUG)
 
1
  import os
2
  import logging
3
+ import cloudinary
4
 
5
  GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
6
 
 
10
  DB_HOST = os.environ.get("DB_HOST")
11
  DB_PORT = os.environ.get("DB_PORT")
12
 
13
+ # Configuration
14
+ cloudinary.config(
15
+ cloud_name = os.environ.get("CLOUDINARY_CLOUD_NAME"),
16
+ api_key = os.environ.get("CLOUDINARY_API_KEY"),
17
+ api_secret = os.environ.get("CLOUDINARY_API_SECRET")
18
+ )
19
  def setup_logger():
20
  logger = logging.getLogger('app_logger')
21
  logger.setLevel(logging.DEBUG)
user_auth/user_manager.py CHANGED
@@ -1,6 +1,8 @@
1
  import psycopg2
 
 
2
  from user_auth.user import User
3
- from settings.base import setup_logger, DB_HOST, DB_NAME, DB_PASSWORD, DB_PORT, DB_USER
4
 
5
 
6
  logger = setup_logger()
@@ -51,8 +53,33 @@ class UserManager:
51
  "daily_calorie_intake": result[14]
52
  }
53
  logger.info(f'User retrieved from database: {result[1]}')
54
- return User(email=result[1], password=result[1], profile=profile)
55
  return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  def close(self):
58
  self.cursor.close()
 
1
  import psycopg2
2
+ from psycopg2 import sql
3
+ import cloudinary.uploader
4
  from user_auth.user import User
5
+ from settings.base import setup_logger, DB_HOST, DB_NAME, DB_PASSWORD, DB_PORT, DB_USER, cloudinary
6
 
7
 
8
  logger = setup_logger()
 
53
  "daily_calorie_intake": result[14]
54
  }
55
  logger.info(f'User retrieved from database: {result[1]}')
56
+ return User(email=result[1], password=result[2], profile=profile)
57
  return None
58
+
59
+ def save_history(self, email, history_json):
60
+ try:
61
+ with self.conn.cursor() as cur:
62
+ query = sql.SQL("""
63
+ INSERT INTO chat_history (username, data)
64
+ VALUES (%s, %s)
65
+ """)
66
+ cur.execute(query, (email, history_json))
67
+ self.conn.commit()
68
+ logger.info(f"Chat history saved to database for user: {email}")
69
+ except Exception as e:
70
+ self.conn.rollback()
71
+ logger.error(f"Error saving chat history to database: {e}")
72
+
73
+ def upload_to_cloudinary(self, file_path):
74
+ try:
75
+ # Upload file to Cloudinary
76
+ upload_result = cloudinary.uploader.upload(file_path)
77
+ uploaded_file_url = upload_result['url']
78
+ logger.info(f"Uploaded file to Cloudinary: {uploaded_file_url}")
79
+ return uploaded_file_url
80
+ except Exception as e:
81
+ logger.exception(f"Error uploading file to Cloudinary: {repr(e)}")
82
+ return None
83
 
84
  def close(self):
85
  self.cursor.close()