This commit is contained in:
2025-11-14 07:18:30 +01:00
parent c72d1f15a1
commit 505076bbf8
4 changed files with 931 additions and 0 deletions

112
Testy/05 Testy.py Normal file
View File

@@ -0,0 +1,112 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import requests
from pathlib import Path
TOKEN_PATH = Path("token.txt")
CLINIC_SLUG = "mudr-buzalkova"
GRAPHQL_URL = "https://api.medevio.cz/graphql" # ← správná URL
# 👉 nastav offset zde
OFFSET = 0 # 0 = první pacient, 1 = druhý, 100 = 101. pacient
FIRST = 1 # načteme jen jednoho
QUERY = """
query PatientGridImpl_ListClinicPatients(
$clinicSlug: String!,
$filter: ListPatientFilter!,
$pageInfo: PageInfo!,
$sort: [ListPatientsSort!]
) {
patientsList: listPatients(
clinicSlug: $clinicSlug
filter: $filter
pageInfo: $pageInfo
sort: $sort
) {
count
patients {
id
identificationNumber
insuranceCompanyObject {
id
shortName
}
lastReservation
locale
name
nextReservation
key
phone
sex
status2
surname
type
kind
isInClinic
isUnknownPatient
user {
id
name
surname
phone
registrationCompletedTime
}
owner {
name
surname
}
clinics {
id
name
slug
}
tags(onlyImportant: false) {
id
name
color
icon
}
}
}
}
"""
variables = {
"clinicSlug": CLINIC_SLUG,
"filter": {},
"pageInfo": {
"first": FIRST,
"offset": OFFSET
},
"sort": [
{
"field": "ReverseFullName",
"sort": "ASC"
}
]
}
token = Path("token.txt").read_text().strip()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
print("⏳ Fetching patient...")
response = requests.post(
GRAPHQL_URL,
json={"query": QUERY, "variables": variables},
headers=headers
)
response.raise_for_status()
data = response.json()
print("\n📌 RAW JSON RESPONSE:\n")
print(json.dumps(data, indent=2, ensure_ascii=False))

203
Testy/06 Testy.py Normal file
View File

@@ -0,0 +1,203 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import requests
import pymysql
from pathlib import Path
# ==============================
# 🔧 KONFIGURACE
# ==============================
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,
}
# počet pacientů na stránku
PAGE_SIZE = 100
# ==============================
# 📌 GRAPHQL QUERY
# ==============================
QUERY = """
query PatientGridImpl_ListClinicPatients(
$clinicSlug: String!,
$filter: ListPatientFilter!,
$pageInfo: PageInfo!,
$sort: [ListPatientsSort!]
) {
patientsList: listPatients(
clinicSlug: $clinicSlug
filter: $filter
pageInfo: $pageInfo
sort: $sort
) {
count
patients {
id
identificationNumber
insuranceCompanyObject {
id
shortName
}
name
surname
phone
sex
status2
type
kind
isInClinic
isUnknownPatient
user {
registrationCompletedTime
}
clinics {
id
name
slug
}
tags(onlyImportant: false) {
id
name
color
icon
}
}
}
}
"""
from datetime import datetime
def normalize_dt(dt_str):
if not dt_str:
return None
# remove Z
dt_str = dt_str.replace("Z", "")
# replace T with space
dt_str = dt_str.replace("T", " ")
# remove fractional seconds
if "." in dt_str:
dt_str = dt_str.split(".")[0]
return dt_str # MySQL can accept "YYYY-MM-DD HH:MM:SS"
# ==============================
# 💾 ULOŽENÍ PACIENTA
# ==============================
def save_patient_summary(cur, p):
sql = """
REPLACE INTO medevio_pacienti (
id, jmeno, prijmeni, rodne_cislo, telefon, pohlavi,
pojistovna_id, pojistovna_nazev,
status, typ, kind,
is_in_clinic, is_unknown,
registration_time,
tags_json, clinics_json,
last_update
)
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,NOW())
"""
ins = p.get("insuranceCompanyObject") or {}
user = p.get("user") or {}
cur.execute(sql, (
p.get("id"),
p.get("name"),
p.get("surname"),
p.get("identificationNumber"),
p.get("phone"),
p.get("sex"),
ins.get("id"),
ins.get("shortName"),
p.get("status2"),
p.get("type"),
p.get("kind"),
1 if p.get("isInClinic") else 0,
1 if p.get("isUnknownPatient") else 0,
normalize_dt(user.get("registrationCompletedTime")),
json.dumps(p.get("tags"), ensure_ascii=False),
json.dumps(p.get("clinics"), ensure_ascii=False),
))
# ==============================
# 🧠 MAIN
# ==============================
def main():
token = TOKEN_PATH.read_text().strip()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
conn = pymysql.connect(**DB_CONFIG)
cur = conn.cursor()
offset = 0
total = None
print("⏳ Starting patient sync...\n")
while True:
print(f"➡️ Fetching patients {offset}{offset + PAGE_SIZE} ...")
variables = {
"clinicSlug": CLINIC_SLUG,
"filter": {},
"pageInfo": {"first": PAGE_SIZE, "offset": offset},
"sort": [{"field": "ReverseFullName", "sort": "ASC"}],
}
response = requests.post(
GRAPHQL_URL,
json={"query": QUERY, "variables": variables},
headers=headers,
timeout=30
)
response.raise_for_status()
data = response.json()
block = data["data"]["patientsList"]
if total is None:
total = block["count"]
print(f"📌 Total patients: {total}\n")
patients = block["patients"]
if not patients:
print("✅ No more patients. Finished.")
break
# save each patient
for p in patients:
save_patient_summary(cur, p)
conn.commit()
print(f" ✓ Saved {len(patients)} patients.")
offset += PAGE_SIZE
if offset >= total:
print("\n✅ All patients downloaded.")
break
cur.close()
conn.close()
# ==============================
if __name__ == "__main__":
main()

251
Testy/07 Testy.py Normal file
View File

@@ -0,0 +1,251 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import requests
from pathlib import Path
TOKEN_PATH = Path("token.txt")
GRAPHQL_URL = "https://api.medevio.cz/graphql"
CLINIC_SLUG = "mudr-buzalkova"
PATIENT_ID = "5a0a9ff0-bbe8-4fc7-a27d-b7b475ee2189"
QUERY = """
query ClinicPatientDetailModal_GetData(
$clinicSlug: String!,
$patientId: String!,
$patientUuid: UUID!,
$challengesStatus: ECRFChallengeStatus!,
$locale: Locale!
) {
clinic: getClinic(clinicSlug: $clinicSlug) {
id
features
sslSUKLCertificateId
type
ais
slug
...ClinicWithTypeAndFeatures_Clinic
...PatientInfo_Clinic
__typename
}
patient: getPatientForClinic(clinicSlug: $clinicSlug, patientId: $patientId) {
...ClinicPatientDetailModal_Patient
__typename
}
challenges: listPatientChallenges2(
clinicSlug: $clinicSlug
patientId: $patientId
status: $challengesStatus
) {
...ChallengeTableList_EcrfChallenge
__typename
}
patientRequestsResponse: filterPatientRequestsForClinic(
clinicSlug: $clinicSlug
filter: {patientId: $patientUuid}
pageInfo: {first: 1, offset: 0}
) {
count
items { id __typename }
__typename
}
treatmentPlanPatients: listTreatmentPlanPatients(
clinicSlug: $clinicSlug
patientId: $patientUuid
) {
...ClinicPlanPatientList_PlanPatient
__typename
}
premiumPlans: listClinicPremiumPlans(clinicSlug: $clinicSlug) {
id
__typename
}
mergeSuggestions: findMergeSuggestions(
clinicSlug: $clinicSlug
input: {existingPatientId: $patientUuid}
) {
...MergeSuggestionAlert_MergeSuggestionResult
__typename
}
insuranceCards: getPatientDocuments(
patientId: $patientUuid
type: InsuranceCard
) {
...PatientInfo_InsuranceCard
__typename
}
}
fragment ClinicWithTypeAndFeatures_Clinic on Clinic {
id
type
features
__typename
}
fragment PatientInfo_Clinic on Clinic {
country
id
slug
ais
...ClinicWithTypeAndFeatures_Clinic
__typename
}
fragment ClinicPatientDetailModal_Patient on ExtendedPatient {
id
isInClinic
kind
name
isUnknownPatient
sex
surname
identificationNumber
editableByDoctor
type
key
user { id name surname __typename }
...ClinicPatientDetail_Patient
...PatientInfo_AccountPatient
...ClinicPatientInfo_Patient
__typename
}
fragment ClinicPatientDetail_Patient on ExtendedPatient {
name
surname
email
id
identificationNumber
isInClinic
key
phone
sex
type
dob
user { id __typename }
isUnknownPatient
hasMobileApp
__typename
}
fragment PatientInfo_AccountPatient on ExtendedPatient {
id
createdAt
key
user {
registrationCompletedTime
deactivatedTime
__typename
}
__typename
}
fragment ClinicPatientInfo_Patient on ExtendedPatient {
anamnesisShared
anamnesisStatusForClinic { updatedAt __typename }
clinics { id name slug __typename }
id
isInClinic
dob
city
familyMembers: family { __typename }
houseNumber
identificationNumber
insuranceCompanyObject { id code name shortName __typename }
kind
name
note
owner { name surname __typename }
key
status
street
surname
user { id email name phone surname __typename }
userRelationship
premiumPlanPatient { id __typename }
sex
tags(onlyImportant: false) { id name color icon __typename }
type
isUnknownPatient
hasMobileApp
__typename
}
fragment ChallengeTableList_EcrfChallenge on ECRFChallenge {
id
createdAt
sentAt
issuedToPatient {
id
identificationNumber
name
surname
__typename
}
userECRF(locale: $locale) { id name __typename }
patientRequestId
status
__typename
}
fragment MergeSuggestionAlert_MergeSuggestionResult on MergeSuggestionResult {
extendedPatient { id __typename }
matchResult
__typename
}
fragment ClinicPlanPatientList_PlanPatient on TreatmentPlanPatient {
id
createdAt
listPatient { id identificationNumber name key status surname __typename }
treatmentPlan { id slug name __typename }
__typename
}
fragment PatientInfo_InsuranceCard on PatientDocument {
id
contentType
url
downloadUrl
__typename
}
"""
def main():
token = TOKEN_PATH.read_text().strip()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
variables = {
"clinicSlug": CLINIC_SLUG,
"patientId": PATIENT_ID,
"patientUuid": PATIENT_ID,
"challengesStatus": "SENT",
"locale": "cs",
}
print("⏳ Fetching patient detail…")
r = requests.post(
GRAPHQL_URL,
json={"query": QUERY, "variables": variables},
headers=headers,
timeout=30
)
r.raise_for_status()
data = r.json()
print("\n📌 RAW DETAIL JSON:\n")
print(json.dumps(data, indent=2, ensure_ascii=False))
if __name__ == "__main__":
main()

365
Testy/08 Testy.py Normal file
View File

@@ -0,0 +1,365 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import requests
import pymysql
from pathlib import Path
# ==============================
# CONFIG
# ==============================
TOKEN_PATH = Path("token.txt")
GRAPHQL_URL = "https://api.medevio.cz/graphql"
CLINIC_SLUG = "mudr-buzalkova"
DB_CONFIG = {
"host": "192.168.1.76",
"port": 3307,
"user": "root",
"password": "Vlado9674+",
"database": "medevio",
"charset": "utf8mb4",
"cursorclass": pymysql.cursors.DictCursor,
}
PATIENT_ID = "5a0a9ff0-bbe8-4fc7-a27d-b7b475ee2189"
# ==============================
# HELPERS
# ==============================
def normalize_dt(dt_str):
if not dt_str:
return None
dt_str = dt_str.replace("Z", "").replace("T", " ")
if "." in dt_str:
dt_str = dt_str.split(".")[0]
return dt_str
def save_patient_detail(cur, p):
user = p.get("user") or {}
ins = p.get("insuranceCompanyObject") or {}
tags = p.get("tags") or []
clinics = p.get("clinics") or []
sql = """
UPDATE medevio_pacienti SET
email = %s,
telefon = %s,
dob = %s,
street = %s,
house_number = %s,
city = %s,
user_id = %s,
user_email = %s,
user_name = %s,
user_surname = %s,
user_phone = %s,
user_reg_time = %s,
user_deactivated_time = %s,
created_at = %s,
note = %s,
has_mobile_app = %s,
user_relationship = %s,
pojistovna_code = %s,
tags_json = %s,
clinics_json = %s,
last_update = NOW()
WHERE id = %s
"""
cur.execute(sql, (
p.get("email"),
p.get("phone"),
p.get("dob"),
p.get("street"),
p.get("houseNumber"),
p.get("city"),
user.get("id"),
user.get("email"),
user.get("name"),
user.get("surname"),
user.get("phone"),
normalize_dt(user.get("registrationCompletedTime")),
normalize_dt(user.get("deactivatedTime")),
normalize_dt(p.get("createdAt")),
p.get("note"),
1 if p.get("hasMobileApp") else 0,
p.get("userRelationship"),
ins.get("code"),
json.dumps(tags, ensure_ascii=False),
json.dumps(clinics, ensure_ascii=False),
p.get("id")
))
# ==============================
# FULL EXACT WORKING GRAPHQL QUERY
# ==============================
QUERY = """
query ClinicPatientDetailModal_GetData(
$clinicSlug: String!,
$patientId: String!,
$patientUuid: UUID!,
$challengesStatus: ECRFChallengeStatus!,
$locale: Locale!
) {
clinic: getClinic(clinicSlug: $clinicSlug) {
id
features
sslSUKLCertificateId
type
ais
slug
...ClinicWithTypeAndFeatures_Clinic
...PatientInfo_Clinic
__typename
}
patient: getPatientForClinic(clinicSlug: $clinicSlug, patientId: $patientId) {
...ClinicPatientDetailModal_Patient
__typename
}
challenges: listPatientChallenges2(
clinicSlug: $clinicSlug
patientId: $patientId
status: $challengesStatus
) {
...ChallengeTableList_EcrfChallenge
__typename
}
patientRequestsResponse: filterPatientRequestsForClinic(
clinicSlug: $clinicSlug
filter: {patientId: $patientUuid}
pageInfo: {first: 1, offset: 0}
) {
count
items { id __typename }
__typename
}
treatmentPlanPatients: listTreatmentPlanPatients(
clinicSlug: $clinicSlug
patientId: $patientUuid
) {
...ClinicPlanPatientList_PlanPatient
__typename
}
premiumPlans: listClinicPremiumPlans(clinicSlug: $clinicSlug) {
id
__typename
}
mergeSuggestions: findMergeSuggestions(
clinicSlug: $clinicSlug
input: {existingPatientId: $patientUuid}
) {
...MergeSuggestionAlert_MergeSuggestionResult
__typename
}
insuranceCards: getPatientDocuments(
patientId: $patientUuid
type: InsuranceCard
) {
...PatientInfo_InsuranceCard
__typename
}
}
fragment ClinicWithTypeAndFeatures_Clinic on Clinic {
id
type
features
__typename
}
fragment PatientInfo_Clinic on Clinic {
country
id
slug
ais
...ClinicWithTypeAndFeatures_Clinic
__typename
}
fragment ClinicPatientDetailModal_Patient on ExtendedPatient {
id
isInClinic
kind
name
isUnknownPatient
sex
surname
identificationNumber
editableByDoctor
type
key
user { id name surname __typename }
...ClinicPatientDetail_Patient
...PatientInfo_AccountPatient
...ClinicPatientInfo_Patient
__typename
}
fragment ClinicPatientDetail_Patient on ExtendedPatient {
name
surname
email
id
identificationNumber
isInClinic
key
phone
sex
type
dob
user { id __typename }
isUnknownPatient
hasMobileApp
__typename
}
fragment PatientInfo_AccountPatient on ExtendedPatient {
id
createdAt
key
user {
registrationCompletedTime
deactivatedTime
__typename
}
__typename
}
fragment ClinicPatientInfo_Patient on ExtendedPatient {
anamnesisShared
anamnesisStatusForClinic { updatedAt __typename }
clinics { id name slug __typename }
id
isInClinic
dob
city
familyMembers: family { __typename }
houseNumber
identificationNumber
insuranceCompanyObject { id code name shortName __typename }
kind
name
note
owner { name surname __typename }
key
status
street
surname
user { id email name phone surname __typename }
userRelationship
premiumPlanPatient { id __typename }
sex
tags(onlyImportant: false) { id name color icon __typename }
type
isUnknownPatient
hasMobileApp
__typename
}
fragment ChallengeTableList_EcrfChallenge on ECRFChallenge {
id
createdAt
sentAt
issuedToPatient {
id
identificationNumber
name
surname
__typename
}
userECRF(locale: $locale) { id name __typename }
patientRequestId
status
__typename
}
fragment MergeSuggestionAlert_MergeSuggestionResult on MergeSuggestionResult {
extendedPatient { id __typename }
matchResult
__typename
}
fragment ClinicPlanPatientList_PlanPatient on TreatmentPlanPatient {
id
createdAt
listPatient { id identificationNumber name key status surname __typename }
treatmentPlan { id slug name __typename }
__typename
}
fragment PatientInfo_InsuranceCard on PatientDocument {
id
contentType
url
downloadUrl
__typename
}
"""
# ==============================
# MAIN
# ==============================
def main():
token = TOKEN_PATH.read_text().strip()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
variables = {
"clinicSlug": CLINIC_SLUG,
"patientId": PATIENT_ID,
"patientUuid": PATIENT_ID,
"challengesStatus": "SENT",
"locale": "cs",
}
print(f"⏳ Fetching patient detail {PATIENT_ID}")
r = requests.post(
GRAPHQL_URL,
json={"query": QUERY, "variables": variables},
headers=headers,
timeout=30
)
r.raise_for_status()
data = r.json()
patient = data["data"]["patient"]
if not patient:
print("❌ Patient not found in API response!")
return
print("📥 Patient detail downloaded.")
conn = pymysql.connect(**DB_CONFIG)
cur = conn.cursor()
save_patient_detail(cur, patient)
conn.commit()
print("✅ Patient detail saved to DB.")
cur.close()
conn.close()
if __name__ == "__main__":
main()