#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import time import pymysql import requests from pathlib import Path from datetime import datetime # ================================ # šŸ”§ CONFIGURATION # ================================ TOKEN_PATH = Path("token.txt") CLINIC_SLUG = "mudr-buzalkova" BATCH_SIZE = 100 STATES = ["ACTIVE", "DONE"] # optionally add "REMOVED" DB_CONFIG = { "host": "192.168.1.76", "port": 3307, "user": "root", "password": "Vlado9674+", "database": "medevio", "charset": "utf8mb4", "cursorclass": pymysql.cursors.DictCursor, } GRAPHQL_QUERY = r""" query ClinicRequestGrid_ListPatientRequestsForClinic2( $clinicSlug: String!, $queueId: String, $queueAssignment: QueueAssignmentFilter!, $pageInfo: PageInfo!, $locale: Locale!, $state: PatientRequestState ) { requestsResponse: listPatientRequestsForClinic2( clinicSlug: $clinicSlug, queueId: $queueId, queueAssignment: $queueAssignment, pageInfo: $pageInfo, state: $state ) { count patientRequests { id displayTitle(locale: $locale) createdAt updatedAt doneAt removedAt extendedPatient { name surname identificationNumber } } } } """ # ================================ # šŸ”‘ TOKEN # ================================ def read_token(p: Path) -> str: tok = p.read_text(encoding="utf-8").strip() if tok.startswith("Bearer "): tok = tok.split(" ", 1)[1] return tok # ================================ # šŸ•’ DATETIME CONVERSION # ================================ def to_mysql_dt(iso_str): """Convert ISO 8601 (with Z) to MySQL DATETIME.""" if not iso_str: return None try: dt = datetime.fromisoformat(iso_str.replace("Z", "+00:00")) return dt.strftime("%Y-%m-%d %H:%M:%S") except Exception: return None # ================================ # šŸ’¾ UPSERT TO MYSQL # ================================ def upsert_many(conn, batch): """Upsert multiple records in one commit.""" if not batch: return sql = """ INSERT INTO pozadavky ( id, displayTitle, createdAt, updatedAt, doneAt, removedAt, pacient_jmeno, pacient_prijmeni, pacient_rodnecislo ) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s) ON DUPLICATE KEY UPDATE displayTitle=VALUES(displayTitle), updatedAt=VALUES(updatedAt), doneAt=VALUES(doneAt), removedAt=VALUES(removedAt), pacient_jmeno=VALUES(pacient_jmeno), pacient_prijmeni=VALUES(pacient_prijmeni), pacient_rodnecislo=VALUES(pacient_rodnecislo) """ vals = [] for r in batch: p = (r.get("extendedPatient") or {}) vals.append(( r.get("id"), r.get("displayTitle"), to_mysql_dt(r.get("createdAt")), to_mysql_dt(r.get("updatedAt")), to_mysql_dt(r.get("doneAt")), to_mysql_dt(r.get("removedAt")), p.get("name"), p.get("surname"), p.get("identificationNumber"), )) with conn.cursor() as cur: cur.executemany(sql, vals) conn.commit() def upsert(conn, r): p = (r.get("extendedPatient") or {}) sql = """ INSERT INTO pozadavky ( id, displayTitle, createdAt, updatedAt, doneAt, removedAt, pacient_jmeno, pacient_prijmeni, pacient_rodnecislo ) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s) ON DUPLICATE KEY UPDATE displayTitle=VALUES(displayTitle), updatedAt=VALUES(updatedAt), doneAt=VALUES(doneAt), removedAt=VALUES(removedAt), pacient_jmeno=VALUES(pacient_jmeno), pacient_prijmeni=VALUES(pacient_prijmeni), pacient_rodnecislo=VALUES(pacient_rodnecislo) """ vals = ( r.get("id"), r.get("displayTitle"), to_mysql_dt(r.get("createdAt")), to_mysql_dt(r.get("updatedAt")), to_mysql_dt(r.get("doneAt")), to_mysql_dt(r.get("removedAt")), p.get("name"), p.get("surname"), p.get("identificationNumber"), ) with conn.cursor() as cur: cur.execute(sql, vals) conn.commit() # ================================ # šŸ“” FETCH ONE BATCH # ================================ def fetch_batch(headers, state, offset): variables = { "clinicSlug": CLINIC_SLUG, "queueId": None, "queueAssignment": "ANY", "pageInfo": {"first": BATCH_SIZE, "offset": offset}, "locale": "cs", "state": state, } payload = { "operationName": "ClinicRequestGrid_ListPatientRequestsForClinic2", "query": GRAPHQL_QUERY, "variables": variables, } r = requests.post("https://api.medevio.cz/graphql", json=payload, headers=headers) r.raise_for_status() data = r.json().get("data", {}).get("requestsResponse", {}) return data.get("patientRequests", []), data.get("count", 0) # ================================ # 🧠 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) total_downloaded = 0 total_upserted = 0 for state in STATES: print(f"\nšŸ“” STATE = {state}") offset = 0 state_total = None while True: batch, count_total = fetch_batch(headers, state, offset) if state_total is None: state_total = count_total print(f" • Total from server: {state_total}") if not batch: break print(f" • Offset {offset:>5}: got {len(batch)}") for r in batch: # upsert(conn, r) upsert_many(conn, batch) total_upserted += 1 total_downloaded += len(batch) offset += BATCH_SIZE if offset >= state_total: break time.sleep(0.4) # respect API conn.close() print(f"\nāœ… Done. Downloaded {total_downloaded} items, upserted {total_upserted} rows (states: {', '.join(STATES)}).") if __name__ == "__main__": main()