acmc.main

main.py module

This module provides the functionality for the acmc command line interface

  1"""
  2main.py module
  3
  4This module provides the functionality for the acmc command line interface
  5"""
  6
  7import argparse
  8import logging
  9from pathlib import Path
 10
 11import acmc
 12from acmc import trud, omop, phen, parse, logging_config as lc
 13
 14
 15DEFAULT_WORKSPACE_PATH = Path("./workspace")
 16"""Default phenotype workspace path"""
 17
 18
 19def _trud_install(args: argparse.Namespace):
 20    """Handle the `trud install` command."""
 21    trud.install()
 22
 23
 24def _omop_install(args: argparse.Namespace):
 25    """Handle the `omop install` command."""
 26    omop.install(args.omop_zip_file, args.version)
 27
 28
 29def _omop_clear(args: argparse.Namespace):
 30    """Handle the `omop clear` command."""
 31    omop.clear(omop.DB_PATH)
 32
 33
 34def _omop_delete(args: argparse.Namespace):
 35    """Handle the `omop delete` command."""
 36    omop.delete(omop.DB_PATH)
 37
 38
 39def _phen_init(args: argparse.Namespace):
 40    """Handle the `phen init` command."""
 41    phen.init(args.phen_dir, args.remote_url)
 42
 43
 44def _phen_fork(args: argparse.Namespace):
 45    """Handle the `phen fork` command."""
 46    phen.fork(
 47        args.phen_dir,
 48        args.upstream_url,
 49        args.upstream_version,
 50        new_origin_url=args.remote_url,
 51    )
 52
 53
 54def _phen_validate(args: argparse.Namespace):
 55    """Handle the `phen validate` command."""
 56    phen.validate(args.phen_dir)
 57
 58
 59def _phen_map(args: argparse.Namespace):
 60    """Handle the `phen map` command."""
 61    phen.map(
 62        args.phen_dir,
 63        args.target_coding,
 64        args.not_translate,
 65        args.no_metadata,
 66        args.do_reverse_translate,
 67    )
 68
 69
 70def _phen_export(args: argparse.Namespace):
 71    """Handle the `phen copy` command."""
 72    phen.export(args.phen_dir, args.version)
 73
 74
 75def _phen_publish(args: argparse.Namespace):
 76    """Handle the `phen publish` command."""
 77    phen.publish(args.phen_dir, args.msg, args.remote_url, args.increment)
 78
 79
 80def _phen_copy(args: argparse.Namespace):
 81    """Handle the `phen copy` command."""
 82    phen.copy(args.phen_dir, args.target_dir, args.version)
 83
 84
 85def _phen_diff(args: argparse.Namespace):
 86    """Handle the `phen diff` command."""
 87    phen.diff(
 88        args.phen_dir,
 89        args.version,
 90        args.old_phen_dir,
 91        args.old_version,
 92        args.not_check_config,
 93    )
 94
 95
 96def main():
 97    parser = argparse.ArgumentParser(description="ACMC command-line tool")
 98    parser.add_argument("--debug", action="store_true", help="Enable debug mode")
 99    parser.add_argument(
100        "--version", action="version", version=f"acmc {acmc.__version__}"
101    )
102
103    # Top-level commands
104    subparsers = parser.add_subparsers(
105        dest="command", required=True, help="Available commands"
106    )
107
108    ### TRUD Command ###
109    trud_parser = subparsers.add_parser("trud", help="TRUD commands")
110    trud_subparsers = trud_parser.add_subparsers(
111        dest="subcommand", required=True, help="TRUD subcommands"
112    )
113
114    # trud install
115    trud_install_parser = trud_subparsers.add_parser(
116        "install", help="Install TRUD components"
117    )
118    trud_install_parser.set_defaults(func=_trud_install)
119
120    ### OMOP Command ###
121    omop_parser = subparsers.add_parser("omop", help="OMOP commands")
122    omop_subparsers = omop_parser.add_subparsers(
123        dest="subcommand", required=True, help="OMOP subcommands"
124    )
125
126    # omop install
127    omop_install_parser = omop_subparsers.add_parser(
128        "install", help="Install OMOP codes within database"
129    )
130    omop_install_parser.add_argument(
131        "-f", "--omop-zip-file", required=True, help="Path to downloaded OMOP zip file"
132    )
133    omop_install_parser.add_argument(
134        "-v", "--version", required=True, help="OMOP vocabularies release version"
135    )
136    omop_install_parser.set_defaults(func=_omop_install)
137
138    # omop clear
139    omop_clear_parser = omop_subparsers.add_parser(
140        "clear", help="Clear OMOP data from database"
141    )
142    omop_clear_parser.set_defaults(func=_omop_clear)
143
144    # omop delete
145    omop_delete_parser = omop_subparsers.add_parser(
146        "delete", help="Delete OMOP database"
147    )
148    omop_delete_parser.set_defaults(func=_omop_delete)
149
150    ### PHEN Command ###
151    phen_parser = subparsers.add_parser("phen", help="Phen commands")
152    phen_subparsers = phen_parser.add_subparsers(
153        dest="subcommand", required=True, help="Phen subcommands"
154    )
155
156    # phen init
157    phen_init_parser = phen_subparsers.add_parser(
158        "init", help="Initiatise phenotype directory"
159    )
160    phen_init_parser.add_argument(
161        "-d",
162        "--phen-dir",
163        type=str,
164        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
165        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
166    )
167    phen_init_parser.add_argument(
168        "-r",
169        "--remote_url",
170        help="(Optional) URL to repository where the phenotype will be published.",
171    )
172    phen_init_parser.set_defaults(func=_phen_init)
173
174    # phen fork
175    phen_fork_parser = phen_subparsers.add_parser(
176        "fork", help="Fork an existing phenotype"
177    )
178    phen_fork_parser.add_argument(
179        "-d",
180        "--phen-dir",
181        type=str,
182        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
183        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
184    )
185    phen_fork_parser.add_argument(
186        "-r",
187        "--remote_url",
188        help="(Optional) URL to repository where the forked phenotype will be published.",
189    )
190    phen_fork_parser.add_argument(
191        "-u",
192        "--upstream-url",
193        required=True,
194        help="(Required) URL to the phenotype repository to fork.",
195    )
196    phen_fork_parser.add_argument(
197        "-v",
198        "--upstream-version",
199        required=True,
200        help="(Required) Phenotype version to fork.",
201    )
202    phen_fork_parser.set_defaults(func=_phen_fork)
203
204    # phen validate
205    phen_validate_parser = phen_subparsers.add_parser(
206        "validate", help="Validate phenotype configuration"
207    )
208    phen_validate_parser.add_argument(
209        "-d",
210        "--phen-dir",
211        type=str,
212        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
213        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
214    )
215    phen_validate_parser.set_defaults(func=_phen_validate)
216
217    # phen map
218    phen_map_parser = phen_subparsers.add_parser("map", help="Process phen mapping")
219    phen_map_parser.add_argument(
220        "-d",
221        "--phen-dir",
222        type=str,
223        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
224        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
225    )
226    phen_map_parser.add_argument(
227        "-t",
228        "--target-coding",
229        choices=parse.SUPPORTED_CODE_TYPES,
230        help=f"Specify the target coding {parse.SUPPORTED_CODE_TYPES}",
231    )
232    phen_map_parser.add_argument(
233        "--not-translate",
234        action="store_true",
235        default=False,
236        help="(Optional) Prevent any phenotype translation using NHS TRUD vocabularies.",
237    )
238    phen_map_parser.add_argument(
239        "--no-metadata",
240        action="store_true",
241        default=False,
242        help="(Optional) Prevent copying of metadata columns to output.",
243    )
244    phen_map_parser.add_argument(
245        "--do-reverse-translate",
246        action="store_true",
247        default=False,
248        help="(Optional) Enable reversing one directional mappings. WARNING goes against NHS TRUD guidelines.",
249    )
250    phen_map_parser.set_defaults(func=_phen_map)
251
252    # phen export
253    phen_export_parser = phen_subparsers.add_parser(
254        "export", help="Export phen to OMOP database"
255    )
256    phen_export_parser.add_argument(
257        "-d",
258        "--phen-dir",
259        type=str,
260        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
261        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
262    )
263    phen_export_parser.add_argument(
264        "-v",
265        "--version",
266        type=str,
267        default="latest",
268        help="Phenotype version to export, defaults to the latest version",
269    )
270    phen_export_parser.set_defaults(func=_phen_export)
271
272    # phen publish
273    phen_publish_parser = phen_subparsers.add_parser(
274        "publish", help="Publish phenotype configuration"
275    )
276    phen_publish_parser.add_argument(
277        "-d",
278        "--phen-dir",
279        type=str,
280        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
281        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
282    )
283    phen_publish_parser.add_argument(
284        "-i",
285        "--increment",
286        type=str,
287        default=phen.DEFAULT_VERSION_INC,
288        choices=phen.SEMANTIC_VERSION_TYPES,
289        help=f"Version increment: {phen.SEMANTIC_VERSION_TYPES}, default is {phen.DEFAULT_VERSION_INC} increment",
290    )
291    phen_publish_parser.add_argument(
292        "-m", "--msg", help="Message to include with the published version"
293    )
294    phen_publish_parser.add_argument(
295        "-r", "--remote_url", help="URL to remote git repository"
296    )
297    phen_publish_parser.set_defaults(func=_phen_publish)
298
299    # phen copy
300    phen_copy_parser = phen_subparsers.add_parser(
301        "copy", help="Publish phenotype configuration"
302    )
303    phen_copy_parser.add_argument(
304        "-d",
305        "--phen-dir",
306        type=str,
307        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
308        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
309    )
310    phen_copy_parser.add_argument(
311        "-td",
312        "--target-dir",
313        type=str,
314        default=str(DEFAULT_WORKSPACE_PATH.resolve()),
315        help="Target directory for the copy",
316    )
317    phen_copy_parser.add_argument(
318        "-v",
319        "--version",
320        type=str,
321        default="latest",
322        help="Phenotype version to copy, defaults to the latest version",
323    )
324    phen_copy_parser.set_defaults(func=_phen_copy)
325
326    # phen diff
327    phen_diff_parser = phen_subparsers.add_parser(
328        "diff", help="Publish phenotype configuration"
329    )
330    phen_diff_parser.add_argument(
331        "-d",
332        "--phen-dir",
333        type=str,
334        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
335        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
336    )
337    phen_diff_parser.add_argument(
338        "-v",
339        "--version",
340        default="latest",
341        help="Phenotype version to compare with an old version, defaults to the HEAD of the workspace directory",
342    )
343    phen_diff_parser.add_argument(
344        "-od",
345        "--old-phen-dir",
346        type=str,
347        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
348        help="Directory for the old phenotype version, defaults to workspace directory",
349    )
350    phen_diff_parser.add_argument(
351        "-ov",
352        "--old-version",
353        required=True,
354        help="Old phenotype version to compare with the changed version",
355    )
356    phen_diff_parser.add_argument(
357        "--not-check-config",
358        action="store_true",
359        default=False,
360        help="(Optional) Prevent loading and comparing config file, in the case where one does not exist",
361    )
362    phen_diff_parser.set_defaults(func=_phen_diff)
363
364    # Parse arguments
365    args = parser.parse_args()
366
367    # setup logging
368    if args.debug:
369        lc.set_log_level(logging.DEBUG)
370
371    # Call the function associated with the command
372    args.func(args)
373
374
375if __name__ == "__main__":
376    main()
DEFAULT_WORKSPACE_PATH = PosixPath('workspace')

Default phenotype workspace path

def main():
 97def main():
 98    parser = argparse.ArgumentParser(description="ACMC command-line tool")
 99    parser.add_argument("--debug", action="store_true", help="Enable debug mode")
100    parser.add_argument(
101        "--version", action="version", version=f"acmc {acmc.__version__}"
102    )
103
104    # Top-level commands
105    subparsers = parser.add_subparsers(
106        dest="command", required=True, help="Available commands"
107    )
108
109    ### TRUD Command ###
110    trud_parser = subparsers.add_parser("trud", help="TRUD commands")
111    trud_subparsers = trud_parser.add_subparsers(
112        dest="subcommand", required=True, help="TRUD subcommands"
113    )
114
115    # trud install
116    trud_install_parser = trud_subparsers.add_parser(
117        "install", help="Install TRUD components"
118    )
119    trud_install_parser.set_defaults(func=_trud_install)
120
121    ### OMOP Command ###
122    omop_parser = subparsers.add_parser("omop", help="OMOP commands")
123    omop_subparsers = omop_parser.add_subparsers(
124        dest="subcommand", required=True, help="OMOP subcommands"
125    )
126
127    # omop install
128    omop_install_parser = omop_subparsers.add_parser(
129        "install", help="Install OMOP codes within database"
130    )
131    omop_install_parser.add_argument(
132        "-f", "--omop-zip-file", required=True, help="Path to downloaded OMOP zip file"
133    )
134    omop_install_parser.add_argument(
135        "-v", "--version", required=True, help="OMOP vocabularies release version"
136    )
137    omop_install_parser.set_defaults(func=_omop_install)
138
139    # omop clear
140    omop_clear_parser = omop_subparsers.add_parser(
141        "clear", help="Clear OMOP data from database"
142    )
143    omop_clear_parser.set_defaults(func=_omop_clear)
144
145    # omop delete
146    omop_delete_parser = omop_subparsers.add_parser(
147        "delete", help="Delete OMOP database"
148    )
149    omop_delete_parser.set_defaults(func=_omop_delete)
150
151    ### PHEN Command ###
152    phen_parser = subparsers.add_parser("phen", help="Phen commands")
153    phen_subparsers = phen_parser.add_subparsers(
154        dest="subcommand", required=True, help="Phen subcommands"
155    )
156
157    # phen init
158    phen_init_parser = phen_subparsers.add_parser(
159        "init", help="Initiatise phenotype directory"
160    )
161    phen_init_parser.add_argument(
162        "-d",
163        "--phen-dir",
164        type=str,
165        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
166        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
167    )
168    phen_init_parser.add_argument(
169        "-r",
170        "--remote_url",
171        help="(Optional) URL to repository where the phenotype will be published.",
172    )
173    phen_init_parser.set_defaults(func=_phen_init)
174
175    # phen fork
176    phen_fork_parser = phen_subparsers.add_parser(
177        "fork", help="Fork an existing phenotype"
178    )
179    phen_fork_parser.add_argument(
180        "-d",
181        "--phen-dir",
182        type=str,
183        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
184        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
185    )
186    phen_fork_parser.add_argument(
187        "-r",
188        "--remote_url",
189        help="(Optional) URL to repository where the forked phenotype will be published.",
190    )
191    phen_fork_parser.add_argument(
192        "-u",
193        "--upstream-url",
194        required=True,
195        help="(Required) URL to the phenotype repository to fork.",
196    )
197    phen_fork_parser.add_argument(
198        "-v",
199        "--upstream-version",
200        required=True,
201        help="(Required) Phenotype version to fork.",
202    )
203    phen_fork_parser.set_defaults(func=_phen_fork)
204
205    # phen validate
206    phen_validate_parser = phen_subparsers.add_parser(
207        "validate", help="Validate phenotype configuration"
208    )
209    phen_validate_parser.add_argument(
210        "-d",
211        "--phen-dir",
212        type=str,
213        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
214        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
215    )
216    phen_validate_parser.set_defaults(func=_phen_validate)
217
218    # phen map
219    phen_map_parser = phen_subparsers.add_parser("map", help="Process phen mapping")
220    phen_map_parser.add_argument(
221        "-d",
222        "--phen-dir",
223        type=str,
224        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
225        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
226    )
227    phen_map_parser.add_argument(
228        "-t",
229        "--target-coding",
230        choices=parse.SUPPORTED_CODE_TYPES,
231        help=f"Specify the target coding {parse.SUPPORTED_CODE_TYPES}",
232    )
233    phen_map_parser.add_argument(
234        "--not-translate",
235        action="store_true",
236        default=False,
237        help="(Optional) Prevent any phenotype translation using NHS TRUD vocabularies.",
238    )
239    phen_map_parser.add_argument(
240        "--no-metadata",
241        action="store_true",
242        default=False,
243        help="(Optional) Prevent copying of metadata columns to output.",
244    )
245    phen_map_parser.add_argument(
246        "--do-reverse-translate",
247        action="store_true",
248        default=False,
249        help="(Optional) Enable reversing one directional mappings. WARNING goes against NHS TRUD guidelines.",
250    )
251    phen_map_parser.set_defaults(func=_phen_map)
252
253    # phen export
254    phen_export_parser = phen_subparsers.add_parser(
255        "export", help="Export phen to OMOP database"
256    )
257    phen_export_parser.add_argument(
258        "-d",
259        "--phen-dir",
260        type=str,
261        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
262        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
263    )
264    phen_export_parser.add_argument(
265        "-v",
266        "--version",
267        type=str,
268        default="latest",
269        help="Phenotype version to export, defaults to the latest version",
270    )
271    phen_export_parser.set_defaults(func=_phen_export)
272
273    # phen publish
274    phen_publish_parser = phen_subparsers.add_parser(
275        "publish", help="Publish phenotype configuration"
276    )
277    phen_publish_parser.add_argument(
278        "-d",
279        "--phen-dir",
280        type=str,
281        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
282        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
283    )
284    phen_publish_parser.add_argument(
285        "-i",
286        "--increment",
287        type=str,
288        default=phen.DEFAULT_VERSION_INC,
289        choices=phen.SEMANTIC_VERSION_TYPES,
290        help=f"Version increment: {phen.SEMANTIC_VERSION_TYPES}, default is {phen.DEFAULT_VERSION_INC} increment",
291    )
292    phen_publish_parser.add_argument(
293        "-m", "--msg", help="Message to include with the published version"
294    )
295    phen_publish_parser.add_argument(
296        "-r", "--remote_url", help="URL to remote git repository"
297    )
298    phen_publish_parser.set_defaults(func=_phen_publish)
299
300    # phen copy
301    phen_copy_parser = phen_subparsers.add_parser(
302        "copy", help="Publish phenotype configuration"
303    )
304    phen_copy_parser.add_argument(
305        "-d",
306        "--phen-dir",
307        type=str,
308        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
309        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
310    )
311    phen_copy_parser.add_argument(
312        "-td",
313        "--target-dir",
314        type=str,
315        default=str(DEFAULT_WORKSPACE_PATH.resolve()),
316        help="Target directory for the copy",
317    )
318    phen_copy_parser.add_argument(
319        "-v",
320        "--version",
321        type=str,
322        default="latest",
323        help="Phenotype version to copy, defaults to the latest version",
324    )
325    phen_copy_parser.set_defaults(func=_phen_copy)
326
327    # phen diff
328    phen_diff_parser = phen_subparsers.add_parser(
329        "diff", help="Publish phenotype configuration"
330    )
331    phen_diff_parser.add_argument(
332        "-d",
333        "--phen-dir",
334        type=str,
335        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
336        help="(Optional) Local phenotype workspace directory (default is ./workspace/phen).",
337    )
338    phen_diff_parser.add_argument(
339        "-v",
340        "--version",
341        default="latest",
342        help="Phenotype version to compare with an old version, defaults to the HEAD of the workspace directory",
343    )
344    phen_diff_parser.add_argument(
345        "-od",
346        "--old-phen-dir",
347        type=str,
348        default=str(phen.DEFAULT_PHEN_PATH.resolve()),
349        help="Directory for the old phenotype version, defaults to workspace directory",
350    )
351    phen_diff_parser.add_argument(
352        "-ov",
353        "--old-version",
354        required=True,
355        help="Old phenotype version to compare with the changed version",
356    )
357    phen_diff_parser.add_argument(
358        "--not-check-config",
359        action="store_true",
360        default=False,
361        help="(Optional) Prevent loading and comparing config file, in the case where one does not exist",
362    )
363    phen_diff_parser.set_defaults(func=_phen_diff)
364
365    # Parse arguments
366    args = parser.parse_args()
367
368    # setup logging
369    if args.debug:
370        lc.set_log_level(logging.DEBUG)
371
372    # Call the function associated with the command
373    args.func(args)