Skip to content

Commit

Permalink
Study version display (#289)
Browse files Browse the repository at this point in the history
* Study version display

* coverted to action

* Moved to centralized --version

* updated docs to remove refs to template study

* fix args check

* remove cli parser for study-version

* promoted version to a subparser
  • Loading branch information
dogversioning authored Aug 28, 2024
1 parent c1d62ad commit fdae03e
Show file tree
Hide file tree
Showing 14 changed files with 74 additions and 189 deletions.
40 changes: 28 additions & 12 deletions cumulus_library/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""Utility for building/retrieving data views in AWS Athena"""

import copy
import importlib.util
import json
import os
import pathlib
Expand Down Expand Up @@ -361,12 +362,6 @@ def main(cli_args=None):

parser = cli_parser.get_parser()
args = vars(parser.parse_args(cli_args))
if args["version"]:
print(__version__)
sys.exit(0)
if args["action"] is None:
parser.print_usage()
sys.exit(1)

arg_env_pairs = (
("data_path", "CUMULUS_LIBRARY_DATA_PATH"),
Expand All @@ -392,6 +387,33 @@ def main(cli_args=None):
args[pair[0]] = env_val
read_env_vars.append([pair[1], env_val])

# We process this arg first, since version checking uses it
if args.get("study_dir"):
posix_paths = []
for path in args["study_dir"]:
posix_paths.append(get_abs_path(path))
args["study_dir"] = posix_paths

if args["action"] is None:
parser.print_usage()
sys.exit(1)

if args["action"] == "version":
print(f"cumulus-library version: {__version__}\n" "Installed studies:")
studies = get_study_dict(args.get("study_dir"))
for study in sorted(studies.keys()):
try:
spec = importlib.util.spec_from_file_location(
"study_init", studies[study] / "__init__.py"
)
study_init = importlib.util.module_from_spec(spec)
sys.modules["study_init"] = study_init
spec.loader.exec_module(study_init)
print(f" {study}: {study_init.__version__}")
except Exception:
print(f" {study}: no version defined")
sys.exit(0)

if len(read_env_vars) > 0:
table = rich.table.Table(title="Values read from environment variables")
table.add_column("Environment Variable", style="green")
Expand Down Expand Up @@ -419,12 +441,6 @@ def main(cli_args=None):
if args.get("data_path"):
args["data_path"] = get_abs_path(args["data_path"])

if args.get("study_dir"):
posix_paths = []
for path in args["study_dir"]:
posix_paths.append(get_abs_path(path))
args["study_dir"] = posix_paths

return run_cli(args)


Expand Down
9 changes: 5 additions & 4 deletions cumulus_library/cli_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,6 @@ def get_parser() -> argparse.ArgumentParser:
epilog="See 'cumulus-library -h [action]' for usage of a specific action",
)

parser.add_argument(
"--version", action="store_true", help="Display cumulus-library version number"
)

actions = parser.add_subparsers(
title="actions",
help="Available library actions",
Expand Down Expand Up @@ -297,4 +293,9 @@ def get_parser() -> argparse.ArgumentParser:
add_target_argument(markdown)
add_verbose_argument(markdown)

# Get study version

version = actions.add_parser("version", help="Gets the versions of the CLI and studies")
add_study_dir_argument(version)

return parser
1 change: 1 addition & 0 deletions cumulus_library/studies/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "3.0.0"
1 change: 1 addition & 0 deletions cumulus_library/studies/discovery/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "1.0.0"
25 changes: 0 additions & 25 deletions cumulus_library/studies/template/counts.sql

This file was deleted.

5 changes: 0 additions & 5 deletions cumulus_library/studies/template/date_range.sql

This file was deleted.

16 changes: 0 additions & 16 deletions cumulus_library/studies/template/lab_observations.sql

This file was deleted.

60 changes: 0 additions & 60 deletions cumulus_library/studies/template/manifest.toml

This file was deleted.

39 changes: 0 additions & 39 deletions cumulus_library/studies/template/setup.sql

This file was deleted.

1 change: 1 addition & 0 deletions cumulus_library/studies/vocab/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "0.1.0"
9 changes: 8 additions & 1 deletion docs/creating-studies.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@ to any build/export call to tell it where to look for your work.

## Creating a new study

If you're authoring a study, you just need to do two things to get started:
If you're authoring a study, you just need to do three things to get started:

- Make a new directory inside the directory you're keeping studies in. The name of this
directory will be the name you use to run it using the `cumulus-library` cli command.
In this document, we're calling this directory `my_study` as an example.
- Make a new file, `__init__.py`, which contains the following:
```python
__version__='0.1.0'
```
The CLI will use this to display the study's version on demand. Consider using
[semantic versioning rules](https://semver.org/#semantic-versioning-specification-semver)
to update this value as appropriate.
- Make a new file, `manifest.toml`. A
[toml file](https://toml.io/en/)
is a config file format - you don't need to worry too much about the details of this
Expand Down
36 changes: 12 additions & 24 deletions docs/first-time-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,29 @@ loading data into analytics packages.
[Cumulus Aggregator](https://docs.smarthealthit.org/cumulus/aggregator/)
- `generate-sql` and `generate-md` both create documentation artifacts, for
users authoring studies
- `version` will provide the installed version of `cumulus-library` and all present studies

By default, all available studies will be used by build and export, but you can use
or `--target` to specify a specific study to be run. You can use it multiple
times to configure several studies in order.
You can use `--target` to specify a specific study to be run. You can use it multiple
times to configure several studies in order. You can use `--study-dir` with most arguments
to target a directory where you are working on studies/working with studies that aren't
available to install with `pip`

Several pip installable studies will automatically be added to the list of available
Several `pip` installable studies will automatically be added to the list of available
studies to run. See [study list](./study-list.md) for more details.

There are several other options - use `--help` to get a detailed list of commands.

## Example usage: building and exporting the template study
## Example usage: building and exporting the core study

Let's walk through configuring and creating a template study in Athena. With
Let's walk through configuring and creating the core study in Athena. With
this completed, you'll be ready to move on to [Creating studies](./creating-studies.md)).

- First, follow the instructions in the readme of the
[Sample Database](https://github.com/smart-on-fhir/cumulus-library-sample-database),
if you haven't already. Our follown steps assume you use the default names and
if you haven't already. Our following steps assume you use the default names and
deploy in Amazon's US-East zone.
- Configure your system to talk to AWS as mentioned in the [AWS setup guide](./aws-setup.md)
- Now we'll build the tables we'll need to run the template study. The `core` study
- Now we'll build the tables we'll need to run the core study. The `core` study
creates tables for commonly used base FHIR resources like `Patient` and `Observation`.
To do this, run the following command:
```bash
Expand All @@ -72,28 +74,14 @@ You should see some progress bars like this while the tables are being created:
```
Creating core study in db... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
```
- Now, we'll build the built-in example `template` study.
Run a very similar command, but targeting `template` this time:
```bash
cumulus-library build --target template
```
This should be much faster - these tables will be created in around 15 seconds.
- You can use the AWS Athena console to view these tables directly, but you can also
download designated study artifacts. To do the latter, run the following command:
```bash
cumulus-library export --target template ./path/to/my/data/dir/
cumulus-library export --target core ./path/to/my/data/dir/
```
And this will download some example count aggregates to the `data_export` directory
inside of this repository. There's only a few tables, but this will give you an idea
of what kind of output to expect. Here's the first few lines:
```
cnt,influenza_lab_code,influenza_result_display,influenza_test_month
102,,,
70,,NEGATIVE (QUALIFIER VALUE),
70,"{code=92142-9, display=Influenza virus A RNA [Presence] in Respiratory specimen by NAA with probe detection, system=http://loinc.org}",,
70,"{code=92141-1, display=Influenza virus B RNA [Presence] in Respiratory specimen by NAA with probe detection, system=http://loinc.org}",,
69,"{code=92141-1, display=Influenza virus B RNA [Presence] in Respiratory specimen by NAA with probe detection, system=http://loinc.org}",NEGATIVE (QUALIFIER VALUE),
```
of what kind of output to expect.

## Next steps

Expand Down
20 changes: 17 additions & 3 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,10 +801,24 @@ def test_sql_error_handling(mock_backend, tmp_path):

@mock.patch.dict(os.environ, clear=True)
def test_version(capfd):
out = None
with pytest.raises(SystemExit):
cli.main(cli_args=["--version"])
out, _ = capfd.readouterr()
assert out == __version__
cli.main(
cli_args=[
"version",
"-s",
"tests/test_data/study_valid/",
"-s",
# TODO: Stand in for a 'study without an __init__.py defining a version
# consider a dedicated 'study_invalid_no_init' if we want to update all
# other test studies to have an __init__.py
"tests/test_data/study_invalid_bad_query/",
]
)
out, _ = capfd.readouterr()
assert f"cumulus-library version: {__version__}" in out
assert "study_valid: 1.0.0" in out
assert "study_invalid_bad_query: no version defined" in out


@mock.patch.dict(os.environ, clear=True)
Expand Down
1 change: 1 addition & 0 deletions tests/test_data/study_valid/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "1.0.0"

0 comments on commit fdae03e

Please sign in to comment.