Files
janssen/Covance_UCO3001/Trash/download_test_results_v1.1.md
T
2026-05-29 13:37:54 +02:00

9.1 KiB
Raw Blame History

download_test_results_v1.1.py — dokumentace

Verze: 1.1 · Datum: 2026-05-29 Umístění: U:\PythonProject\Janssen\Covance_UCO3001\download_test_results_v1.1.py

Změny v1.1 oproti 1.0: přidána druhá studie 35472 (MDD) a druhý typ reportu Microbiology. Dříve jen 36940 + Standard.


1. Účel

Automatické stažení reportů Test Results z portálu Labcorp Sponsor Portal (xsp.labcorp.com). Skript projde 2 studie × jejich centra × 2 typy reportu, u každého vyexportuje grid do CSV a uloží ho timestampovaný do Source/.

Studie Interní ID Význam Počet center
UC 36940 77242113UCO3001 12
MDD 35472 druhá studie 5

Typy reportu (záložka v URL): Standard (/standard-test-results) a Microbiology (/microbiology).

Celkem: (12 + 5) × 2 = 34 reportů (prázdná centra se přeskakují, viz 6.5).


2. Spuštění

U:\PythonProject\Janssen\.venv\Scripts\python.exe ^
  U:\PythonProject\Janssen\Covance_UCO3001\download_test_results_v1.1.py
  • Prohlížeč běží viditelně (headless=False), maximalizovaný.
  • Persistent profile (browser_profile/ vedle skriptu) — session přežívá.

Dočasný test (1 centrum / studie)

Pro rychlé ověření stačí dočasně zúžit STUDIES, např.:

STUDIES = [
    {"study": "36940", "sites": ["930557"]},   # UC  — centrum s daty
    {"study": "35472", "sites": ["898745"]},   # MDD — první centrum
]

→ proběhnou 4 reporty (2 centra × 2 typy). Po testu vrátit plný seznam.


3. Konfigurace (konstanty v hlavičce skriptu)

Konstanta Hodnota / význam
EMAIL vbuzalka@its.jnj.com (login přes iMedidata/OKTA na xsp.covance.com)
PASSWORD heslo k účtu (uložené přímo v kódu)
LOGIN_URL https://xsp.covance.com/ — po přihlášení redirect na xsp.labcorp.com
OUT_DIR U:\PythonProject\Janssen\Covance_UCO3001\Source
PROFILE_DIR browser_profile/ vedle skriptu (persistent Chromium profil)
STUDIES seznam studií, každá má study (interní ID) + sites (interní ID center)
REPORT_TYPES standard-test-results/standard a microbiology/microbiology

Interní čísla center

36940 (UC):  930551, 930556, 930525, 930549, 930543, 930547,
             930555, 930557, 930539, 930536, 930553, 930531
35472 (MDD): 898745, 898739, 898733, 898744, 898727

Pozor: jsou to interní ID Labcorpu, nikoli čísla center typu CZ10001. V URL test-results se používá právě toto interní ID: …/test-results/{SITE_ID}/{standard-test-results|microbiology}. (Pozn.: 36940 zdroj = download_equeries_report_v1.1.py SITES; 35472 zdroj = ručně dodaná čísla center.)

Generování REPORTS (DRY)

REPORTS se sestaví automaticky jako kartézský součin STUDIES × sites × REPORT_TYPES. Přidání/odebrání centra, studie nebo typu reportu = úprava příslušného seznamu, vzor URL i názvu se píše jen jednou.


4. Výstupní soubory

Formát názvu (timestamp + popisný název):

{YYYY-MM-DD_HHMMSS} sponsor-study-{STUDY}-test-results-{SITE_ID}-{TYP}.csv

{TYP} = standard nebo microbiology. Příklady:

2026-05-29_131121 sponsor-study-36940-test-results-930557-standard.csv
2026-05-29_131500 sponsor-study-36940-test-results-930557-microbiology.csv
2026-05-29_131800 sponsor-study-35472-test-results-898745-standard.csv
  • Timestamp se generuje pro každý report zvlášť (v okamžiku exportu).
  • Staré soubory se nikdy nemažou (verzování přes timestamp).
  • expect_download zachytí download event, save_as() uloží pod naším názvem.

5. Průběh skriptu (kroky + logging)

Každý krok se loguje s časem ([HH:MM:SS], flush=True).

Fáze Co dělá
START spustí prohlížeč
LOGIN otevře login; pokud je session aktivní, přihlášení přeskočí
Pro každý report (studie × centrum × typ):
KROK 1/5 navigace na report URL
KROK 2/5 čeká na řádky gridu .ag-row nebo prázdný grid („No Data"); pak stabilizace počtu
KROK 3/5 klik na viditelné tři tečky (more_horiz) → otevře menu
KROK 4/5 klik na viditelné „Export to CSV" → zachytí download
KROK 5/5 uloží soubor do OUT_DIR
KONEC souhrn hotovo X/34 + seznam selhaných (site/typ)

Log u každého reportu ukazuje i typ: === Centrum 930557 / microbiology (studie 36940) ===.


6. Klíčové technické poznatky (PROČ to tak je) — ověřeno přes Chrome MCP

Stránka test-results je Angular SPA s knihovnou MDL a tabulkou AG Grid. Microbiology záložka má stejnou strukturu jako Standard → vše níže platí pro oba.

6.1 Čekání na data = řádky AG Gridu

  • Data jsou načtena, jakmile se objeví řádky div.ag-row (count 0 → N).
  • Řádky jsou position-absolute (virtuální render) → Playwright je nepovažuje za „visible". Proto:
    • wait_for_selector("div.ag-row") (default visible) timeoutuje.
    • wait_for_function("() => document.querySelectorAll('div.ag-row').length > 0").
  • Stabilizace: počet řádků se čte co 2 s, dokud se 2× po sobě neshodne.
  • POZN.: počet .ag-row se „zastropuje" (typicky ~153) kvůli virtuálnímu renderu — NENÍ to skutečný počet záznamů. Slouží jen jako signál „data jsou". Export do CSV ale vyexportuje VŠECHNY řádky (ověřeno: různé velikosti CSV).

6.2 „Fetching Data" / spinner — NEPLATÍ pro tuto stránku

  • Na test-results NENÍ text „Fetching Data" (ten je na samples reportu).
  • <loading-bar> jen problikne při route-loadu → nespoléhat. Signál = .ag-row.

6.3 Tři tečky (export) — na stránce jsou DVA <ag-export>

  • 2× <ag-export> (1 skrytý), 3× ikona more_horiz. Proto filtr na viditelnost: page.locator("ag-export button:visible", has_text="more_horiz").first.click()

6.4 „Export to CSV" — v DOM jsou DVĚ položky

  • 2× mdl-menu-item „Export to CSV" (1 skrytá). Proto: page.locator("mdl-menu-item:visible", has_text="Export to CSV").first.click()
    • get_by_text("Export to CSV") → strict mode violation (2 elementy).

6.5 Prázdné centrum (ověřeno přes Chrome MCP na centru 930551)

  • AG Grid při 0 záznamech zobrazí no-rows overlay s textem „No Data".
  • Struktura: .ag-overlay.ag-overlay-panel.ag-overlay-no-rows-wrapper<span>No Data</span>.
  • ⚠️ Třída NENÍ .ag-overlay-no-rows-center (chybný předpoklad, nikdy nezabral) — správně je .ag-overlay-no-rows-wrapper.
  • ⚠️ Text „No Data" NENÍ v .ag-body-viewport (ten je prázdný, height: 1px).
  • ⚠️ Na stránce jsou 2 overlaye (1 skrytý, 1 viditelný) → kontrola viditelnosti offsetParent !== null.
  • Detekce (KROK 2):
    () => {
      if (document.querySelectorAll('div.ag-row').length > 0) return false;
      return [...document.querySelectorAll('.ag-overlay-no-rows-wrapper')]
          .some(e => e.offsetParent !== null);
    }
    
  • KROK 2 čeká na .ag-row NEBO tuto detekci → prázdné centrum necheká zbytečně 120 s a export se přeskočí.

7. Login logika (sdílená napříč Covance skripty)

page.goto(LOGIN_URL)
page.wait_for_load_state("networkidle")
if not page.get_by_label("Email").is_visible():
    return                      # session aktivní → login přeskočit
# jinak: Email → Next → Password → Verify → wait redirect (code= zmizí z URL)
  • Proč is_visible() a ne kontrola URL: po goto(LOGIN_URL) zůstane URL xsp.covance.com i po redirectu, takže URL test je nespolehlivý.
  • is_visible() neháže výjimku — když pole není, vrátí False.

8. Chrome flagy proti „Restore pages" / broken session

--disable-restore-session-state      # neobnovovat předchozí session
--disable-session-crashed-bubble     # potlačit "Chromium didn't shut down correctly"

9. Robustnost smyčky

  • Každý report je v try/exceptchyba u jednoho nezastaví zbytek.
  • Na konci souhrn: hotovo X/34 + seznam SELHALA centra: site/typ, ….

10. Možná budoucí rozšíření

  • Další studie / centra: přidat položku do STUDIES.
  • Další typ reportu: přidat položku do REPORT_TYPES (slug + suffix).
  • Ověření počtu: počet .ag-row se loguje — POZOR, je zastropený virtuálním renderem, takže ho nelze porovnávat s počtem řádků v CSV (CSV má všechny).

11. Příbuzné skripty (stejná složka / portál)

Skript Co stahuje
download_samples_report_v1.1.py All Samples (sampletracking, čeká na „Fetching Data")
download_kit_inventory_v2.1.py Kit inventory (on-hand expiration)
download_equeries_report_v1.1.py eQuery reporty (zdroj SITE_IDS pro 36940)
download_test_results_v1.1.py tento — Test Results (Standard + Microbiology, 2 studie)

Všechny sdílejí: persistent profile, login s is_visible() checkem, ag-export + „Export to CSV" pattern.