-
Notifications
You must be signed in to change notification settings - Fork 28
Bulk FHIR Gen 3 Authorization Tagging #313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dsafarian
wants to merge
39
commits into
uc-cdis:master
Choose a base branch
from
dsafarian:fhir_transform
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
fdc70f1
Added cli/fhir_transform.py and transform_utils.py
dsafarian 134df13
Add fhir_transform cli, utils, and tests
dsafarian 92d603e
Remove unnecessary imports
dsafarian 44940a9
Add documentation, format tests, integrate into gen3 cli, add test_da…
dsafarian aab4d54
Fix and add tests, create folder even if output_file path doesn't exist
dsafarian c66e855
Pass all tests, modify multiprocessing to not cause issues with gen3,…
dsafarian 404be39
test md
dsafarian 8899bef
Add fhir.md
dsafarian 2d2e6fe
Merge branch 'uc-cdis:master' into fhir_transform
dsafarian 3f861f6
Black formatting
dsafarian 80f1315
black formatting
dsafarian d8ae042
Fix pull request comments
dsafarian 76c6797
Delete test outputs
dsafarian a34ed6c
Remove setuptools dependency from pyproject.toml
dsafarian d929fd2
Fix pyproject.toml dependencies and poetry.lock
dsafarian 8e0174c
Remove FIXME
dsafarian 6192216
Fix default working directory and directory creation, imports, rename…
dsafarian 6b5f319
Remove test outputs, fix typos, add assertions, change to SHA-256 has…
dsafarian d00ecf5
Fix hash bug
dsafarian 8339418
Add unit test for global authz and fix tmp_path
dsafarian 9cbf8ba
Comment out all parrallelization code
dsafarian 8f5eee5
Remove _resume_run from all code
dsafarian 9cdf886
Fix exception handling
dsafarian 818c537
Fix resource_type check
dsafarian dd2abb2
Use fhirpathpy.compile instead of fhirpathpy.evaluate for speed up.
dsafarian 157eb94
Add check for if output file exists and is not empty for _is_new.
dsafarian d7773f6
Fix poetry dependencies
dsafarian 82e8710
Remove all parallelization code and make fhir import optional in cli
dsafarian 9c42dd7
Add helper function for tag_fhir_resources_with_authz and fix tmp_roo…
dsafarian a9a0418
Black formatting
dsafarian 7b942b0
fix(drsclient): remove dep due to out of date sub-deps, implement DRS…
Avantol13 69279e0
Merge branch 'master' into fhir_transform
Avantol13 df146ee
Update docs/howto/fhir.md
dsafarian ece2a0a
Update fhir.md
dsafarian 3d340b2
Update fhir.md
dsafarian 8b86006
Update fhir.md
dsafarian 50ae4e1
Fix commands for optional fhir import
dsafarian d248015
Fix paths in .config.json for fhir unit test and the pyproject.toml
dsafarian 0591c06
Black formatting
dsafarian File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| ## FHIR | ||
|
|
||
| This integration aims to enhance the data ingestion capabilities of Gen3 by integrating a Fast Healthcare Interoperability Resources (FHIR) data ingestion tools. FHIR is an important standard for working with Electronic Health Records (EHR) and we have started development of a Gen3 FHIR Proxy service. | ||
|
|
||
| Gen3 is working on adding support for FHIR and these tools will help with data preparation. | ||
|
|
||
|
|
||
| The fhir commands can be invoked as follows | ||
|
|
||
| `gen3 fhir COMMAND [ARGS] [OPTIONS]` | ||
|
|
||
| For a list of commands and options run | ||
|
|
||
| `gen3 fhir --help` | ||
|
|
||
| For example, the following tags the 'Patient.ndjson' file with Gen3 authorization and outputs 'gen3_Patient.ndjson' using the authorization rules from 'config.yaml' | ||
|
dsafarian marked this conversation as resolved.
|
||
|
|
||
| `gen3 fhir transform Patient.ndjson gen3_Patient.ndjson config.yaml --batch_size 10000` | ||
|
|
||
|
|
||
| The authorization configuration file has to be in yaml format and can have multiple conditions, e.g: | ||
|
|
||
| ```yaml | ||
| rules: | ||
| - resource_type: "Patient" | ||
| condition: "Patient.managingOrganization.reference = 'Organization/site-alpha'" | ||
| authz: "/programs/Alpha/projects/Main" | ||
|
|
||
| #Example with multiple conditions | ||
| - resource_type: "Specimen" | ||
| condition: "Specimen.status = 'available' and Specimen.Type = 'Blood specimen (specimen)'" | ||
| authz: "/programs/Alpha/projects/Biobank" | ||
| ``` | ||
|
|
||
| And example config.yaml file can be found in [fhir_config.yaml](../../tests/test_data/fhir_config.yaml) | ||
| To run the fhir transfrom with synthetic test data: | ||
|
|
||
| `poetry run gen3 -vv fhir transform ./tests/test_data/Patient.ndjson ./test_Patient.ndjson ./tests/test_data/fhir_config.yaml` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| import click | ||
| import os | ||
| import pathlib | ||
| from cdislogging import get_logger | ||
| from gen3.fhir import * | ||
|
|
||
| logging = get_logger(__name__) | ||
|
|
||
|
|
||
| @click.group() | ||
| def fhir(): | ||
| """Commands for FHIR data processing""" | ||
| pass | ||
|
|
||
|
|
||
| @click.command( | ||
| context_settings={"help_option_names": ["-h", "--help"]}, | ||
| help="""Tag Bulk FHIR data with Gen3 compatible authorization tags. | ||
|
|
||
| \b | ||
| input_file (str): Input .ndjson file with Bulk FHIR data, MUST be one resource type per file | ||
| output_file (str): Output file name, also an .ndjson file | ||
| config (str): .yaml file with authorization rules, see docs/howto/fhir.md for more details on formatting | ||
| """, | ||
| ) | ||
| @click.argument( | ||
| "input_file", | ||
| type=click.Path(exists=True, dir_okay=False, readable=True), | ||
| metavar="input_file", | ||
| ) | ||
| @click.argument( | ||
| "output_file", type=click.Path(dir_okay=False, writable=True), metavar="output_file" | ||
| ) | ||
| @click.argument( | ||
| "config", | ||
| type=click.Path(exists=True, dir_okay=False, readable=True), | ||
| metavar="config", | ||
| ) | ||
| @click.option( | ||
| "--work_dir", | ||
| type=click.Path(), | ||
| metavar="work_dir", | ||
| help=f"Specify which working directory to clean, if not specified the default ({DEFAULT_WORK_DIR}) will be used. Can also be set as an environment variable: GEN3_FHIR_WORK_DIR", | ||
| ) | ||
| @click.option( | ||
| "-b", | ||
| "--batch_size", | ||
| type=click.IntRange(min=1), | ||
| default=10000, | ||
| show_default=True, | ||
| metavar="batch_size", | ||
| help="batch size for chunking", | ||
| ) | ||
| @click.option( | ||
| "--force", | ||
| is_flag=True, | ||
| help="Remove all intermediate files for this run before exiting even if run crashes", | ||
| ) | ||
| def cli( | ||
| input_file: str | os.PathLike[str], | ||
| output_file: str | os.PathLike[str], | ||
| config: str | os.PathLike[str], | ||
| work_dir: str | os.PathLike[str] | None, | ||
| batch_size: int, | ||
| force: bool, | ||
| ): | ||
| """ | ||
| CLI implementation of tag_fhir_resources_with_authz. | ||
|
|
||
| Args: | ||
| input_file (str): Input .ndjson file | ||
| output_file (str): Output file name | ||
| config (str): .yaml file with authorization rules | ||
| work_dir (str): Working directory to save intermediate files for each run | ||
| batch_size (int): number of lines per chunk | ||
| force (bool): remove all intermediate files for this run before exiting even if it crashes | ||
| """ | ||
| tag_fhir_resources_with_authz( | ||
| input_file=input_file, | ||
| output_file=output_file, | ||
| config=config, | ||
| batch_size=batch_size, | ||
| work_dir=work_dir, | ||
| force=force, | ||
| ) | ||
|
|
||
|
|
||
| @click.command( | ||
| context_settings={"help_option_names": ["-h", "--help"]}, | ||
| help="Remove all intermediate files in the tmp folder from previous runs", | ||
| ) | ||
| @click.option( | ||
| "--work_dir", | ||
| type=click.Path(), | ||
| metavar="work_dir", | ||
| help=f"Specify which working directory to clean, if not specified the default ({DEFAULT_WORK_DIR}) will be cleaned. Can also be set as an environment variable: GEN3_FHIR_WORK_DIR", | ||
| ) | ||
| @click.option( | ||
| "--dry-run", | ||
| is_flag=True, | ||
| help="Report what would be deleted with --cleanup without deleting the files", | ||
| ) | ||
| @click.option( | ||
| "--force", | ||
| is_flag=True, | ||
| help="Remove temporary directory ignoring status of each directory", | ||
| ) | ||
| def cleanup(work_dir, dry_run: bool, force: bool): | ||
| """ | ||
| Remove all intermediate files in the tmp folder from previous runs | ||
|
|
||
| Args: | ||
| work_dir (str): Working directory to save intermediate files for each run | ||
| dry_run (bool): If True, list the files that would be removed, but not actually remove them | ||
| force (bool): Delete all intermediate directories disregarding the status | ||
| """ | ||
|
|
||
| cleanup_fhir_transform_artifacts(work_dir=work_dir, dry_run=dry_run, force=force) | ||
|
|
||
|
|
||
| fhir.add_command(cli, name="transform") | ||
| fhir.add_command(cleanup, name="cleanup") |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.