From 3904948c329d60d506eb7ea494094c003a88a6ad Mon Sep 17 00:00:00 2001 From: Abdelkouddous LHACHIMI Date: Thu, 12 Mar 2026 16:16:22 +0000 Subject: [PATCH] Optional 6 month visit completeness --- eb_dashboard.py | 26 +++++++++++++++++++++++--- eb_org_center_mapping.xlsx | Bin 18768 -> 18804 bytes 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/eb_dashboard.py b/eb_dashboard.py index 2e5bd7d..525911c 100644 --- a/eb_dashboard.py +++ b/eb_dashboard.py @@ -119,6 +119,7 @@ refresh_token = "" threads_list = [] _token_refresh_lock = threading.Lock() on_retry_exhausted = "ask" # "ask" | "ignore" | "abort" — set at startup +fetch_six_month_visit = False # Whether to fetch 6-month visit data (slow, ~5s per patient) _stored_username = "" # Credentials stored at login for automatic re-login _stored_password = "" _threads_list_lock = threading.Lock() @@ -354,6 +355,19 @@ def ask_on_retry_exhausted(): on_retry_exhausted = "abort" +def ask_fetch_six_month_visit(): + """Asks the user whether to fetch 6-month visit data (slow API call, ~5s per patient).""" + global fetch_six_month_visit + choice = questionary.select( + "Fetch 6-month visit progress data? (slow, ~5s per patient) :", + choices=[ + "No (skip, faster execution)", + "Yes (fetch 6-month visit data)" + ] + ).ask() + fetch_six_month_visit = (choice == "Yes (fetch 6-month visit data)") + + def wait_for_scheduled_launch(): """Asks the user when to start the processing and waits if needed. Options: Immediately / In X minutes / At HH:MM @@ -1238,9 +1252,12 @@ def _process_inclusion_data(inclusion, organization): output_inclusion = {} # --- Prepare all data sources --- - # 1. Launch Visit Search asynchronously (it's slow, ~5s) + # 1. Launch Visit Search asynchronously (it's slow, ~5s) — only if enabled by user # We use run_with_context to pass the patient identity to the new thread - visit_future = subtasks_thread_pool.submit(run_with_context, search_visit_by_pseudo_and_order, ctx, pseudo, 2) + if fetch_six_month_visit: + visit_future = subtasks_thread_pool.submit(run_with_context, search_visit_by_pseudo_and_order, ctx, pseudo, 2) + else: + visit_future = None # 2. Prepare inclusion_data: enrich inclusion with organization info inclusion_data = dict(inclusion) @@ -1265,7 +1282,7 @@ def _process_inclusion_data(inclusion, organization): request_data = None try: - six_month_visit_data = visit_future.result() + six_month_visit_data = visit_future.result() if visit_future is not None else {} except Exception as e: logging.error(f"Error searching 6-month visit for patient {pseudo}: {e}") six_month_visit_data = None @@ -1335,6 +1352,9 @@ def main(): if login_status == "Exit": return + print() + ask_fetch_six_month_visit() + print() number_of_threads = int((questionary.text("Number of threads :", default="12", validate=lambda x: x.isdigit() and 0 < int(x) <= MAX_THREADS).ask())) diff --git a/eb_org_center_mapping.xlsx b/eb_org_center_mapping.xlsx index 3e9213bfc4be9b4b7e82e4d1a50efbb379c7e3be..83b00327e9eb445bb6ab027dbae360eaf2f7200c 100644 GIT binary patch delta 8341 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 delta 8307 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