#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Download and store Medevio questionnaires (userNote + eCRF) for all patient requests. Uses the verified working query "GetPatientRequest2". """ import json import requests import pymysql from datetime import datetime from pathlib import Path import time # ============================== # šŸ”§ CONFIGURATION # ============================== TOKEN_PATH = Path("token.txt") CLINIC_SLUG = "mudr-buzalkova" GRAPHQL_URL = "https://api.medevio.cz/graphql" DB_CONFIG = { "host": "192.168.1.76", "port": 3307, "user": "root", "password": "Vlado9674+", "database": "medevio", "charset": "utf8mb4", "cursorclass": pymysql.cursors.DictCursor, } from datetime import datetime def fix_datetime(dt_str): """Convert ISO 8601 string with 'Z' or ms into MySQL DATETIME format.""" if not dt_str: return None try: # Remove trailing Z and parse flexible ISO format return datetime.fromisoformat(dt_str.replace("Z", "").replace("+00:00", "")) except Exception: return None # āœ… Optional: limit which requests to process CREATED_AFTER = "2025-11-09" # set "" to disable # ============================== # 🧮 HELPERS # ============================== def read_token(p: Path) -> str: """Read Bearer token from file.""" tok = p.read_text(encoding="utf-8").strip() if tok.startswith("Bearer "): tok = tok.split(" ", 1)[1] return tok GRAPHQL_QUERY = r""" query GetPatientRequest2($requestId: UUID!, $clinicSlug: String!, $locale: Locale!) { request: getPatientRequest2(patientRequestId: $requestId, clinicSlug: $clinicSlug) { id displayTitle(locale: $locale) createdAt updatedAt userNote eventType extendedPatient(clinicSlug: $clinicSlug) { name surname identificationNumber } ecrfFilledData(locale: $locale) { name groups { label fields { name label type value } } } } } """ def fetch_questionnaire(headers, request_id, clinic_slug): """Fetch questionnaire for given request ID.""" payload = { "operationName": "GetPatientRequest2", "query": GRAPHQL_QUERY, "variables": { "requestId": request_id, "clinicSlug": clinic_slug, "locale": "cs", }, } r = requests.post(GRAPHQL_URL, json=payload, headers=headers, timeout=40) if r.status_code != 200: print(f"āŒ HTTP {r.status_code} for {request_id}: {r.text}") return None return r.json().get("data", {}).get("request") def insert_questionnaire(cur, req): """Insert questionnaire data into MySQL.""" if not req: return patient = req.get("extendedPatient") or {} ecrf_data = req.get("ecrfFilledData") created_at = fix_datetime(req.get("createdAt")) updated_at = fix_datetime(req.get("updatedAt")) cur.execute(""" INSERT INTO medevio_questionnaires ( request_id, patient_name, patient_surname, patient_identification, created_at, updated_at, user_note, ecrf_json ) VALUES (%s,%s,%s,%s,%s,%s,%s,%s) ON DUPLICATE KEY UPDATE updated_at = VALUES(updated_at), user_note = VALUES(user_note), ecrf_json = VALUES(ecrf_json), updated_local = NOW() """, ( req.get("id"), patient.get("name"), patient.get("surname"), patient.get("identificationNumber"), created_at, updated_at, req.get("userNote"), json.dumps(ecrf_data, ensure_ascii=False), )) print(f" šŸ’¾ Stored questionnaire for {patient.get('surname','')} {patient.get('name','')}") # ============================== # 🧠 MAIN # ============================== def main(): token = read_token(TOKEN_PATH) headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json", "Accept": "application/json", } conn = pymysql.connect(**DB_CONFIG) with conn.cursor() as cur: sql = """ SELECT id, pacient_jmeno, pacient_prijmeni, createdAt, updatedAt, questionnaireprocessed FROM pozadavky WHERE (questionnaireprocessed IS NULL OR questionnaireprocessed < updatedAt) """ if CREATED_AFTER: sql += " AND createdAt >= %s" cur.execute(sql, (CREATED_AFTER,)) else: cur.execute(sql) rows = cur.fetchall() print(f"šŸ“‹ Found {len(rows)} requests needing questionnaire check.") for i, row in enumerate(rows, 1): req_id = row["id"] print(f"\n[{i}/{len(rows)}] šŸ” Fetching questionnaire for {req_id} ...") req = fetch_questionnaire(headers, req_id, CLINIC_SLUG) if not req: print(" āš ļø No questionnaire data found.") continue with conn.cursor() as cur: insert_questionnaire(cur, req) cur.execute("UPDATE pozadavky SET questionnaireprocessed = NOW() WHERE id = %s", (req_id,)) conn.commit() time.sleep(0.4) # polite pacing conn.close() print("\nāœ… Done! All questionnaires stored in MySQL table `medevio_questionnaires`.") # ============================== if __name__ == "__main__": main()