nbintang
updated model
6752520
Raw
History Blame Contribute Delete
4.1 kB
from typing import Literal, Optional
from pydantic import BaseModel, Field, StrictBool, model_validator, StrictFloat
from api.schema.input_helpers import (
JOB_CATEGORY_MODEL,
age_category_map,
education_map,
map_customer_job,
)
class Education(BaseModel):
type: Literal["school", "university", "course", "illiterate"]
level: Optional[Literal["primary", "middle", "high"]] = None
grade: Optional[int] = None
@model_validator(mode="before")
def validate_education(cls, values):
type_ = values.get("type")
level = values.get("level")
grade = values.get("grade")
if type_ == "school":
if level is None or grade is None:
raise ValueError(
"For type 'school', both level and grade must be provided"
)
else:
if level is not None or grade is not None:
raise ValueError(
f"For type '{type_}', level and grade must not be provided"
)
return values
class PersonalInfo(BaseModel):
age: int = Field(..., ge=0, le=120)
job: Literal[
"blue_collar",
"housemaid",
"services",
"admin",
"technician",
"management",
"self_employed",
"entrepreneur",
"unemployed",
"student",
]
marital: Literal["married", "single"]
education: Education
# Derived fields
job_category: Optional[Literal["cat1", "cat2", "cat3", "cat4", "other"]] = None
age_category: Optional[
Literal[
"struggling",
"stable",
"about to retire",
"old age",
"counting a last breathe",
]
] = None
education_str: Optional[str] = None
@model_validator(mode="before")
def derive_categories(cls, values):
job_input = values.get("job")
age_input = values.get("age")
edu_dict = values.get("education")
job_model_name = map_customer_job(job_input)
job_cat = JOB_CATEGORY_MODEL.get(job_model_name, "other")
age_cat = age_category_map(age_input)
edu_type = edu_dict.get("type") if edu_dict else None
edu_level = edu_dict.get("level") if edu_dict else None
edu_grade = edu_dict.get("grade") if edu_dict else None
values["education_str"] = education_map(
type=edu_type, level=edu_level, grade=edu_grade
)
values["job_category"] = job_cat
values["age_category"] = age_cat
return values
class FinancialInfo(BaseModel):
default: StrictBool
housing: StrictBool
loan: StrictBool
@model_validator(mode="after")
def transform_bool_to_int(cls, values):
values.default = int(values.default)
values.housing = int(values.housing)
values.loan = int(values.loan)
return values
class ContactInfo(BaseModel):
contact: Literal["cellular", "telephone"]
day_of_week: Literal["mon", "tue", "wed", "thu", "fri"]
month: Literal[
"mar",
"apr",
"may",
"jun",
"jul",
"aug",
"sep",
"oct",
"nov",
"dec",
]
class CampaignInfo(BaseModel):
campaign: int = Field(..., ge=0)
previous: int = Field(..., ge=0)
poutcome: Literal["success", "failure", "nonexistent"]
class MacroInfo(BaseModel):
emp_var_rate: StrictFloat = Field(..., alias="employment_variation_rate")
euribor3m: StrictFloat = Field(..., alias="euribor_3m_rate")
nr_employed: StrictFloat = Field(..., alias="number_employed")
cons_price_idx: StrictFloat = Field(..., alias="consumer_price_index")
cons_conf_idx: float = Field(..., alias="consumer_confidence_index")
class InputData(BaseModel):
personal_info: PersonalInfo
financial_info: FinancialInfo
contact_info: ContactInfo
campaign_info: CampaignInfo
macro_info: MacroInfo