"""泄露扫描:查一次构建的资料库里有没有真实病例号、交付文件名、亚型名、诊断列名。 用法:uv run python scripts/scan_library.py --library library/<构建号> --answers answers/<构建号> 病例号和视频号从答案库读;亚型名、列名、文件名的词表在本脚本里独立写,不取自 delivery。 只输出命中的条数和类别,不输出命中的内容。这个脚本同时读两个库,只能放在 scripts/。 """ import argparse from collections import Counter from pathlib import Path from cadx.answers import read_aliases from cadx.library import scan_for_leaks SUBTYPE_NAMES = ( "IPMN", "IPMT", "SPN", "SPT", "SPTP", "MCN", "SCN", "导管内乳头状黏液性肿瘤", "导管内乳头状", "导管内乳头", "实性假乳头状", "实性假乳头", "黏液性囊性肿瘤", "黏液性囊", "粘液性囊", "黏液囊性", "粘液囊性", "浆液性囊性肿瘤", "浆液性囊", "浆液性微囊", "囊腺瘤", ) COLUMN_NAMES = ( "Case_ID", "Diagnosis", "病理类型", "病理类型(1 IPMN,2 SPN,3 MCN,4 SCN)", "患者ID", "CEUS视频ID", "推注开始时间", ) DELIVERY_FILE_NAMES = ( "临床工作簿_40例.xlsx", "超声报告文本_40例.xlsx", "MR报告文本_40例.xlsx", "Clinical_agent", "CEUS_agent", "MR_agent", ) FORBIDDEN_KEYS = ("diagnosis", "label", "gold", "pathology", "name", "row") def main() -> None: parser = argparse.ArgumentParser(description="扫描资料库里的泄露") parser.add_argument("--library", type=Path, required=True, help="资料库的构建目录") parser.add_argument("--answers", type=Path, required=True, help="同一构建号的答案库目录") args = parser.parse_args() library: Path = args.library answers: Path = args.answers if library.name != answers.name: raise SystemExit(f"两个目录的构建号不同:{library.name} 与 {answers.name}") categories: dict[str, str] = {} for row in read_aliases(answers): categories[f"P{row.case_no}"] = "病例号" categories[row.video_id] = "视频号" for suffix in ("_key.png", "_roi2.mp4", ".mp4", "_roi2_report.xlsx", "_report.xlsx"): categories[f"{row.video_id}{suffix}"] = "交付文件名" categories.update(dict.fromkeys(DELIVERY_FILE_NAMES, "交付文件名")) categories.update(dict.fromkeys(SUBTYPE_NAMES, "亚型名")) categories.update(dict.fromkeys(COLUMN_NAMES, "列名")) hits = scan_for_leaks(library, list(categories), FORBIDDEN_KEYS) counts = Counter("键名" if hit.kind == "键名" else categories[hit.term] for hit in hits) print(f"扫描的病例数:{len(read_aliases(answers))}") print(f"禁止的字符串:{len(categories)} 个;禁止的键名:{len(FORBIDDEN_KEYS)} 个") print(f"命中总数:{len(hits)}") for category in ("病例号", "视频号", "交付文件名", "亚型名", "列名", "键名"): print(f" {category}:{counts[category]}") if __name__ == "__main__": main()