7.4 KiB
download_test_results_v1.4.py — dokumentace
Verze: 1.4 · Datum: 2026-05-29
Umístění: U:\PythonProject\Janssen\Covance\download_test_results_v1.4.py
Změny v1.4 oproti 1.3: retry na úrovni reportu. Při paralelním běhu server občas vrátí timeout (zejm.
page.goto30 s, nebowait_for_function120 s na grid). Dřív byl takový report rovnou zapsán jako selhaný. Teď se každý report zkusí až 2× (MAX_ATTEMPTS=2), mezi pokusy 5 s pauza agoto("about:blank")jako reset. Většina přechodných timeoutů projde napodruhé. Launcher povýšen narun_test_results_parallel_v1.2.py(cílí na v1.4).Změny v1.3 oproti 1.2: robustní login (NEčekat na
networkidle, čekat přímo na pole Email/Password) + okno se při pádu nezavře (try/except + input()). Změny v1.2 oproti 1.1: paralelní běh přes sharding (--shard N --of M). Změny v1.1 oproti 1.0: druhá studie 35472 (MDD) + report Microbiology.
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: 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í
2a) Paralelně (doporučeno — rychlejší)
U:\PythonProject\Janssen\.venv\Scripts\python.exe ^
U:\PythonProject\Janssen\Covance\run_test_results_parallel_v1.2.py
2b) Serialně (jeden proces)
U:\PythonProject\Janssen\.venv\Scripts\python.exe ^
U:\PythonProject\Janssen\Covance\download_test_results_v1.4.py
2c) Jeden konkrétní shard ručně
…\python.exe download_test_results_v1.4.py --shard 2 --of 4
- Prohlížeč běží viditelně (
headless=False), maximalizovaný. - Po dokončení (i po chybě) okno čeká na Enter — ať je vidět log.
3. Retry (v1.4)
3.1 Proč
Z reálného běhu 4 shardů (29. 5. 2026) ze 34 reportů selhaly 2:
930539/standard—page.gototimeout 30 s (server vůbec neodpověděl)930547/standard—wait_for_functiontimeout 120 s (grid se nedotáhl)
Obojí jsou přechodné serverové timeouty (sharding ho zatěžuje). Stačí počkat a zkusit znovu — propadne to.
3.2 Jak
Konstanty:
MAX_ATTEMPTS = 2 # 1. pokus + 1 retry
RETRY_BACKOFF_S = 5 # pauza pred opakovanym pokusem
download_report(page, report) je wrapper, který volá
download_report_once(...) v cyklu 1..MAX_ATTEMPTS. Při výjimce zaloguje
POKUS X/N SELHAL: …, počká RETRY_BACKOFF_S, navštíví about:blank
(reset gridu), a zkusí znovu. Když selže poslední pokus, výjimka se propustí
ven a vnější smyčka v main() to zapíše do failed.
3.3 Co se nezopakuje
Login — ten je mimo retry. Pokud spadne login, shard skončí přes vnější
try/except v __main__ s FATAL: ... a okno čeká na Enter.
4. Paralelní běh (sharding) — beze změny vůči v1.3
4.1 Rozdělení práce
REPORTS = ALL_REPORTS[SHARD - 1::OF]
Shard 1 z 4 vezme indexy 0, 4, 8, … atd. Bez argumentů = serial.
4.2 Profil per shard
| Běh | Profil |
|---|---|
serialní (--of 1) |
browser_profile/ |
shard N (--of M>1) |
browser_profile_{N}/ |
Chrome zamyká adresář profilu → 2 instance nesdílí 1 profil.
4.3 Login (varianta B)
Každý shard se přihlásí sám (jen heslo, žádné MFA). Session se uloží do
browser_profile_{N}/ → další běh login přeskočí. Launcher startuje
s rozestupem STAGGER_S = 8 s, aby se OKTA nezahltil.
4.4 Launcher run_test_results_parallel_v1.2.py
N_SHARDS = 4,STAGGER_S = 8 s.- Každý proces v novém okně (
CREATE_NEW_CONSOLE) → logy se neprolínají. - Prefix logu:
[S{shard}/{of}].
4.5 Reálné zrychlení
~2–3× (server throttluje exporty, ne přesně 4×).
5. Výstupní soubory
{YYYY-MM-DD_HHMMSS} sponsor-study-{STUDY}-test-results-{SITE_ID}-{TYP}.csv
Všechny shardy ukládají do Source/. Staré se nikdy nemažou.
6. Klíčové technické poznatky — ověřeno přes Chrome MCP
6.1 Čekání na data = .ag-row
- ❌
wait_for_selector("div.ag-row")(default visible) timeoutuje (řádky jsouposition-absolute). - ✅
wait_for_function("() => document.querySelectorAll('div.ag-row').length > 0"). - Stabilizace: počet se čte co 2 s, dokud se 2× neshodne.
- Počet
.ag-rowje zastropený (~153) virtuálním renderem. Export do CSV ale vyexportuje VŠECHNY řádky.
6.2 „Fetching Data" / spinner — NEPLATÍ pro tuto stránku
Je jen na samples reportu. Signál = .ag-row.
6.3 Tři tečky (export) — DVA <ag-export>
✅ page.locator("ag-export button:visible", has_text="more_horiz").first.click()
6.4 „Export to CSV" — DVĚ položky v DOM
✅ page.locator("mdl-menu-item:visible", has_text="Export to CSV").first.click()
6.5 Prázdné centrum
- No-rows overlay
.ag-overlay-no-rows-wrapper(NE-no-rows-center). - 2 overlaye, 1 skrytý → kontrola
offsetParent !== null. - KROK 2 čeká na
.ag-rowNEBO prázdný overlay → nečeká 120 s zbytečně.
7. Login logika (v1.3+) — beze změny ve v1.4
page.goto(LOGIN_URL)
try:
page.get_by_label("Email").wait_for(state="visible", timeout=12000)
except Exception:
return # session aktivni → login přeskočit
page.get_by_label("Email").fill(EMAIL)
page.get_by_role("button", name="Next").click()
page.get_by_label("Password").wait_for(state="visible", timeout=30000)
page.get_by_label("Password").fill(PASSWORD)
page.get_by_role("button", name="Verify").click()
page.wait_for_url(lambda url: "code=" not in url or "xsp." in url, timeout=60000)
NE networkidle. NE kontrola URL (po redirectu zůstává xsp.covance.com).
8. Chrome flagy
--disable-restore-session-state
--disable-session-crashed-bubble
9. Robustnost
- Retry per report (
MAX_ATTEMPTS = 2) → přechodné timeouty propadnou. - Každý report v
try/except→ chyba u jednoho nezastaví zbytek shardu. - Celý běh shardu v
try/except+finally: input()→ okno se při pádu nezavře. - Souhrn na konci:
hotovo X/Y (shard N/M)+SELHALA centra: …. - Launcher hlídá
returncodekaždého shardu.
10. Možná budoucí rozšíření
- Více pokusů: zvednout
MAX_ATTEMPTS(3+) — pro hodně přetížený server. - Více/méně procesů: změnit
N_SHARDSv launcheru (profily_1.._N). - Další studie / centra / typ reportu: přidat do
STUDIES/REPORT_TYPES. - Vyčistit profily: smazat
browser_profile_*/(vynutí nový login).
11. Příbuzné skripty
| Skript | Co stahuje |
|---|---|
download_samples_report_v1.1.py |
All Samples (sampletracking) |
download_kit_inventory_v2.1.py |
Kit inventory |
download_equeries_report_v1.1.py |
eQuery reporty (zdroj SITE_IDS pro 36940) |
download_test_results_v1.4.py |
tento — Test Results (Standard + Microbiology, 2 studie, sharding, retry) |
run_test_results_parallel_v1.2.py |
launcher 4 paralelních shardů test-results |