Ali2206 commited on
Commit
b224fad
·
1 Parent(s): 8e3371d

Integrate TxAgent into CPS API: add TxAgent files, update requirements, fix imports and database collections

Browse files
api/routes/txagent.py CHANGED
@@ -204,6 +204,20 @@ async def get_patient_analysis_results(
204
  continue # Skip if patient no longer exists
205
 
206
  # Format the response with proper fields matching the expected format
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  formatted_analysis = {
208
  "_id": str(analysis["_id"]),
209
  "patient_id": analysis.get("patient_id"),
@@ -212,9 +226,9 @@ async def get_patient_analysis_results(
212
  "created_at": analysis.get("created_at"),
213
  "analysis_date": analysis.get("analysis_date"),
214
  "suicide_risk": {
215
- "level": _normalize_risk_level(analysis.get("risk_level", "none")),
216
- "score": analysis.get("risk_score", 0.0),
217
- "factors": analysis.get("risk_factors", [])
218
  },
219
  "summary": analysis.get("summary", ""),
220
  "recommendations": analysis.get("recommendations", [])
 
204
  continue # Skip if patient no longer exists
205
 
206
  # Format the response with proper fields matching the expected format
207
+ # Handle both old format (risk_level, risk_score) and new format (suicide_risk object)
208
+ suicide_risk_data = analysis.get("suicide_risk", {})
209
+
210
+ # Extract risk data from suicide_risk object or fallback to individual fields
211
+ if isinstance(suicide_risk_data, dict):
212
+ risk_level = suicide_risk_data.get("level", "none")
213
+ risk_score = suicide_risk_data.get("score", 0.0)
214
+ risk_factors = suicide_risk_data.get("factors", [])
215
+ else:
216
+ # Fallback to individual fields for backward compatibility
217
+ risk_level = analysis.get("risk_level", "none")
218
+ risk_score = analysis.get("risk_score", 0.0)
219
+ risk_factors = analysis.get("risk_factors", [])
220
+
221
  formatted_analysis = {
222
  "_id": str(analysis["_id"]),
223
  "patient_id": analysis.get("patient_id"),
 
226
  "created_at": analysis.get("created_at"),
227
  "analysis_date": analysis.get("analysis_date"),
228
  "suicide_risk": {
229
+ "level": _normalize_risk_level(risk_level),
230
+ "score": risk_score,
231
+ "factors": risk_factors
232
  },
233
  "summary": analysis.get("summary", ""),
234
  "recommendations": analysis.get("recommendations", [])
check_database.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Check database directly to see analysis data
4
+ """
5
+
6
+ import asyncio
7
+ import motor.motor_asyncio
8
+ import os
9
+ from datetime import datetime
10
+
11
+ async def check_database():
12
+ """Check database directly for analysis data"""
13
+
14
+ print("🔍 Checking Database Directly")
15
+ print("=" * 50)
16
+ print(f"⏰ Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
17
+ print()
18
+
19
+ try:
20
+ # Connect to MongoDB
21
+ mongo_url = os.getenv('MONGODB_URL', 'mongodb://localhost:27017')
22
+ client = motor.motor_asyncio.AsyncIOMotorClient(mongo_url)
23
+ db = client.cps_database
24
+
25
+ # Check patients collection
26
+ print("📊 Checking patients collection...")
27
+ patients_count = await db.patients.count_documents({})
28
+ print(f" ✅ Found {patients_count} patients")
29
+
30
+ if patients_count > 0:
31
+ # Show sample patients
32
+ patients = await db.patients.find({}).limit(3).to_list(length=3)
33
+ print("\n📋 Sample Patients:")
34
+ for i, patient in enumerate(patients):
35
+ print(f" Patient {i+1}: {patient.get('full_name', 'Unknown')}")
36
+ print(f" - ID: {patient.get('fhir_id', 'No ID')}")
37
+ print(f" - Email: {patient.get('email', 'No email')}")
38
+ print()
39
+
40
+ # Check analysis collection
41
+ print("📊 Checking analysis collection...")
42
+ analysis_count = await db.patient_analysis_results.count_documents({})
43
+ print(f" ✅ Found {analysis_count} analysis results")
44
+
45
+ if analysis_count > 0:
46
+ # Show sample analysis results
47
+ analyses = await db.patient_analysis_results.find({}).limit(3).to_list(length=3)
48
+ print("\n📋 Sample Analysis Results:")
49
+ for i, analysis in enumerate(analyses):
50
+ print(f" Analysis {i+1}:")
51
+ print(f" - Patient ID: {analysis.get('patient_id', 'No ID')}")
52
+ print(f" - Timestamp: {analysis.get('timestamp', 'No timestamp')}")
53
+
54
+ # Check suicide risk data
55
+ suicide_risk = analysis.get('suicide_risk', {})
56
+ if isinstance(suicide_risk, dict):
57
+ risk_level = suicide_risk.get('level', 'No level')
58
+ risk_score = suicide_risk.get('score', 0.0)
59
+ risk_factors = suicide_risk.get('factors', [])
60
+ print(f" - Risk Level: {risk_level}")
61
+ print(f" - Risk Score: {risk_score}")
62
+ print(f" - Risk Factors: {risk_factors}")
63
+ else:
64
+ print(f" - Suicide Risk: {suicide_risk}")
65
+
66
+ # Check summary
67
+ summary = analysis.get('summary', '')
68
+ if summary:
69
+ print(f" - Summary: {summary[:100]}...")
70
+ print()
71
+
72
+ # Check if there are any patients without analysis
73
+ if patients_count > 0 and analysis_count > 0:
74
+ print("🔍 Checking for patients without analysis...")
75
+ patients_with_analysis = await db.patient_analysis_results.distinct('patient_id')
76
+ patients_without_analysis = patients_count - len(patients_with_analysis)
77
+ print(f" 📊 Patients with analysis: {len(patients_with_analysis)}")
78
+ print(f" 📊 Patients without analysis: {patients_without_analysis}")
79
+
80
+ if patients_without_analysis > 0:
81
+ print(" ⚠️ Some patients need analysis!")
82
+ print(" 💡 You may need to trigger analysis for these patients")
83
+
84
+ client.close()
85
+
86
+ except Exception as e:
87
+ print(f"❌ Database error: {e}")
88
+ print("💡 Make sure MongoDB is running and accessible")
89
+
90
+ print("\n" + "="*50)
91
+ print("✅ Database check completed!")
92
+ print("\n📝 Summary:")
93
+ print(" - If you see analysis results with real scores, the data exists")
94
+ print(" - If scores are 0.0, the analysis may need to be re-run")
95
+ print(" - Your mobile app should show real scores if data exists")
96
+
97
+ if __name__ == "__main__":
98
+ asyncio.run(check_database())
test_direct_connection.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test direct connection to cps-api-tx to check analysis results
4
+ """
5
+
6
+ import asyncio
7
+ import aiohttp
8
+ import json
9
+ from datetime import datetime
10
+
11
+ async def test_direct_connection():
12
+ """Test direct connection to the space"""
13
+
14
+ space_url = "https://rocketfarmstudios-cps-api-tx.hf.space"
15
+
16
+ print("🔍 Testing Direct Connection to cps-api-tx")
17
+ print("=" * 50)
18
+ print(f"📡 Space URL: {space_url}")
19
+ print(f"⏰ Test started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
20
+ print()
21
+
22
+ try:
23
+ async with aiohttp.ClientSession() as session:
24
+ # Test 1: Root endpoint
25
+ print("🧪 Test 1: Root endpoint")
26
+ async with session.get(space_url, timeout=10) as response:
27
+ print(f" Status: {response.status}")
28
+ if response.status == 200:
29
+ root_data = await response.text()
30
+ print(f" ✅ Root endpoint: {root_data}")
31
+ else:
32
+ print(f" ❌ Root endpoint failed: {response.status}")
33
+ return
34
+
35
+ # Test 2: Analysis results endpoint (without auth)
36
+ print("\n🧪 Test 2: Analysis results endpoint")
37
+ try:
38
+ results_url = f"{space_url}/txagent/patients/analysis-results"
39
+ async with session.get(results_url, timeout=10) as response:
40
+ print(f" Status: {response.status}")
41
+ if response.status == 200:
42
+ results_data = await response.json()
43
+ print(f" ✅ Found {len(results_data)} analysis results")
44
+
45
+ if len(results_data) > 0:
46
+ print("\n📊 Analysis Results:")
47
+ for i, result in enumerate(results_data[:5]): # Show first 5 results
48
+ print(f" Result {i+1}:")
49
+ print(f" - Patient: {result.get('full_name', 'Unknown')}")
50
+ print(f" - Patient ID: {result.get('patient_id', 'No ID')}")
51
+
52
+ suicide_risk = result.get('suicide_risk', {})
53
+ risk_level = suicide_risk.get('level', 'No level')
54
+ risk_score = suicide_risk.get('score', 0.0)
55
+ risk_factors = suicide_risk.get('factors', [])
56
+
57
+ print(f" - Risk Level: {risk_level}")
58
+ print(f" - Risk Score: {risk_score}")
59
+ print(f" - Risk Factors: {risk_factors}")
60
+
61
+ # Check if we have real scores
62
+ if risk_score > 0:
63
+ print(f" ✅ Real score detected: {risk_score}")
64
+ else:
65
+ print(f" ⚠️ Score is 0 - may need to trigger analysis")
66
+ print()
67
+ else:
68
+ print(" ⚠️ No analysis results found")
69
+ elif response.status == 401:
70
+ print(" 🔐 Authentication required - this is expected")
71
+ print(" 💡 The API requires login to access analysis results")
72
+ else:
73
+ print(f" ❌ Failed: {response.status}")
74
+ error_text = await response.text()
75
+ print(f" Error details: {error_text[:200]}...")
76
+
77
+ except Exception as e:
78
+ print(f" ❌ Results error: {e}")
79
+
80
+ # Test 3: Status endpoint
81
+ print("\n🧪 Test 3: Status endpoint")
82
+ try:
83
+ status_url = f"{space_url}/txagent/status"
84
+ async with session.get(status_url, timeout=10) as response:
85
+ print(f" Status: {response.status}")
86
+ if response.status == 200:
87
+ status_data = await response.json()
88
+ print(f" ✅ Status: {json.dumps(status_data, indent=2)}")
89
+ elif response.status == 401:
90
+ print(" 🔐 Authentication required - this is expected")
91
+ else:
92
+ print(f" ❌ Status failed: {response.status}")
93
+ except Exception as e:
94
+ print(f" ❌ Status error: {e}")
95
+
96
+ except Exception as e:
97
+ print(f"❌ Connection error: {e}")
98
+
99
+ print("\n" + "="*50)
100
+ print("✅ Direct connection test completed!")
101
+ print("\n📝 Summary:")
102
+ print(" - Your Hugging Face Space is ONLINE ✅")
103
+ print(" - Authentication is required for analysis results (expected)")
104
+ print(" - Your mobile app should now be able to connect!")
105
+ print(" - Check your mobile app - it should show real scores if you're logged in")
106
+
107
+ if __name__ == "__main__":
108
+ asyncio.run(test_direct_connection())