Skip to content

Commit be24e2b

Browse files
author
“Carmel
committed
Add Ldot client classs
1 parent 5749a38 commit be24e2b

20 files changed

Lines changed: 237 additions & 270 deletions

__pycache__/app.cpython-311.pyc

2.76 KB
Binary file not shown.

app.py

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
from flask import Flask, json, render_template, request, jsonify
44
import requests
55
import yaml
6+
import json
67

8+
from new_ldot_workflows.ldot_client import LdotClient
79
from new_ldot_workflows.b_1_get_new_subjects import get_new_subjects
810
from new_ldot_workflows.b_2_get_qualtrics_links import add_individuals_to_survey
911
from new_ldot_workflows.b_2_send_links_to_ldot import send_links_to_ldot
1012
from new_ldot_workflows.b_3_get_incomplete_subjects import get_incomplete_subjects
1113
from new_ldot_workflows.b_4_get_individual_progress import get_individual_progress
14+
from new_ldot_workflows.logging_utils import QualtricsAPIError
1215

1316
app = Flask(__name__)
1417

18+
1519
CONFIG_PATH = Path(__file__).resolve().with_name("study_configs.yaml")
1620
STUDIES = yaml.safe_load(CONFIG_PATH.read_text(encoding="utf-8"))
1721

@@ -22,6 +26,21 @@ def get_study_settings(study_key: str):
2226

2327
return study, study.get("ldot_variables", {}), study.get("qualtrics_variables", {})
2428

29+
30+
with open("new_ldot_workflows/ldot_config.json") as f:
31+
config = json.load(f)
32+
LDOT_TOKEN_URL = config["LDOT_TOKEN_URL"]
33+
LDOT_API_URL = config["LDOT_API_URL"]
34+
CLIENT_ID = config["client_id"]
35+
CLIENT_SECRET = config["client_secret"]
36+
37+
ldot_client = LdotClient(
38+
token_url=LDOT_TOKEN_URL,
39+
api_url=LDOT_API_URL,
40+
client_id=CLIENT_ID,
41+
client_secret=CLIENT_SECRET
42+
)
43+
2544
@app.route("/")
2645
def index():
2746
return render_template("index.html", studies=STUDIES)
@@ -33,7 +52,6 @@ def button1():
3352

3453
data = request.json
3554
study_id = data.get("study_id")
36-
print(f"Received study_id: {study_id}")
3755

3856
study, ldot_vars, qualtrics_vars = get_study_settings(study_id)
3957
if not study:
@@ -44,11 +62,13 @@ def button1():
4462
link_completed_eaid = ldot_vars.get("eaid_qualtrics_survey_link_creation_completed")
4563

4664
try:
47-
new_subjects_ids = get_new_subjects(ldot_study_id, link_creation_eaid, link_completed_eaid)
65+
new_subjects_ids = get_new_subjects(ldot_client, ldot_study_id, link_creation_eaid, link_completed_eaid)
66+
except QualtricsAPIError as e:
67+
return jsonify({"success": False, "message": str(e)}), 502
4868
except requests.RequestException as e:
49-
return jsonify({"success": False, "message": f"Failed to fetch new subjects from LDOT: {e}"}), 502
69+
return jsonify({"success": False, "message": f"Failed to fetch new subjects from Ldot: {e}"}), 502
5070
except (KeyError, ValueError, TypeError) as e:
51-
return jsonify({"success": False, "message": f"Unexpected LDOT response while fetching new subjects: {e}"}), 502
71+
return jsonify({"success": False, "message": f"Unexpected Ldot response while fetching new subjects: {e}"}), 502
5272
except Exception as e:
5373
return jsonify({"success": False, "message": f"Unexpected error in button1: {e}"}), 500
5474

@@ -59,7 +79,7 @@ def button1():
5979

6080
@app.route("/api/button2", methods=["POST"])
6181
def button2():
62-
"""Uses subjectIDs from button 1 to add them to Qualtrics and send the links back to LDOT"""
82+
"""Uses subjectIDs from button 1 to add them to Qualtrics and send the links back to Ldot"""
6383
data = request.json
6484
study_id = data.get("study_id")
6585
new_subject_ids = data.get("new_subject_ids") or data.get("subject_ids")
@@ -101,8 +121,13 @@ def button2():
101121
"distribution_id": distribution_id
102122
}
103123

104-
subject_id_to_link_dict = add_individuals_to_survey(new_subject_ids, ldot_study_id, id_deelnemer_entity, embedded_data_field, distribution_id, qualtrics_survey_id, mailing_list_id, directory_id)
105-
send_links_to_ldot(ldot_study_id, id_deelnemer_entity, id_location, custom_var_qualtrics_link, link_completed_eaid, subject_id_to_link_dict)
124+
try:
125+
subject_id_to_link_dict = add_individuals_to_survey(ldot_client, new_subject_ids, ldot_study_id, id_deelnemer_entity, embedded_data_field, distribution_id, qualtrics_survey_id, mailing_list_id, directory_id)
126+
send_links_to_ldot(ldot_client, ldot_study_id, id_deelnemer_entity, id_location, custom_var_qualtrics_link, link_completed_eaid, subject_id_to_link_dict)
127+
except QualtricsAPIError as e:
128+
return jsonify({"success": False, "message": str(e), "debug_inputs": debug_inputs}), 502
129+
except Exception as e:
130+
return jsonify({"success": False, "message": f"Unexpected error in button2: {e}", "debug_inputs": debug_inputs}), 500
106131

107132
return jsonify({
108133
"success": True,
@@ -127,12 +152,13 @@ def button3():
127152
eaid_survey_progress_completed = ldot_vars.get("eaid_survey_progress_completed")
128153

129154
try:
130-
subjects_not_completed_survey = get_incomplete_subjects(ldot_study_id, eaid_survey_invitation_completed, eaid_survey_progress_completed)
131-
print("Subjects not completed survey:", subjects_not_completed_survey)
155+
subjects_not_completed_survey = get_incomplete_subjects(ldot_client, ldot_study_id, eaid_survey_invitation_completed, eaid_survey_progress_completed)
132156
message = f"Found {len(subjects_not_completed_survey)} subjects who have not completed the survey"
133157
return jsonify({"success": True, "message": message, "subject_ids": subjects_not_completed_survey})
158+
except QualtricsAPIError as e:
159+
return jsonify({"success": False, "message": str(e)}), 502
134160
except Exception as e:
135-
return jsonify({"success": False, "message": str(e)})
161+
return jsonify({"success": False, "message": str(e)}), 500
136162

137163

138164
@app.route("/api/button4", methods=["POST"])
@@ -153,18 +179,23 @@ def button4():
153179
qualtrics_survey_id = qualtrics_vars.get("qualtrics_survey_id")
154180
embedded_data_field = qualtrics_vars.get("embedded_data_field")
155181

156-
participant_to_progress_dict = get_individual_progress(ldot_study_id, id_deelnemer_entity, id_location, subject_ids, embedded_data_field, qualtrics_survey_id)
157-
182+
try:
183+
participant_to_progress_dict = get_individual_progress(ldot_client, ldot_study_id, id_deelnemer_entity, id_location, subject_ids, embedded_data_field, qualtrics_survey_id)
184+
except QualtricsAPIError as e:
185+
return jsonify({"success": False, "message": str(e)}), 502
186+
except Exception as e:
187+
return jsonify({"success": False, "message": f"Unexpected error in button4: {e}"}), 500
158188

159-
# return jsonify({
160-
# "success": True,
161-
# "message": f"Retrieved progress for {len(participant_to_progress_dict)} subjects",
162-
# "study_id": study_id,
163-
# "qualtrics_survey_id": qualtrics_survey_id,
164-
# "embedded_data_field": embedded_data_field,
165-
# "progress_results": participant_to_progress_dict,
166-
# })
189+
return jsonify({
190+
"success": True,
191+
"message": f"Retrieved progress for {len(participant_to_progress_dict)} subjects",
192+
"study_id": study_id,
193+
"qualtrics_survey_id": qualtrics_survey_id,
194+
"embedded_data_field": embedded_data_field,
195+
"progress_results": participant_to_progress_dict,
196+
})
167197

198+
# Here need to add the last step to send the progress back to Ldot, but that will be done in a separate function or workflow.
168199

169200
if __name__ == "__main__":
170201
app.run(debug=True)

logs/api_calls.log

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,15 @@
6464
2026-07-10 13:15:57,283 | INFO | get_incomplete_subjects | Ldot GET response | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/337ecba2-3dd3-1141-8c38-6cffdcfbd7eb | status=200 | body={"Status": "succes", "Message": "Success", "Data": {"StudyEventActions": []}}
6565
2026-07-10 13:15:57,285 | INFO | get_incomplete_subjects | Ldot GET request | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/120d298d-9aa9-084b-abc6-432148db0e10 | params=null | json=null | data=null | stream=False
6666
2026-07-10 13:15:57,722 | INFO | get_incomplete_subjects | Ldot GET response | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/120d298d-9aa9-084b-abc6-432148db0e10 | status=200 | body={"Status": "succes", "Message": "Success", "Data": {"StudyEventActions": []}}
67+
2026-07-10 14:16:07,454 | INFO | get_new_subjects | Ldot POST request | url=https://accware.memic.maastrichtuniversity.nl/ldot_identity_server/connect/token | params=null | json=null | data={"grant_type": "client_credentials", "client_id": "piama_api_qualtrics", "client_secret": "<redacted>"} | stream=False
68+
2026-07-10 14:16:07,976 | INFO | get_new_subjects | Ldot POST response | url=https://accware.memic.maastrichtuniversity.nl/ldot_identity_server/connect/token | status=200 | body={"access_token": "<redacted>", "expires_in": 3600, "token_type": "Bearer", "scope": "subject.POST"}
69+
2026-07-10 14:16:07,976 | INFO | get_new_subjects | Ldot GET request | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/5d31129c-d814-5d4b-a96f-048cadc150ce | params=null | json=null | data=null | stream=False
70+
2026-07-10 14:16:08,780 | INFO | get_new_subjects | Ldot GET response | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/5d31129c-d814-5d4b-a96f-048cadc150ce | status=200 | body={"Status": "succes", "Message": "Success", "Data": {"StudyEventActions": []}}
71+
2026-07-10 14:16:08,782 | INFO | get_new_subjects | Ldot GET request | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/31599192-8e9b-4341-b7f4-8b8967dd846a | params=null | json=null | data=null | stream=False
72+
2026-07-10 14:16:09,367 | INFO | get_new_subjects | Ldot GET response | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/31599192-8e9b-4341-b7f4-8b8967dd846a | status=200 | body={"Status": "succes", "Message": "Success", "Data": {"StudyEventActions": []}}
73+
2026-07-10 14:16:11,621 | INFO | get_incomplete_subjects | Ldot POST request | url=https://accware.memic.maastrichtuniversity.nl/ldot_identity_server/connect/token | params=null | json=null | data={"grant_type": "client_credentials", "client_id": "piama_api_qualtrics", "client_secret": "<redacted>"} | stream=False
74+
2026-07-10 14:16:11,928 | INFO | get_incomplete_subjects | Ldot POST response | url=https://accware.memic.maastrichtuniversity.nl/ldot_identity_server/connect/token | status=200 | body={"access_token": "<redacted>", "expires_in": 3600, "token_type": "Bearer", "scope": "subject.POST"}
75+
2026-07-10 14:16:11,928 | INFO | get_incomplete_subjects | Ldot GET request | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/337ecba2-3dd3-1141-8c38-6cffdcfbd7eb | params=null | json=null | data=null | stream=False
76+
2026-07-10 14:16:12,401 | INFO | get_incomplete_subjects | Ldot GET response | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/337ecba2-3dd3-1141-8c38-6cffdcfbd7eb | status=200 | body={"Status": "succes", "Message": "Success", "Data": {"StudyEventActions": []}}
77+
2026-07-10 14:16:12,401 | INFO | get_incomplete_subjects | Ldot GET request | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/120d298d-9aa9-084b-abc6-432148db0e10 | params=null | json=null | data=null | stream=False
78+
2026-07-10 14:16:12,899 | INFO | get_incomplete_subjects | Ldot GET response | url=https://accware.memic.maastrichtuniversity.nl/memic_ldot_api/api/v1.1/5c9c6a47-c8d7-8142-a8c8-ccdcb8a8044b/Action/120d298d-9aa9-084b-abc6-432148db0e10 | status=200 | body={"Status": "succes", "Message": "Success", "Data": {"StudyEventActions": []}}
-565 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3.34 KB
Binary file not shown.

0 commit comments

Comments
 (0)