Skip to content

Commit 0eef897

Browse files
authored
refactor: Move feature flags to FeatureFlag enum. (#1002)
* refactor: Move feature flags out of environment to their own dataclass * lint: ruff * ruff
1 parent 81015b2 commit 0eef897

13 files changed

+72
-53
lines changed

v03_pipeline/bin/pipeline_worker.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from v03_pipeline.api.model import LoadingPipelineRequest
99
from v03_pipeline.lib.logger import get_logger
10-
from v03_pipeline.lib.model import Env
10+
from v03_pipeline.lib.model import FeatureFlag
1111
from v03_pipeline.lib.paths import (
1212
loading_pipeline_queue_path,
1313
project_pedigree_path,
@@ -54,7 +54,7 @@ def main():
5454
'run_id': run_id,
5555
**{k: v for k, v in lpr.model_dump().items() if k != 'projects_to_run'},
5656
}
57-
if Env.SHOULD_TRIGGER_HAIL_BACKEND_RELOAD:
57+
if FeatureFlag.SHOULD_TRIGGER_HAIL_BACKEND_RELOAD:
5858
tasks = [
5959
TriggerHailBackendReload(**loading_run_task_params),
6060
]

v03_pipeline/lib/model/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
Sex,
88
)
99
from v03_pipeline.lib.model.environment import Env
10+
from v03_pipeline.lib.model.feature_flag import FeatureFlag
1011

1112
__all__ = [
1213
'AccessControl',
1314
'DatasetType',
1415
'Env',
16+
'FeatureFlag',
1517
'Sex',
1618
'PipelineVersion',
1719
'ReferenceGenome',

v03_pipeline/lib/model/environment.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,30 +51,12 @@
5151
GCLOUD_REGION = os.environ.get('GCLOUD_REGION')
5252
PIPELINE_RUNNER_APP_VERSION = os.environ.get('PIPELINE_RUNNER_APP_VERSION', 'latest')
5353

54-
# Feature Flags
55-
ACCESS_PRIVATE_REFERENCE_DATASETS = (
56-
os.environ.get('ACCESS_PRIVATE_REFERENCE_DATASETS') == '1'
57-
)
58-
CHECK_SEX_AND_RELATEDNESS = os.environ.get('CHECK_SEX_AND_RELATEDNESS') == '1'
59-
EXPECT_TDR_METRICS = os.environ.get('EXPECT_TDR_METRICS') == '1'
60-
EXPECT_WES_FILTERS = os.environ.get('EXPECT_WES_FILTERS') == '1'
61-
INCLUDE_PIPELINE_VERSION_IN_PREFIX = (
62-
os.environ.get('INCLUDE_PIPELINE_VERSION_IN_PREFIX') == '1'
63-
)
64-
SHOULD_TRIGGER_HAIL_BACKEND_RELOAD = (
65-
os.environ.get('SHOULD_TRIGGER_HAIL_BACKEND_RELOAD') == '1'
66-
)
67-
6854

6955
@dataclass
7056
class Env:
71-
ACCESS_PRIVATE_REFERENCE_DATASETS: bool = ACCESS_PRIVATE_REFERENCE_DATASETS
72-
CHECK_SEX_AND_RELATEDNESS: bool = CHECK_SEX_AND_RELATEDNESS
7357
CLINGEN_ALLELE_REGISTRY_LOGIN: str | None = CLINGEN_ALLELE_REGISTRY_LOGIN
7458
CLINGEN_ALLELE_REGISTRY_PASSWORD: str | None = CLINGEN_ALLELE_REGISTRY_PASSWORD
7559
DEPLOYMENT_TYPE: Literal['dev', 'prod'] = DEPLOYMENT_TYPE
76-
EXPECT_TDR_METRICS: bool = EXPECT_TDR_METRICS
77-
EXPECT_WES_FILTERS: bool = EXPECT_WES_FILTERS
7860
GCLOUD_DATAPROC_SECONDARY_WORKERS: str = GCLOUD_DATAPROC_SECONDARY_WORKERS
7961
GCLOUD_PROJECT: str | None = GCLOUD_PROJECT
8062
GCLOUD_ZONE: str | None = GCLOUD_ZONE
@@ -85,10 +67,8 @@ class Env:
8567
HAIL_BACKEND_SERVICE_PORT: int = HAIL_BACKEND_SERVICE_PORT
8668
HAIL_TMP_DIR: str = HAIL_TMP_DIR
8769
HAIL_SEARCH_DATA_DIR: str = HAIL_SEARCH_DATA_DIR
88-
INCLUDE_PIPELINE_VERSION_IN_PREFIX: bool = INCLUDE_PIPELINE_VERSION_IN_PREFIX
8970
LOADING_DATASETS_DIR: str = LOADING_DATASETS_DIR
9071
PIPELINE_RUNNER_APP_VERSION: str = PIPELINE_RUNNER_APP_VERSION
9172
PRIVATE_REFERENCE_DATASETS_DIR: str = PRIVATE_REFERENCE_DATASETS_DIR
9273
REFERENCE_DATASETS_DIR: str = REFERENCE_DATASETS_DIR
93-
SHOULD_TRIGGER_HAIL_BACKEND_RELOAD: bool = SHOULD_TRIGGER_HAIL_BACKEND_RELOAD
9474
VEP_REFERENCE_DATASETS_DIR: str = VEP_REFERENCE_DATASETS_DIR
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import os
2+
from dataclasses import dataclass
3+
4+
# Feature Flags
5+
ACCESS_PRIVATE_REFERENCE_DATASETS = (
6+
os.environ.get('ACCESS_PRIVATE_REFERENCE_DATASETS') == '1'
7+
)
8+
CHECK_SEX_AND_RELATEDNESS = os.environ.get('CHECK_SEX_AND_RELATEDNESS') == '1'
9+
EXPECT_TDR_METRICS = os.environ.get('EXPECT_TDR_METRICS') == '1'
10+
EXPECT_WES_FILTERS = os.environ.get('EXPECT_WES_FILTERS') == '1'
11+
INCLUDE_PIPELINE_VERSION_IN_PREFIX = (
12+
os.environ.get('INCLUDE_PIPELINE_VERSION_IN_PREFIX') == '1'
13+
)
14+
SHOULD_TRIGGER_HAIL_BACKEND_RELOAD = (
15+
os.environ.get('SHOULD_TRIGGER_HAIL_BACKEND_RELOAD') == '1'
16+
)
17+
18+
19+
@dataclass
20+
class FeatureFlag:
21+
ACCESS_PRIVATE_REFERENCE_DATASETS: bool = ACCESS_PRIVATE_REFERENCE_DATASETS
22+
CHECK_SEX_AND_RELATEDNESS: bool = CHECK_SEX_AND_RELATEDNESS
23+
EXPECT_TDR_METRICS: bool = EXPECT_TDR_METRICS
24+
EXPECT_WES_FILTERS: bool = EXPECT_WES_FILTERS
25+
INCLUDE_PIPELINE_VERSION_IN_PREFIX: bool = INCLUDE_PIPELINE_VERSION_IN_PREFIX
26+
SHOULD_TRIGGER_HAIL_BACKEND_RELOAD: bool = SHOULD_TRIGGER_HAIL_BACKEND_RELOAD

v03_pipeline/lib/paths.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
AccessControl,
77
DatasetType,
88
Env,
9+
FeatureFlag,
910
PipelineVersion,
1011
ReferenceGenome,
1112
SampleType,
@@ -21,7 +22,7 @@ def _pipeline_prefix(
2122
reference_genome: ReferenceGenome,
2223
dataset_type: DatasetType,
2324
) -> str:
24-
if Env.INCLUDE_PIPELINE_VERSION_IN_PREFIX:
25+
if FeatureFlag.INCLUDE_PIPELINE_VERSION_IN_PREFIX:
2526
return os.path.join(
2627
root,
2728
PipelineVersion.V3_1.value,
@@ -45,7 +46,7 @@ def _v03_reference_data_prefix(
4546
if access_control == AccessControl.PRIVATE
4647
else Env.REFERENCE_DATASETS_DIR
4748
)
48-
if Env.INCLUDE_PIPELINE_VERSION_IN_PREFIX:
49+
if FeatureFlag.INCLUDE_PIPELINE_VERSION_IN_PREFIX:
4950
return os.path.join(
5051
root,
5152
PipelineVersion.V03.value,
@@ -68,7 +69,7 @@ def _v03_reference_dataset_prefix(
6869
if access_control == AccessControl.PRIVATE
6970
else Env.REFERENCE_DATASETS_DIR
7071
)
71-
if Env.INCLUDE_PIPELINE_VERSION_IN_PREFIX:
72+
if FeatureFlag.INCLUDE_PIPELINE_VERSION_IN_PREFIX:
7273
return os.path.join(
7374
root,
7475
PipelineVersion.V3_1.value,
@@ -287,7 +288,7 @@ def valid_filters_path(
287288
callset_path: str,
288289
) -> str | None:
289290
if (
290-
not Env.EXPECT_WES_FILTERS
291+
not FeatureFlag.EXPECT_WES_FILTERS
291292
or not dataset_type.expect_filters(sample_type)
292293
or 'part_one_outputs' not in callset_path
293294
):

v03_pipeline/lib/paths_test.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ def test_family_table_path(self) -> None:
3636
),
3737
'/var/seqr/seqr-hail-search-data/v3.1/GRCh37/SNV_INDEL/families/WES/franklin.ht',
3838
)
39-
with patch('v03_pipeline.lib.paths.Env') as mock_env:
39+
with patch('v03_pipeline.lib.paths.Env') as mock_env, patch(
40+
'v03_pipeline.lib.paths.FeatureFlag',
41+
) as mock_ff:
4042
mock_env.HAIL_SEARCH_DATA_DIR = 'gs://seqr-datasets/'
4143
self.assertEqual(
4244
family_table_path(
@@ -47,7 +49,7 @@ def test_family_table_path(self) -> None:
4749
),
4850
'gs://seqr-datasets/v3.1/GRCh37/SNV_INDEL/families/WES/franklin.ht',
4951
)
50-
mock_env.INCLUDE_PIPELINE_VERSION_IN_PREFIX = False
52+
mock_ff.INCLUDE_PIPELINE_VERSION_IN_PREFIX = False
5153
self.assertEqual(
5254
family_table_path(
5355
ReferenceGenome.GRCh37,
@@ -67,8 +69,8 @@ def test_valid_filters_path(self) -> None:
6769
),
6870
None,
6971
)
70-
with patch('v03_pipeline.lib.paths.Env') as mock_env:
71-
mock_env.EXPECT_WES_FILTERS = True
72+
with patch('v03_pipeline.lib.paths.FeatureFlag') as mock_ff:
73+
mock_ff.EXPECT_WES_FILTERS = True
7274
self.assertEqual(
7375
valid_filters_path(
7476
DatasetType.SNV_INDEL,

v03_pipeline/lib/reference_datasets/reference_dataset.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010
validate_allele_type,
1111
validate_no_duplicate_variants,
1212
)
13-
from v03_pipeline.lib.model import AccessControl, DatasetType, Env, ReferenceGenome
13+
from v03_pipeline.lib.model import (
14+
AccessControl,
15+
DatasetType,
16+
FeatureFlag,
17+
ReferenceGenome,
18+
)
1419
from v03_pipeline.lib.reference_datasets import clinvar, dbnsfp
1520
from v03_pipeline.lib.reference_datasets.misc import (
1621
compress_floats,
@@ -41,7 +46,7 @@ def for_reference_genome_dataset_type(
4146
for dataset, config in CONFIG.items()
4247
if dataset_type in config.get(reference_genome, {}).get(DATASET_TYPES, [])
4348
]
44-
if not Env.ACCESS_PRIVATE_REFERENCE_DATASETS:
49+
if not FeatureFlag.ACCESS_PRIVATE_REFERENCE_DATASETS:
4550
return {
4651
dataset
4752
for dataset in reference_datasets

v03_pipeline/lib/tasks/dataproc/create_dataproc_cluster.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from v03_pipeline.lib.logger import get_logger
99
from v03_pipeline.lib.misc.gcp import get_service_account_credentials
10-
from v03_pipeline.lib.model import Env, ReferenceGenome
10+
from v03_pipeline.lib.model import Env, FeatureFlag, ReferenceGenome
1111
from v03_pipeline.lib.tasks.base.base_loading_pipeline_params import (
1212
BaseLoadingPipelineParams,
1313
)
@@ -88,18 +88,21 @@ def get_cluster_config(reference_genome: ReferenceGenome, run_id: str):
8888
'spark:spark.executorEnv.HAIL_WORKER_OFF_HEAP_MEMORY_PER_CORE_MB': '6323',
8989
'spark:spark.speculation': 'true',
9090
'spark-env:ACCESS_PRIVATE_REFERENCE_DATASETS': '1'
91-
if Env.ACCESS_PRIVATE_REFERENCE_DATASETS
91+
if FeatureFlag.ACCESS_PRIVATE_REFERENCE_DATASETS
9292
else '0',
9393
'spark-env:CHECK_SEX_AND_RELATEDNESS': '1'
94-
if Env.CHECK_SEX_AND_RELATEDNESS
94+
if FeatureFlag.CHECK_SEX_AND_RELATEDNESS
95+
else '0',
96+
'spark-env:EXPECT_TDR_METRICS': '1'
97+
if FeatureFlag.EXPECT_TDR_METRICS
9598
else '0',
9699
'spark-env:EXPECT_WES_FILTERS': '1'
97-
if Env.EXPECT_WES_FILTERS
100+
if FeatureFlag.EXPECT_WES_FILTERS
98101
else '0',
99102
'spark-env:HAIL_SEARCH_DATA_DIR': Env.HAIL_SEARCH_DATA_DIR,
100103
'spark-env:HAIL_TMP_DIR': Env.HAIL_TMP_DIR,
101104
'spark-env:INCLUDE_PIPELINE_VERSION_IN_PREFIX': '1'
102-
if Env.INCLUDE_PIPELINE_VERSION_IN_PREFIX
105+
if FeatureFlag.INCLUDE_PIPELINE_VERSION_IN_PREFIX
103106
else '0',
104107
'spark-env:LOADING_DATASETS_DIR': Env.LOADING_DATASETS_DIR,
105108
'spark-env:PRIVATE_REFERENCE_DATASETS_DIR': Env.PRIVATE_REFERENCE_DATASETS_DIR,

v03_pipeline/lib/tasks/update_variant_annotations_table_with_new_samples_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ def test_update_vat_grch37(
712712
@patch(
713713
'v03_pipeline.lib.tasks.write_new_variants_table.UpdateVariantAnnotationsTableWithUpdatedReferenceDataset',
714714
)
715-
@patch('v03_pipeline.lib.reference_datasets.reference_dataset.Env')
715+
@patch('v03_pipeline.lib.reference_datasets.reference_dataset.FeatureFlag')
716716
@patch('v03_pipeline.lib.vep.hl.vep')
717717
@patch(
718718
'v03_pipeline.lib.tasks.write_new_variants_table.load_gencode_ensembl_to_refseq_id',
@@ -721,7 +721,7 @@ def test_update_vat_without_accessing_private_datasets(
721721
self,
722722
mock_load_gencode_ensembl_to_refseq_id: Mock,
723723
mock_vep: Mock,
724-
mock_rd_env: Mock,
724+
mock_rd_ff: Mock,
725725
mock_update_vat_with_rd_task: Mock,
726726
mock_register_alleles: Mock,
727727
) -> None:
@@ -740,7 +740,7 @@ def test_update_vat_without_accessing_private_datasets(
740740
ReferenceDataset.hgmd,
741741
),
742742
)
743-
mock_rd_env.ACCESS_PRIVATE_REFERENCE_DATASETS = False
743+
mock_rd_ff.ACCESS_PRIVATE_REFERENCE_DATASETS = False
744744
mock_vep.side_effect = lambda ht, **_: ht.annotate(vep=MOCK_38_VEP_DATA)
745745
mock_register_alleles.side_effect = None
746746

v03_pipeline/lib/tasks/validate_callset.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
validate_no_duplicate_variants,
1111
validate_sample_type,
1212
)
13-
from v03_pipeline.lib.model.environment import Env
13+
from v03_pipeline.lib.model.feature_flag import FeatureFlag
1414
from v03_pipeline.lib.paths import (
1515
imported_callset_path,
1616
sex_check_table_path,
@@ -41,7 +41,7 @@ def get_validation_dependencies(self) -> dict[str, hl.Table]:
4141
),
4242
)
4343
if (
44-
Env.CHECK_SEX_AND_RELATEDNESS
44+
FeatureFlag.CHECK_SEX_AND_RELATEDNESS
4545
and self.dataset_type.check_sex_and_relatedness
4646
and not self.skip_check_sex_and_relatedness
4747
):
@@ -86,7 +86,7 @@ def requires(self) -> list[luigi.Task]:
8686
),
8787
]
8888
if (
89-
Env.CHECK_SEX_AND_RELATEDNESS
89+
FeatureFlag.CHECK_SEX_AND_RELATEDNESS
9090
and self.dataset_type.check_sex_and_relatedness
9191
and not self.skip_check_sex_and_relatedness
9292
):

0 commit comments

Comments
 (0)