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

Default phenotype workspace path

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