| from enum import Enum |
| from typing import Annotated, Literal, get_args, get_type_hints |
|
|
| import yaml |
| from pydantic import BaseModel, Field, StringConstraints |
|
|
|
|
| class InnerOp(Enum): |
| IN = "in" |
|
|
|
|
| class InnerRangeOp(Enum): |
| EQ = "=" |
| LT = "<" |
| GT = ">" |
| LE = "<=" |
| GE = ">=" |
|
|
|
|
| class MiddleOp(Enum): |
| AND = "and" |
|
|
|
|
| class OuterOp(Enum): |
| AND = "and" |
|
|
|
|
| class InnerAgeDxContent(BaseModel): |
| field: Literal["cases.diagnoses.age_at_diagnosis"] |
| value: Annotated[int, Field(ge=0, le=32872)] |
|
|
|
|
| class InnerYearDxContent(BaseModel): |
| field: Literal["cases.diagnoses.year_of_diagnosis"] |
| value: Annotated[int, Field(ge=1900, le=2050)] |
|
|
|
|
| class InnerCigDayContent(BaseModel): |
| field: Literal["cases.exposures.cigarettes_per_day"] |
| value: Annotated[int, Field(ge=0, le=999999)] |
|
|
|
|
| class InnerPackYrContent(BaseModel): |
| field: Literal["cases.exposures.pack_years_smoked"] |
| value: Annotated[int, Field(ge=0, le=999999)] |
|
|
|
|
| class InnerCigStrtContent(BaseModel): |
| field: Literal["cases.exposures.tobacco_smoking_onset_year"] |
| value: Annotated[int, Field(ge=1900, le=2050)] |
|
|
|
|
| excluded_values = set() |
| for alt_inner in [ |
| InnerYearDxContent, |
| InnerCigDayContent, |
| InnerPackYrContent, |
| InnerCigStrtContent, |
| ]: |
| field_type = get_type_hints(alt_inner)["field"] |
| excluded_values |= set(get_args(field_type)) |
|
|
|
|
| with open("config.yaml", "r") as f: |
| CONFIG = yaml.safe_load(f) |
| all_other_fields = tuple( |
| [ |
| card["field"] |
| for tab in CONFIG["tabs"] |
| for card in tab["cards"] |
| if card["field"] not in excluded_values |
| ] |
| ) |
|
|
|
|
| class InnerStrContent(BaseModel): |
| field: Literal[all_other_fields] |
| value: list[Annotated[str, StringConstraints(min_length=1, max_length=128)]] |
|
|
|
|
| class Inner(BaseModel): |
| op: InnerOp |
| content: InnerStrContent |
|
|
|
|
| class InnerRange(BaseModel): |
| op: InnerRangeOp |
| content: ( |
| InnerAgeDxContent |
| | InnerYearDxContent |
| | InnerCigDayContent |
| | InnerPackYrContent |
| | InnerCigStrtContent |
| ) |
|
|
|
|
| class Middle(BaseModel): |
| op: MiddleOp |
| content: list[Inner | InnerRange] |
|
|
|
|
| class GDCCohortSchema(BaseModel): |
| op: OuterOp |
| content: list[Middle | Inner | InnerRange] |
|
|