Coverage for anonymise/demo_config.py: 61%
41 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-08-27 10:34 -0500
« prev ^ index » next coverage.py v7.8.0, created at 2025-08-27 10:34 -0500
1#!/usr/bin/env python
3"""
4crate_anon/anonymise/demo_config.py
6===============================================================================
8 Copyright (C) 2015, University of Cambridge, Department of Psychiatry.
9 Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
11 This file is part of CRATE.
13 CRATE is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
18 CRATE is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with CRATE. If not, see <https://www.gnu.org/licenses/>.
26===============================================================================
28**Print a demonstration config file for the anonymiser.**
30"""
32import argparse
33import pprint
34import re
35import sys
36from typing import Dict
38from cardinal_pythonlib.file_io import smart_open
39from rich_argparse import ArgumentDefaultsRichHelpFormatter
41from crate_anon.anonymise.constants import DEMO_CONFIG
42from crate_anon.common.constants import EXIT_FAILURE
43from crate_anon.version import CRATE_VERSION_PRETTY
46# =============================================================================
47# Get a demo config, with placeholders replaced
48# =============================================================================
51def search_replace_text(text: str, replace_dict: Dict[str, str]) -> str:
52 for search, replace in replace_dict.items():
53 if replace is None:
54 print(f"Can't replace '{search}' with None")
55 sys.exit(EXIT_FAILURE)
57 text = text.replace(f"@@{search}@@", replace)
59 return text
62def get_demo_config() -> str:
63 replace_dict = {
64 "admin_db_url": "mysql+mysqldb://username:password@127.0.0.1:3306/admin_databasename?charset=utf8", # noqa: E501
65 "change_detection_encryption_phrase": "YETANOTHER",
66 "data_dictionary_filename": "testdd.tsv",
67 "dest_db_url": "mysql+mysqldb://username:password@127.0.0.1:3306/output_databasename?charset=utf8", # noqa: E501
68 "master_patient_id_encryption_phrase": "SOME_OTHER_PASSPHRASE_REPLACE_ME", # noqa: E501
69 "per_table_patient_id_encryption_phrase": "SOME_PASSPHRASE_REPLACE_ME",
70 "source_db1_ddgen_include_fields": "",
71 "source_db1_ddgen_scrubsrc_patient_fields": "",
72 "source_db1_url": "mysql+mysqldb://username:password@127.0.0.1:3306/source_databasename?charset=utf8", # noqa: E501
73 }
75 config = search_replace_text(DEMO_CONFIG, replace_dict)
77 missing_dict = {}
79 regex = r"@@([^@]*)@@"
80 for match in re.finditer(regex, config):
81 missing_dict[f"{match.group(1)}"] = ""
83 if missing_dict:
84 print(
85 "@@ Placeholders not substituted in DEMO_CONFIG:", file=sys.stderr
86 )
87 pprint.pprint(missing_dict, stream=sys.stderr)
88 sys.exit(EXIT_FAILURE)
90 return config.strip()
93# =============================================================================
94# Main
95# =============================================================================
98def main() -> None:
99 """
100 Command-line entry point.
101 """
102 # noinspection PyTypeChecker
103 parser = argparse.ArgumentParser(
104 description=f"Print a demo config file for the CRATE anonymiser. "
105 f"({CRATE_VERSION_PRETTY})",
106 formatter_class=ArgumentDefaultsRichHelpFormatter,
107 )
109 parser.add_argument(
110 "--output", default="-", help="File for output; use '-' for stdout."
111 )
112 parser.add_argument(
113 "--leave_placeholders",
114 action="store_true",
115 help="Don't substitute @@ placeholders with examples",
116 )
118 args = parser.parse_args()
120 # -------------------------------------------------------------------------
121 # Print demo config
122 # -------------------------------------------------------------------------
124 with smart_open(args.output, "w") as f:
125 if args.leave_placeholders:
126 contents = DEMO_CONFIG.strip()
127 else:
128 contents = get_demo_config()
129 print(contents, file=f)
132if __name__ == "__main__":
133 main()