Jesse Liu commited on
Commit
6a725a4
·
1 Parent(s): 58ee581
.gitignore CHANGED
@@ -81,3 +81,14 @@ Thumbs.db
81
  /summaries/*
82
  /assets/*
83
  trace_back_results_30patient_2ad/
 
 
 
 
 
 
 
 
 
 
 
 
81
  /summaries/*
82
  /assets/*
83
  trace_back_results_30patient_2ad/
84
+
85
+ # Google Drive credentials (sensitive)
86
+ service-account-key.json
87
+ *service-account*.json
88
+ user_tokens/
89
+ *.pickle
90
+ *.pkl
91
+
92
+ # Environment variables
93
+ .env
94
+ .env.local
DEPLOY_INSTRUCTIONS.md ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Steps to Deploy on Hugging Face
2
+
3
+ ## Step 1: Generate a Hugging Face token
4
+
5
+ 1. Visit https://huggingface.co/settings/tokens
6
+ 2. Click **“New token”**
7
+ 3. Choose **“Write”** permission
8
+ 4. Copy the generated token
9
+
10
+ ## Step 2: Log in to Hugging Face
11
+
12
+ Run in your terminal:
13
+
14
+ ```bash
15
+ huggingface-cli login
16
+ ```
17
+
18
+ Then paste your token when prompted.
19
+
20
+ Or provide it via environment variable:
21
+
22
+ ```bash
23
+ export HF_TOKEN="your_token"
24
+ huggingface-cli login --token $HF_TOKEN
25
+ ```
26
+
27
+ ## Step 3: Deploy the app
28
+
29
+ Run:
30
+
31
+ ```bash
32
+ gradio deploy
33
+ ```
34
+
35
+ Or use the helper script:
36
+
37
+ ```bash
38
+ ./deploy_hf.sh
39
+ ```
40
+
41
+ ## Step 4: Add Google Drive secrets (post-deployment)
42
+
43
+ 1. Open your Space page: `https://huggingface.co/spaces/<username>/<space-name>`
44
+ 2. Go to the **“Settings”** tab
45
+ 3. Under **“Repository secrets”** add:
46
+ - **Name**: `GOOGLE_SERVICE_ACCOUNT_JSON`
47
+ - **Value**: paste the full Service Account JSON content
48
+
49
+ ## Done!
50
+
51
+ Wait 2–5 minutes for the build to finish, then open your Space URL.
52
+
DEPLOY_NOW.md ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Deploy to Hugging Face Right Now
2
+
3
+ ## Problem
4
+ The CLI error shows that Space names cannot contain spaces, so you must provide a valid identifier.
5
+
6
+ ## Solution
7
+
8
+ Run this inside your `chatbot` environment:
9
+
10
+ ```bash
11
+ gradio deploy --space chatbot-mimic-notes
12
+ ```
13
+
14
+ Or include your Hugging Face username:
15
+
16
+ ```bash
17
+ gradio deploy --space your-username/chatbot-mimic-notes
18
+ ```
19
+
20
+ ## Valid Space Name Rules
21
+ - ✅ Letters, digits, hyphen `-`, underscore `_`, dot `.`
22
+ - ✅ Cannot start or end with `-` or `.`
23
+ - ✅ `--` and `..` are not allowed
24
+ - ✅ Maximum length 96 characters
25
+ - ❌ No spaces
26
+
27
+ ## Examples
28
+ ```bash
29
+ # Valid
30
+ gradio deploy --space chatbot-mimic-notes
31
+ gradio deploy --space my-chatbot-app
32
+ gradio deploy --space chatbot_123
33
+
34
+ # Invalid (contains spaces)
35
+ gradio deploy --space "Chatbot Mimic Notes"
36
+ ```
37
+
DEPLOY_SIMPLE.md ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Simplest Deployment Path
2
+
3
+ Because this version of `gradio deploy` does not accept the `--space` flag, use Git-based deployment instead.
4
+
5
+ ## Option 1: Deployment Script (recommended)
6
+
7
+ ```bash
8
+ ./deploy_git.sh
9
+ ```
10
+
11
+ The script automatically:
12
+ 1. Checks login status
13
+ 2. Creates or updates the Space
14
+ 3. Copies files and pushes via Git
15
+
16
+ ## Option 2: Manual Git Workflow
17
+
18
+ ### Step 1: Create the Space
19
+
20
+ Visit https://huggingface.co/new-space or run:
21
+
22
+ ```bash
23
+ huggingface-cli repo create chatbot-mimic-notes --type space --sdk gradio
24
+ ```
25
+
26
+ ### Step 2: Clone the Space
27
+
28
+ ```bash
29
+ git clone https://huggingface.co/spaces/jesseliu/chatbot-mimic-notes
30
+ cd chatbot-mimic-notes
31
+ ```
32
+
33
+ ### Step 3: Copy project files
34
+
35
+ ```bash
36
+ # Copy required files
37
+ cp ../chatbot-mimic-notes/chatgpt.py .
38
+ cp ../chatbot-mimic-notes/README.md .
39
+ cp ../chatbot-mimic-notes/requirements.txt .
40
+ cp -r ../chatbot-mimic-notes/src ./src
41
+ cp ../chatbot-mimic-notes/google_drive_sync.py .
42
+ ```
43
+
44
+ ### Step 4: Commit and push
45
+
46
+ ```bash
47
+ git add .
48
+ git commit -m "Initial deployment"
49
+ git push
50
+ ```
51
+
52
+ ## Done!
53
+
54
+ Wait 2–5 minutes for the build, then visit:
55
+ https://huggingface.co/spaces/jesseliu/chatbot-mimic-notes
56
+
57
+ ## Configure Google Drive Secrets
58
+
59
+ 1. Open Space Settings
60
+ 2. Add secret: `GOOGLE_SERVICE_ACCOUNT_JSON`
61
+ 3. Paste the full Service Account JSON content
62
+
HUGGINGFACE_DEPLOY.md ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Hugging Face Spaces Deployment Guide
2
+
3
+ This guide walks through deploying the chatbot to Hugging Face Spaces so you have a permanent HTTPS endpoint.
4
+
5
+ ## 📋 Prerequisites
6
+
7
+ 1. **Hugging Face account**
8
+ - Sign up at [huggingface.co](https://huggingface.co)
9
+ - Verify your email
10
+
11
+ 2. **CLI tooling**
12
+ ```bash
13
+ pip install huggingface_hub[cli]
14
+ ```
15
+
16
+ ## 🎯 Deployment Paths
17
+
18
+ ### Option 1: Deployment script (easiest)
19
+
20
+ ```bash
21
+ # 1. Log in to Hugging Face
22
+ huggingface-cli login
23
+
24
+ # 2. Run the helper script
25
+ python deploy_to_huggingface.py
26
+ ```
27
+
28
+ ### Option 2: Gradio CLI
29
+
30
+ ```bash
31
+ huggingface-cli login
32
+ gradio deploy
33
+ ```
34
+
35
+ ### Option 3: Manual Git push
36
+
37
+ ```bash
38
+ # 1. Create a Space at https://huggingface.co/new-space (select Gradio SDK)
39
+
40
+ # 2. Clone the Space repo
41
+ git clone https://huggingface.co/spaces/<username>/<space-name>
42
+ cd <space-name>
43
+
44
+ # 3. Copy project files
45
+ cp -r /path/to/chatbot-mimic-notes/* .
46
+
47
+ # 4. Commit and push
48
+ git add .
49
+ git commit -m "Initial deployment"
50
+ git push
51
+ ```
52
+
53
+ ## 🔐 Configure Google Drive (important)
54
+
55
+ Spaces should rely on environment variables for Drive credentials.
56
+
57
+ ### Step 1: Obtain the Service Account JSON
58
+
59
+ 1. Follow `QUICK_SETUP.md`
60
+ 2. Download the JSON key file
61
+
62
+ ### Step 2: Add Hugging Face secrets
63
+
64
+ 1. Open `https://huggingface.co/spaces/<username>/<space-name>`
65
+ 2. Go to **Settings → Repository secrets**
66
+ 3. Add the required secrets:
67
+
68
+ #### Option A: Service Account (recommended)
69
+
70
+ 1. Copy the full JSON content
71
+ 2. Add a secret:
72
+ - **Name**: `GOOGLE_SERVICE_ACCOUNT_JSON`
73
+ - **Value**: entire JSON blob
74
+
75
+ #### Option B: Refresh token flow
76
+
77
+ Add these secrets if you prefer OAuth refresh tokens:
78
+ - **Name**: `GOOGLE_REFRESH_TOKEN`
79
+ - **Name**: `GOOGLE_CLIENT_ID` (optional override)
80
+ - **Name**: `GOOGLE_CLIENT_SECRET` (optional override)
81
+
82
+ ### Step 3: Environment variable support
83
+
84
+ The code already reads credentials from environment variables. If you supply the JSON via secret, no extra code changes are needed.
85
+
86
+ ## 📝 README front matter
87
+
88
+ Ensure the top of `README.md` contains:
89
+
90
+ ```yaml
91
+ ---
92
+ title: Chatbot Mimic Notes
93
+ emoji: 🤖
94
+ colorFrom: blue
95
+ colorTo: green
96
+ sdk: gradio
97
+ sdk_version: 3.50.2
98
+ app_file: chatgpt.py
99
+ pinned: false
100
+ ---
101
+ ```
102
+
103
+ ## ✅ Post-deployment checklist
104
+
105
+ 1. **Visit the Space**
106
+ `https://<username>-<space-name>.hf.space` (build takes ~2–5 minutes)
107
+
108
+ 2. **Smoke test**
109
+ - Confirm the UI loads
110
+ - Trigger a sample Google Drive sync
111
+ - Verify data persistence
112
+
113
+ 3. **Check logs**
114
+ - Open the “Logs” tab to inspect errors
115
+
116
+ ## 🔧 Troubleshooting
117
+
118
+ ### Build failed
119
+
120
+ - Confirm `requirements.txt` lists every dependency
121
+ - Review the build logs
122
+ - Ensure Python 3.10 compatibility
123
+
124
+ ### Google Drive sync fails
125
+
126
+ 1. Verify Space secrets
127
+ 2. Confirm the Service Account has Drive access
128
+ 3. Ensure the Drive API is enabled
129
+ 4. Review runtime logs
130
+
131
+ ### App won’t start
132
+
133
+ - Make sure `app_file` matches `chatgpt.py`
134
+ - Confirm `chatgpt.py` exists in the repo
135
+ - Read the log output for stack traces
136
+
137
+ ## 📦 Updating the Space
138
+
139
+ ### Via Git
140
+
141
+ ```bash
142
+ cd <space-repo>
143
+ git add .
144
+ git commit -m "Update: describe changes"
145
+ git push
146
+ ```
147
+
148
+ ### Via the web UI
149
+
150
+ 1. Open the Space and click **Files**
151
+ 2. Upload or edit files
152
+ 3. Commit the changes online
153
+
154
+ ## 🎉 What you get
155
+
156
+ - ✅ Permanent HTTPS URL
157
+ - ✅ Free hosting tier
158
+ - ✅ Automatic certificates
159
+ - ✅ Global CDN
160
+ - ✅ Version history & rollbacks
161
+
162
+ ## 💡 Tips
163
+
164
+ - **Custom domain**: configure under Space Settings
165
+ - **Resources**: upgrade if you need more CPU/RAM
166
+ - **Private Spaces**: toggle visibility in Settings
167
+ - **Monitoring**: use the built-in analytics/logs
168
+
QUICK_SETUP.md ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 Google Drive Quick Setup Guide
2
+
3
+ If you run into `invalid_client` errors, **use the Service Account approach** (simpler and more reliable).
4
+
5
+ ## ⭐ Recommended: Service Account (≈5 minutes)
6
+
7
+ ### Step 1: Create a Service Account (≈2 minutes)
8
+
9
+ 1. Visit [Google Cloud Console](https://console.cloud.google.com/)
10
+ 2. Create a new project or select an existing one
11
+ 3. Enable the Google Drive API:
12
+ - Left menu → “APIs & Services” → “Library”
13
+ - Search “Google Drive API” → click “Enable”
14
+ 4. Create the Service Account:
15
+ - Left menu → “IAM & Admin” → “Service Accounts”
16
+ - Click “Create Service Account”
17
+ - Name it `chatbot-drive-uploader`
18
+ - Click “Create and Continue” → “Done”
19
+
20
+ ### Step 2: Download the key (≈1 minute)
21
+
22
+ 1. Open the Service Account you just created
23
+ 2. Go to the “Keys” tab
24
+ 3. Click “Add Key” → “Create new key”
25
+ 4. Choose **JSON**
26
+ 5. Click “Create” (the file downloads automatically)
27
+ 6. Rename it to `service-account-key.json`
28
+ 7. Place it in the project root (next to `google_drive_sync.py`)
29
+
30
+ ### Step 3: Share the Google Drive folder (≈1 minute)
31
+
32
+ 1. Create a folder in Google Drive (e.g., “Chatbot_Data”)
33
+ 2. Right-click → “Share”
34
+ 3. Open `service-account-key.json`, find `client_email`
35
+ - Example: `chatbot-drive-uploader@your-project.iam.gserviceaccount.com`
36
+ 4. Invite that email with “Editor” permission
37
+ 5. Click “Send”
38
+
39
+ ### Step 4: Update the code (≈1 minute)
40
+
41
+ Open `google_drive_sync.py` and set:
42
+
43
+ ```python
44
+ SERVICE_ACCOUNT_FILE = "service-account-key.json"
45
+ ```
46
+
47
+ ### Done! ✅
48
+
49
+ All data will now sync to your Drive folder automatically without manual intervention.
50
+
51
+ ---
52
+
53
+ ## 🔄 Alternative: Fix the OAuth client (refresh token flow)
54
+
55
+ If you prefer refresh tokens, create a new OAuth client.
56
+
57
+ ### Step 1: Create the OAuth client
58
+
59
+ 1. Visit [Google Cloud Console](https://console.cloud.google.com/)
60
+ 2. Select your project
61
+ 3. Left menu → “APIs & Services” → “Credentials”
62
+ 4. Click “Create Credentials” → “OAuth client ID”
63
+ 5. If prompted, configure the consent screen (choose “External”)
64
+ 6. App name: `Chatbot Drive Uploader`
65
+ 7. User support email: your email
66
+ 8. Developer contact: your email
67
+ 9. Click through “Save and Continue” to finish
68
+ 10. Click “Create Credentials” → “OAuth client ID” again
69
+ 11. Choose **“Desktop app”**
70
+ 12. Name it `Chatbot Desktop Client`
71
+ 13. Click “Create”
72
+ 14. Copy the **Client ID** and **Client secret**
73
+
74
+ ### Step 2: Update the code
75
+
76
+ ```python
77
+ CLIENT_ID = "your new client id"
78
+ CLIENT_SECRET = "your new client secret"
79
+ ```
80
+
81
+ ### Step 3: Fetch a new refresh token
82
+
83
+ ```bash
84
+ python get_refresh_token.py
85
+ ```
86
+
87
+ ---
88
+
89
+ ## 📝 Notes
90
+
91
+ - The Service Account JSON is sensitive — **never commit it to Git**
92
+ - Add `service-account-key.json` to `.gitignore`
93
+ - Service Accounts are safer because no user credentials live in code
94
+
README.md CHANGED
@@ -1,10 +1,18 @@
1
  ---
2
- title: llm-autobiography
3
- app_file: chatgpt.py
 
 
4
  sdk: gradio
5
  sdk_version: 3.50.2
 
 
 
6
  ---
7
- # Chatbot Frontend
 
 
 
8
 
9
  ## Prerequisites
10
  - Python 3.x
@@ -35,3 +43,61 @@ python -m src.server
35
 
36
  ## Usage
37
  - Open Chrome and visit `http://localhost:7860` to interact with the chatbot.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Chatbot Mimic Notes
3
+ emoji: 🤖
4
+ colorFrom: blue
5
+ colorTo: green
6
  sdk: gradio
7
  sdk_version: 3.50.2
8
+ app_file: chatgpt.py
9
+ pinned: false
10
+ license: mit
11
  ---
12
+
13
+ # Chatbot Mimic Notes
14
+
15
+ A medical-focused chatbot that supports patient evaluations, structured conversation management, and optional Google Drive backups.
16
 
17
  ## Prerequisites
18
  - Python 3.x
 
43
 
44
  ## Usage
45
  - Open Chrome and visit `http://localhost:7860` to interact with the chatbot.
46
+
47
+ ## Google Drive Auto-Backup
48
+
49
+ The chatbot can automatically push evaluation data to Google Drive so the latest files are available when deploying to Hugging Face.
50
+
51
+ ### Storage Layout
52
+
53
+ 1. **Patient evaluations** (`patient_evaluations/`)
54
+ - Synced to the `Patient_Evaluations` folder in Drive
55
+ - Includes per-evaluation JSON files plus the master CSV summary
56
+
57
+ 2. **Conversation logs** (`user_data/`)
58
+ - Synced to the `Chatbot_Conversations` folder in Drive
59
+ - Includes conversation transcripts and memory graphs
60
+
61
+ ### Configuration Options (choose one)
62
+
63
+ #### ⭐ Option 1: Service Account (recommended)
64
+
65
+ Use this if you see an `invalid_client` error or want a hands-off setup.
66
+
67
+ 1. Create a Service Account in Google Cloud Console and download the JSON key
68
+ 2. Share your destination Drive folder with the Service Account email
69
+ 3. Update `google_drive_sync.py`:
70
+ ```python
71
+ SERVICE_ACCOUNT_FILE = "service-account-key.json"
72
+ ```
73
+
74
+ **Full walkthrough (≈5 minutes):** see `QUICK_SETUP.md`
75
+
76
+ #### Option 2: Refresh Token (requires an OAuth client)
77
+
78
+ 1. Generate a refresh token:
79
+ ```bash
80
+ python get_refresh_token.py
81
+ ```
82
+ 2. If you hit `invalid_client`, create a new OAuth client (see `QUICK_SETUP.md`)
83
+ 3. Complete the browser authentication flow
84
+ 4. Copy the printed `refresh_token`
85
+ 5. Update `google_drive_sync.py`:
86
+ ```python
87
+ REFRESH_TOKEN = "your_refresh_token"
88
+ ```
89
+
90
+ See `google_drive_setup_guide.md` or `QUICK_SETUP.md` for detailed steps.
91
+
92
+ #### Option 3: Interactive OAuth (manual in UI)
93
+
94
+ 1. Click **“Login to Google Drive”** inside the Gradio interface
95
+ 2. Complete the browser authentication
96
+ 3. Future saves will automatically sync to Drive
97
+
98
+ ### Notes
99
+
100
+ - Without authentication, all files remain in local storage
101
+ - Upload failures are silent but local saves always succeed
102
+ - Only your own Drive account receives files; no shared storage is involved
103
+ - **Security:** never commit credentials or tokens into the repo
chatgpt.py CHANGED
@@ -277,6 +277,18 @@ def save_patient_evaluation(patient_id, patient_input, ai_summary, rating, feedb
277
  len(sentence_comments) if sentence_comments else 0
278
  ])
279
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  return f"Patient evaluation saved successfully at {timestamp}"
281
 
282
  def submit_patient_evaluation(patient_id, patient_input, ai_summary, overall_rating,
@@ -1334,11 +1346,22 @@ with gr.Blocks(css=css) as app:
1334
  print("3. Deploy: gradio deploy")
1335
  print("4. This will give you a permanent https://yourname-appname.hf.space URL")
1336
 
1337
- # For now, launch with share link (72 hour expiry)
1338
- app.launch(
1339
- share=True,
1340
- max_threads=10,
1341
- server_name="0.0.0.0", # Allow external connections
1342
- server_port=7860,
1343
- show_error=True
1344
- )
 
 
 
 
 
 
 
 
 
 
 
 
277
  len(sentence_comments) if sentence_comments else 0
278
  ])
279
 
280
+ # Auto-upload to Google Drive if authenticated
281
+ try:
282
+ from google_drive_sync import auto_upload_to_drive
283
+ # Upload JSON file
284
+ auto_upload_to_drive(eval_file, folder_name="Patient_Evaluations")
285
+ # Upload CSV file (only if it was just created, to avoid duplicates)
286
+ if not file_exists:
287
+ auto_upload_to_drive(csv_file, folder_name="Patient_Evaluations")
288
+ except Exception as e:
289
+ # Fail silently if Google Drive upload fails
290
+ pass
291
+
292
  return f"Patient evaluation saved successfully at {timestamp}"
293
 
294
  def submit_patient_evaluation(patient_id, patient_input, ai_summary, overall_rating,
 
1346
  print("3. Deploy: gradio deploy")
1347
  print("4. This will give you a permanent https://yourname-appname.hf.space URL")
1348
 
1349
+ # Check if running on Hugging Face Spaces
1350
+ hf_space = os.getenv("SPACE_ID") is not None
1351
+
1352
+ if hf_space:
1353
+ # Running on Hugging Face Spaces
1354
+ app.launch(
1355
+ server_name="0.0.0.0",
1356
+ server_port=7860,
1357
+ show_error=True
1358
+ )
1359
+ else:
1360
+ # Running locally
1361
+ app.launch(
1362
+ share=True,
1363
+ max_threads=10,
1364
+ server_name="0.0.0.0", # Allow external connections
1365
+ server_port=7860,
1366
+ show_error=True
1367
+ )
deploy_git.sh ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Git-based deployment to Hugging Face Spaces
4
+
5
+ echo "🚀 Chatbot Mimic Notes - Git deployment to Hugging Face"
6
+ echo "======================================================="
7
+ echo ""
8
+
9
+ # Check login status
10
+ if ! huggingface-cli whoami &> /dev/null; then
11
+ echo "❌ Not logged into Hugging Face"
12
+ echo "Run: huggingface-cli login"
13
+ exit 1
14
+ fi
15
+
16
+ USERNAME=$(huggingface-cli whoami | head -n 1)
17
+ echo "✅ Logged in as: $USERNAME"
18
+ echo ""
19
+
20
+ # Prompt for Space name
21
+ read -p "Enter Space name (e.g., chatbot-mimic-notes): " SPACE_NAME
22
+
23
+ if [ -z "$SPACE_NAME" ]; then
24
+ echo "❌ Space name cannot be empty"
25
+ exit 1
26
+ fi
27
+
28
+ FULL_SPACE_NAME="${USERNAME}/${SPACE_NAME}"
29
+ SPACE_URL="https://huggingface.co/spaces/${FULL_SPACE_NAME}"
30
+
31
+ echo ""
32
+ echo "📦 Preparing deployment to: $FULL_SPACE_NAME"
33
+ echo ""
34
+
35
+ # Check if Space exists
36
+ if huggingface-cli repo exists "$FULL_SPACE_NAME" &> /dev/null; then
37
+ echo "✅ Space already exists: $SPACE_URL"
38
+ echo " Updating existing Space"
39
+ else
40
+ echo "🆕 Creating a new Space..."
41
+ huggingface-cli repo create "$SPACE_NAME" --type space --sdk gradio
42
+ if [ $? -ne 0 ]; then
43
+ echo "❌ Failed to create Space"
44
+ exit 1
45
+ fi
46
+ echo "✅ Space created successfully"
47
+ fi
48
+
49
+ echo ""
50
+ echo "📤 Preparing Git push..."
51
+ echo ""
52
+
53
+ # Create temp directory
54
+ TEMP_DIR=$(mktemp -d)
55
+ echo "Temp directory: $TEMP_DIR"
56
+
57
+ # Clone Space repo
58
+ echo "Cloning Space..."
59
+ git clone "$SPACE_URL.git" "$TEMP_DIR/space" 2>/dev/null || {
60
+ echo "Clone failed, initializing empty repo..."
61
+ mkdir -p "$TEMP_DIR/space"
62
+ cd "$TEMP_DIR/space"
63
+ git init
64
+ git remote add origin "$SPACE_URL.git"
65
+ }
66
+
67
+ cd "$TEMP_DIR/space"
68
+
69
+ # Copy project files
70
+ echo "Copying files..."
71
+ cp -r /Users/liuzijie/Desktop/chatbot-mimic-notes/chatgpt.py .
72
+ cp -r /Users/liuzijie/Desktop/chatbot-mimic-notes/README.md .
73
+ cp -r /Users/liuzijie/Desktop/chatbot-mimic-notes/requirements.txt .
74
+ cp -r /Users/liuzijie/Desktop/chatbot-mimic-notes/src ./src 2>/dev/null || true
75
+ cp -r /Users/liuzijie/Desktop/chatbot-mimic-notes/google_drive_sync.py . 2>/dev/null || true
76
+
77
+ # Remove sensitive files
78
+ rm -f service-account-key.json
79
+ rm -rf user_tokens/
80
+
81
+ # Commit & push
82
+ echo "Committing changes..."
83
+ git add .
84
+ git commit -m "Deploy chatbot application" || echo "No changes to commit"
85
+ git push origin main || git push origin master
86
+
87
+ echo ""
88
+ echo "✅ Deployment finished!"
89
+ echo "🌐 Space URL: $SPACE_URL"
90
+ echo ""
91
+ echo "💡 Notes:"
92
+ echo " - First build takes 2–5 minutes"
93
+ echo " - Configure Google Drive secrets via Space Settings > Repository secrets"
94
+ echo " - Add secret: GOOGLE_SERVICE_ACCOUNT_JSON"
95
+
96
+ # Cleanup
97
+ rm -rf "$TEMP_DIR"
98
+
deploy_hf.sh ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Quick deployment script for Hugging Face Spaces
4
+
5
+ echo "🚀 Chatbot Mimic Notes - Hugging Face deployment script"
6
+ echo "======================================================="
7
+ echo ""
8
+
9
+ # Check login status
10
+ if ! huggingface-cli whoami &> /dev/null; then
11
+ echo "❌ Not logged into Hugging Face"
12
+ echo "Run: huggingface-cli login"
13
+ exit 1
14
+ fi
15
+
16
+ echo "✅ Logged into Hugging Face"
17
+ USERNAME=$(huggingface-cli whoami | head -n 1)
18
+ echo " User: $USERNAME"
19
+ echo ""
20
+
21
+ # Prompt for Space name
22
+ read -p "Enter Space name (e.g., chatbot-mimic-notes): " SPACE_NAME
23
+
24
+ if [ -z "$SPACE_NAME" ]; then
25
+ echo "❌ Space name cannot be empty"
26
+ exit 1
27
+ fi
28
+
29
+ FULL_SPACE_NAME="${USERNAME}/${SPACE_NAME}"
30
+
31
+ echo ""
32
+ echo "📦 Preparing deployment to: $FULL_SPACE_NAME"
33
+ echo ""
34
+
35
+ # Check existing Space
36
+ if huggingface-cli repo exists "$FULL_SPACE_NAME" &> /dev/null; then
37
+ echo "⚠️ Space already exists; update in place?"
38
+ read -p "Continue? (y/n): " -n 1 -r
39
+ echo
40
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
41
+ exit 1
42
+ fi
43
+ else
44
+ echo "🆕 Creating a new Space..."
45
+ huggingface-cli repo create "$SPACE_NAME" --type space --sdk gradio
46
+ fi
47
+
48
+ echo ""
49
+ echo "📤 Starting deployment..."
50
+ echo ""
51
+
52
+ # Use gradio CLI
53
+ gradio deploy --space "$FULL_SPACE_NAME" --app-file chatgpt.py
54
+
55
+ echo ""
56
+ echo "✅ Deployment finished!"
57
+ echo "🌐 URL: https://huggingface.co/spaces/$FULL_SPACE_NAME"
58
+ echo ""
59
+ echo "💡 Tips:"
60
+ echo " - First build takes 2–5 minutes"
61
+ echo " - Configure Google Drive secrets in Space Settings"
62
+ echo " - See HUGGINGFACE_DEPLOY.md for full details"
63
+
get_refresh_token.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Helper script for retrieving a Google Drive refresh token.
4
+
5
+ Run it once, finish the OAuth flow, then copy the printed token into
6
+ REFRESH_TOKEN inside google_drive_sync.py.
7
+
8
+ If you hit an invalid_client error, consider switching to the Service
9
+ Account approach, which is more reliable.
10
+ """
11
+
12
+ from google_drive_sync import get_refresh_token
13
+
14
+ if __name__ == "__main__":
15
+ print("="*60)
16
+ print("Google Drive Refresh Token Helper")
17
+ print("="*60)
18
+ print("\n⚠️ If you see 'invalid_client', the OAuth client is misconfigured.")
19
+ print(" Use the Service Account method instead (no OAuth required).")
20
+ print(" See google_drive_setup_guide.md for the full walkthrough.\n")
21
+ print("A browser window will open so you can complete Google sign-in...\n")
22
+
23
+ refresh_token = get_refresh_token()
24
+
25
+ if refresh_token:
26
+ print("\n✅ Success! Copy the refresh_token above into google_drive_sync.py.")
27
+ else:
28
+ print("\n" + "="*60)
29
+ print("❌ Failed to get refresh_token")
30
+ print("="*60)
31
+ print("\nPossible fixes:")
32
+ print("1. Use a Service Account (recommended):")
33
+ print(" - See option B in google_drive_setup_guide.md")
34
+ print(" - Create a Service Account and download the JSON key")
35
+ print(" - Set SERVICE_ACCOUNT_FILE inside google_drive_sync.py")
36
+ print("\n2. Create a new OAuth client:")
37
+ print(" - Visit https://console.cloud.google.com/")
38
+ print(" - Create a new OAuth 2.0 client ID")
39
+ print(" - Update CLIENT_ID and CLIENT_SECRET in google_drive_sync.py")
40
+ print("="*60)
41
+
google_drive_setup_guide.md ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Google Drive Hard-Coded Auth Guide
2
+
3
+ Use this guide to enable automatic Drive uploads without running OAuth each time.
4
+
5
+ ## Option 1: Refresh Token (recommended, simple)
6
+
7
+ ### Step 1: Obtain a refresh token
8
+
9
+ 1. In a Python shell run:
10
+
11
+ ```python
12
+ from google_drive_sync import get_refresh_token
13
+ refresh_token = get_refresh_token()
14
+ ```
15
+
16
+ 2. A browser window opens for Google sign-in
17
+ 3. The terminal prints your `refresh_token`, e.g.
18
+ ```
19
+ REFRESH_TOKEN = "1//0gxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
20
+ ```
21
+
22
+ ### Step 2: Configure the refresh token
23
+
24
+ Open `google_drive_sync.py` and set:
25
+
26
+ ```python
27
+ REFRESH_TOKEN = None # place your refresh token here
28
+ ```
29
+
30
+ Replace `None` with your token:
31
+
32
+ ```python
33
+ REFRESH_TOKEN = "1//0gxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # your refresh token
34
+ ```
35
+
36
+ ### Step 3: Done
37
+
38
+ Save the file; future uploads happen automatically without another login.
39
+
40
+ ---
41
+
42
+ ## Option 2: Service Account (more secure, production-friendly)
43
+
44
+ ### Step 1: Create the Service Account
45
+
46
+ 1. Visit [Google Cloud Console](https://console.cloud.google.com/)
47
+ 2. Select or create a project
48
+ 3. Enable the Google Drive API
49
+ 4. Go to “IAM & Admin” → “Service Accounts”
50
+ 5. Click “Create Service Account”
51
+ 6. Provide a name/description, click “Create and Continue”
52
+ 7. Grant the “Editor” role, then “Continue” → “Done”
53
+
54
+ ### Step 2: Create and download the key
55
+
56
+ 1. Open the Service Account
57
+ 2. Go to the “Keys” tab
58
+ 3. Click “Add Key” → “Create new key”
59
+ 4. Choose JSON → “Create”
60
+ 5. Save the JSON into your project directory (e.g., `service-account-key.json`)
61
+
62
+ ### Step 3: Share the Drive folder with the Service Account
63
+
64
+ 1. Create a folder in Drive (e.g., “Chatbot_Data”)
65
+ 2. Right-click → “Share”
66
+ 3. In the JSON file find `client_email` (looks like `xxx@xxx.iam.gserviceaccount.com`)
67
+ 4. Add that email to the folder with “Editor” access
68
+
69
+ ### Step 4: Point the code to the Service Account file
70
+
71
+ Set this in `google_drive_sync.py`:
72
+
73
+ ```python
74
+ SERVICE_ACCOUNT_FILE = None # e.g. "path/to/service-account-key.json"
75
+ ```
76
+
77
+ Replace `None` with your JSON path:
78
+
79
+ ```python
80
+ SERVICE_ACCOUNT_FILE = "service-account-key.json" # your Service Account JSON path
81
+ ```
82
+
83
+ ### Step 5: Done
84
+
85
+ All data now syncs to the folder you shared with the Service Account!
86
+
87
+ ---
88
+
89
+ ## Verify the setup
90
+
91
+ Run the app and confirm uploads reach Drive. If not, check:
92
+
93
+ 1. Refresh token or Service Account path is correct
94
+ 2. Network connectivity
95
+ 3. Google Drive API is enabled
96
+ 4. Service Account has access to the folder
97
+
98
+ ## Notes
99
+
100
+ ⚠️ **Security reminders**
101
+ - Never commit credentials to public repos
102
+ - Add `google_drive_sync.py` or secrets to `.gitignore` if needed
103
+ - Protect the Service Account JSON carefully
104
+
105
+ ## Troubleshooting
106
+
107
+ ### Refresh token expired
108
+ Re-run `get_refresh_token()` to obtain a new one.
109
+
110
+ ### Service Account can’t access the folder
111
+ Ensure the Service Account email was invited with the proper permission.
112
+
113
+ ### Authentication failure
114
+ 1. Double-check `CLIENT_ID` / `CLIENT_SECRET`
115
+ 2. Confirm the Drive API is enabled
116
+ 3. Verify your network connection
117
+
google_drive_sync.py CHANGED
@@ -5,6 +5,7 @@ from datetime import datetime
5
 
6
  from google.auth.transport.requests import Request
7
  from google.oauth2.credentials import Credentials
 
8
  from google_auth_oauthlib.flow import InstalledAppFlow
9
  from googleapiclient.discovery import build
10
  from googleapiclient.http import MediaFileUpload
@@ -12,16 +13,33 @@ from googleapiclient.http import MediaFileUpload
12
  # Google Drive API scopes
13
  SCOPES = ['https://www.googleapis.com/auth/drive.file']
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  # Real OAuth 2.0 configuration - Public client credentials for this app
16
  # These are safe to include in public code (they're meant to be public)
17
  CLIENT_CONFIG = {
18
  "installed": {
19
- "client_id": "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com",
20
  "project_id": "patient-eval-app-439620",
21
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
22
  "token_uri": "https://oauth2.googleapis.com/token",
23
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
24
- "client_secret": "d-FL95Q19q7MQmFpd7hPD0Ty",
25
  "redirect_uris": ["http://localhost"]
26
  }
27
  }
@@ -55,10 +73,56 @@ class GoogleDriveSync:
55
  return False, f"Authentication error: {str(e)}"
56
 
57
  def authenticate(self):
58
- """Authenticate with existing token or start new flow"""
59
  creds = None
60
 
61
- # Load existing token
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  if os.path.exists(self.token_file):
63
  try:
64
  with open(self.token_file, 'rb') as token:
@@ -259,4 +323,60 @@ def check_user_authentication(user_id="default"):
259
  """Check if user is already authenticated"""
260
  sync = get_user_sync(user_id)
261
  success, message = sync.authenticate()
262
- return success, message
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  from google.auth.transport.requests import Request
7
  from google.oauth2.credentials import Credentials
8
+ from google.oauth2 import service_account
9
  from google_auth_oauthlib.flow import InstalledAppFlow
10
  from googleapiclient.discovery import build
11
  from googleapiclient.http import MediaFileUpload
 
13
  # Google Drive API scopes
14
  SCOPES = ['https://www.googleapis.com/auth/drive.file']
15
 
16
+ # ============================================================================
17
+ # Hard-coded Google Drive auth configuration
18
+ # Option 1: Service Account (recommended)
19
+ # Option 2: Refresh Token
20
+ # ============================================================================
21
+
22
+ # Option 1: Service Account JSON file (env-var friendly for Spaces)
23
+ SERVICE_ACCOUNT_FILE = os.getenv("GOOGLE_SERVICE_ACCOUNT_FILE", None) # e.g. "path/to/service-account-key.json"
24
+
25
+ # Option 2: Refresh Token (requires OAuth flow once)
26
+ REFRESH_TOKEN = os.getenv("GOOGLE_REFRESH_TOKEN", None)
27
+ CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
28
+ CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET")
29
+
30
+ # Fallback: interactive OAuth
31
+ USE_HARDCODED_AUTH = SERVICE_ACCOUNT_FILE is not None or REFRESH_TOKEN is not None
32
+
33
  # Real OAuth 2.0 configuration - Public client credentials for this app
34
  # These are safe to include in public code (they're meant to be public)
35
  CLIENT_CONFIG = {
36
  "installed": {
37
+ "client_id": CLIENT_ID,
38
  "project_id": "patient-eval-app-439620",
39
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
40
  "token_uri": "https://oauth2.googleapis.com/token",
41
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
42
+ "client_secret": CLIENT_SECRET,
43
  "redirect_uris": ["http://localhost"]
44
  }
45
  }
 
73
  return False, f"Authentication error: {str(e)}"
74
 
75
  def authenticate(self):
76
+ """Authenticate with hardcoded credentials, existing token, or start new flow"""
77
  creds = None
78
 
79
+ # Option 1: Service Account (supports env JSON for Spaces)
80
+ service_account_json = os.getenv("GOOGLE_SERVICE_ACCOUNT_JSON")
81
+ if service_account_json:
82
+ try:
83
+ import tempfile
84
+ import json as json_lib
85
+ # Persist JSON string to a temporary file
86
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
87
+ json_lib.dump(json_lib.loads(service_account_json), f)
88
+ temp_file = f.name
89
+ creds = service_account.Credentials.from_service_account_file(
90
+ temp_file, scopes=SCOPES)
91
+ self.service = build('drive', 'v3', credentials=creds)
92
+ os.unlink(temp_file) # remove temp file
93
+ return True, "Authenticated with Service Account (from env)"
94
+ except Exception as e:
95
+ return False, f"Service Account authentication error: {str(e)}"
96
+
97
+ if SERVICE_ACCOUNT_FILE and os.path.exists(SERVICE_ACCOUNT_FILE):
98
+ try:
99
+ creds = service_account.Credentials.from_service_account_file(
100
+ SERVICE_ACCOUNT_FILE, scopes=SCOPES)
101
+ self.service = build('drive', 'v3', credentials=creds)
102
+ return True, "Authenticated with Service Account"
103
+ except Exception as e:
104
+ return False, f"Service Account authentication error: {str(e)}"
105
+
106
+ # Option 2: hard-coded refresh token
107
+ if REFRESH_TOKEN:
108
+ if not CLIENT_ID or not CLIENT_SECRET:
109
+ return False, "Refresh token provided but GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET are missing."
110
+ try:
111
+ creds = Credentials(
112
+ token=None,
113
+ refresh_token=REFRESH_TOKEN,
114
+ token_uri="https://oauth2.googleapis.com/token",
115
+ client_id=CLIENT_ID,
116
+ client_secret=CLIENT_SECRET
117
+ )
118
+ # Refresh to obtain a fresh access token
119
+ creds.refresh(Request())
120
+ self.service = build('drive', 'v3', credentials=creds)
121
+ return True, "Authenticated with Refresh Token"
122
+ except Exception as e:
123
+ return False, f"Refresh Token authentication error: {str(e)}"
124
+
125
+ # Option 3: previously saved token file
126
  if os.path.exists(self.token_file):
127
  try:
128
  with open(self.token_file, 'rb') as token:
 
323
  """Check if user is already authenticated"""
324
  sync = get_user_sync(user_id)
325
  success, message = sync.authenticate()
326
+ return success, message
327
+
328
+ def get_refresh_token():
329
+ """
330
+ Helper: run once to fetch a refresh token for the hard-coded config.
331
+ Complete the OAuth flow, copy the printed token into REFRESH_TOKEN.
332
+ """
333
+ try:
334
+ flow = InstalledAppFlow.from_client_config(CLIENT_CONFIG, SCOPES)
335
+ creds = flow.run_local_server(port=0, open_browser=True)
336
+
337
+ if creds and creds.refresh_token:
338
+ print("\n" + "="*60)
339
+ print("✅ Refresh token retrieved!")
340
+ print("="*60)
341
+ print(f"\nPaste the following refresh_token into REFRESH_TOKEN:\n")
342
+ print(f"REFRESH_TOKEN = \"{creds.refresh_token}\"")
343
+ print("\n" + "="*60 + "\n")
344
+ return creds.refresh_token
345
+ else:
346
+ print("❌ Could not obtain refresh_token. Please retry.")
347
+ return None
348
+ except Exception as e:
349
+ print(f"❌ Error retrieving refresh_token: {str(e)}")
350
+ return None
351
+
352
+ def auto_upload_to_drive(file_path, user_id="default", folder_name="Chatbot_Data"):
353
+ """
354
+ Automatically upload a file to Google Drive if user is authenticated.
355
+ Returns (success, message) tuple. If not authenticated, returns (False, None) silently.
356
+ This function fails silently to not interrupt normal operation.
357
+ """
358
+ try:
359
+ sync = get_user_sync(user_id)
360
+
361
+ # Check authentication (uses hard-coded creds if configured)
362
+ success, message = sync.authenticate()
363
+ if not success:
364
+ # Log once when hard-coded auth was expected but failed
365
+ if USE_HARDCODED_AUTH:
366
+ print(f"⚠️ Google Drive authentication failed: {message}")
367
+ return False, None # Not authenticated, fail silently
368
+
369
+ # Create or get folder (use custom folder name for chatbot data)
370
+ folder_id, folder_message = sync.create_or_get_folder(folder_name)
371
+ if not folder_id:
372
+ return False, None # Fail silently if folder creation fails
373
+
374
+ # Upload file
375
+ success, result = sync.upload_file(file_path)
376
+ if success:
377
+ return True, f"✅ Auto-uploaded to Google Drive: {result.get('name', 'file')}"
378
+ else:
379
+ return False, None # Fail silently on upload error
380
+ except Exception as e:
381
+ # Fail silently if there's an error (e.g., network issue, import error)
382
+ return False, None
src/server.py CHANGED
@@ -232,6 +232,20 @@ def configure_routes(app, args):
232
  # save memory graph
233
  server.doctor.memory_graph.save(local_memory_graph_file)
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  return jsonify({"message": "Current conversation and memory graph are saved!"}), 200
236
 
237
  @app.route('/responses/doctor', methods=['POST'])
 
232
  # save memory graph
233
  server.doctor.memory_graph.save(local_memory_graph_file)
234
 
235
+ # Auto-upload to Google Drive if authenticated
236
+ try:
237
+ import sys
238
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
239
+ from google_drive_sync import auto_upload_to_drive
240
+
241
+ # Upload conversation file
242
+ auto_upload_to_drive(local_conv_file_path, user_id=username, folder_name="Chatbot_Conversations")
243
+ # Upload memory graph file
244
+ auto_upload_to_drive(local_memory_graph_file, user_id=username, folder_name="Chatbot_Conversations")
245
+ except Exception as e:
246
+ # Fail silently if Google Drive upload fails
247
+ print(f"Google Drive auto-upload failed (non-critical): {str(e)}")
248
+
249
  return jsonify({"message": "Current conversation and memory graph are saved!"}), 200
250
 
251
  @app.route('/responses/doctor', methods=['POST'])