DEVALIDATION OF VALIDATION
This commit is contained in:
@ -38,4 +38,4 @@ class GameDecisionResponseWithBotDecisionDTO(BaseModel):
|
||||
client_id: Optional[UUID] = None
|
||||
client_data: Optional[Dict[str, Any]] = None
|
||||
bot_decision: Literal["Accept", "Reject"]
|
||||
bot_reason: str
|
||||
bot_reason: Optional[str]
|
@ -1,43 +1,56 @@
|
||||
from typing import Literal, Optional, Self
|
||||
from pydantic import BaseModel, ConfigDict, EmailStr, Field, model_validator
|
||||
from pydantic_extra_types.phone_numbers import PhoneNumber
|
||||
from typing import Optional # Removed Literal, Self
|
||||
from pydantic import BaseModel, ConfigDict # Removed Field, model_validator
|
||||
# Removed PhoneNumber import as it's not used and types are simplified
|
||||
|
||||
class FromAccount(BaseModel):
|
||||
"""
|
||||
Fields which can be extracted from account.pdf
|
||||
Fields which can be extracted from account.pdf - All fields optional and simplified to string.
|
||||
Validators removed for testing purposes.
|
||||
"""
|
||||
model_config = ConfigDict(validate_assignment=True, str_strip_whitespace=True)
|
||||
|
||||
# Details of the Account and Client
|
||||
account_name: str = Field(min_length=1)
|
||||
account_holder_name: str = Field(min_length=1)
|
||||
account_holder_surname: str = Field(min_length=1)
|
||||
account_name: Optional[str] = None
|
||||
account_holder_name: Optional[str] = None
|
||||
account_holder_surname: Optional[str] = None
|
||||
|
||||
@model_validator(mode='after')
|
||||
def check_account_name_is_name_surname(self) -> Self:
|
||||
combined = f"{self.account_holder_name} {self.account_holder_surname}"
|
||||
if combined != self.account_name:
|
||||
raise ValueError(f'Account name is not name + surname: {self.account_name} != {combined}')
|
||||
return self
|
||||
# --- Updated Validator 1 ---
|
||||
# @model_validator(mode='after')
|
||||
# def check_account_name_is_name_surname(self) -> Self:
|
||||
# # Only validate if all relevant fields are present
|
||||
# if self.account_holder_name is not None and \
|
||||
# self.account_holder_surname is not None and \
|
||||
# self.account_name is not None:
|
||||
# combined = f"{self.account_holder_name} {self.account_holder_surname}"
|
||||
# if combined != self.account_name:
|
||||
# raise ValueError(f'Account name is not name + surname: {self.account_name} != {combined}')
|
||||
# return self
|
||||
|
||||
passport_number: str = Field(min_length=5)
|
||||
passport_number: Optional[str] = None # Removed Field constraint
|
||||
|
||||
reference_currency: Literal["CHF", "EUR", "USD", "Other"]
|
||||
reference_currency: Optional[str] = None # Simplified from Literal
|
||||
other_currency: Optional[str] = None
|
||||
|
||||
# Delivery of Communication
|
||||
building_number: str = Field(min_length=1)
|
||||
street_name: str = Field(min_length=1)
|
||||
postal_code: str = Field(min_length=1)
|
||||
city: str = Field(min_length=1)
|
||||
country: str = Field(min_length=1)
|
||||
building_number: Optional[str] = None
|
||||
street_name: Optional[str] = None
|
||||
postal_code: Optional[str] = None
|
||||
city: Optional[str] = None
|
||||
country: Optional[str] = None
|
||||
|
||||
# Application for e-banking
|
||||
ebanking_name: str = Field(min_length=1)
|
||||
@model_validator(mode='after')
|
||||
def check_account_name_ebanking_name(self) -> Self:
|
||||
if self.ebanking_name != self.account_name:
|
||||
raise ValueError(f'Ebanking name is different from account name')
|
||||
return self
|
||||
phone_number: str = Field(..., min_length=8)
|
||||
email: str = Field(min_length=5)
|
||||
ebanking_name: Optional[str] = None
|
||||
|
||||
# --- Updated Validator 2 ---
|
||||
# @model_validator(mode='after')
|
||||
# def check_account_name_ebanking_name(self) -> Self:
|
||||
# # Only validate if both fields are present
|
||||
# if self.ebanking_name is not None and self.account_name is not None:
|
||||
# if self.ebanking_name != self.account_name:
|
||||
# raise ValueError(f'Ebanking name ({self.ebanking_name}) is different from account name ({self.account_name})')
|
||||
# return self
|
||||
|
||||
# Kept as Optional[str], but you might consider Optional[PhoneNumber]
|
||||
# if you want specific phone number validation using pydantic-extra-types
|
||||
phone_number: Optional[str] = None # Removed Field constraint
|
||||
email: Optional[str] = None # Removed Field constraint
|
@ -1,35 +1,32 @@
|
||||
from typing import Literal
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from typing import Optional # Removed Literal
|
||||
from pydantic import BaseModel, ConfigDict # Removed Field
|
||||
|
||||
|
||||
class FromDescription(BaseModel):
|
||||
"""
|
||||
Fields which can be extracted from description.txt
|
||||
Fields which can be extracted from description.txt - All fields optional and simplified to string.
|
||||
"""
|
||||
model_config = ConfigDict(validate_assignment=True, str_strip_whitespace=True)
|
||||
|
||||
full_name: Optional[str] = None
|
||||
age: Optional[str] = None # Simplified from int
|
||||
nationality: Optional[str] = None
|
||||
marital_status: Optional[str] = None # Simplified from Literal
|
||||
has_children: Optional[str] = None # Simplified from bool
|
||||
|
||||
full_name: str = Field(..., min_length=1)
|
||||
age: int = Field(..., ge=0, le=120)
|
||||
nationality: str = Field(..., min_length=1)
|
||||
secondary_education_school: Optional[str] = None
|
||||
secondary_education_year: Optional[str] = None # Simplified from int
|
||||
university_name: Optional[str] = None
|
||||
university_graduation_year: Optional[str] = None # Simplified from int
|
||||
|
||||
marital_status: Literal["single", "married", "divorced", "widowed"]
|
||||
has_children: bool
|
||||
occupation_title: Optional[str] = None
|
||||
employer: Optional[str] = None
|
||||
start_year: Optional[str] = None # Simplified from int
|
||||
annual_salary_eur: Optional[str] = None # Simplified from float
|
||||
|
||||
secondary_education_school: str
|
||||
secondary_education_year: int = Field(..., ge=1900, le=2100)
|
||||
university_name: str
|
||||
university_graduation_year: int = Field(..., ge=1900, le=2100)
|
||||
|
||||
occupation_title: str
|
||||
employer: str
|
||||
start_year: int = Field(..., ge=1900, le=2100)
|
||||
annual_salary_eur: float = Field(..., ge=0)
|
||||
|
||||
total_savings_eur: float = Field(..., ge=0)
|
||||
has_properties: bool
|
||||
|
||||
inheritance_amount_eur: float = Field(..., ge=0)
|
||||
inheritance_year: int = Field(..., ge=1900, le=2100)
|
||||
inheritance_source: str
|
||||
total_savings_eur: Optional[str] = None # Simplified from float
|
||||
has_properties: Optional[str] = None # Simplified from bool
|
||||
|
||||
inheritance_amount_eur: Optional[str] = None # Simplified from float
|
||||
inheritance_year: Optional[str] = None # Simplified from int
|
||||
inheritance_source: Optional[str] = None
|
@ -10,61 +10,22 @@ class FromPassport(BaseModel):
|
||||
"""
|
||||
model_config = ConfigDict(validate_assignment=True, str_strip_whitespace=True)
|
||||
|
||||
country: str = Field(
|
||||
...,
|
||||
min_length=3,
|
||||
max_length=3,
|
||||
description="The country issuing the passport, as a 3-letter ISO 3166-1 alpha-3 code (e.g., 'CHE' for Switzerland)."
|
||||
)
|
||||
country: Optional[str] = None
|
||||
passport_number: Optional[str] = None
|
||||
surname: Optional[str] = None
|
||||
given_names: Optional[str] = None
|
||||
birth_date: Optional[str] = None # Simplified from date
|
||||
citizenship: Optional[str] = None
|
||||
sex: Optional[str] = None # Simplified from Literal
|
||||
issue_date: Optional[str] = None # Simplified from date
|
||||
expiry_date: Optional[str] = None # Simplified from date
|
||||
|
||||
passport_number: str = Field(
|
||||
...,
|
||||
min_length=9,
|
||||
max_length=9,
|
||||
pattern=r"^[A-Z0-9]{9}$",
|
||||
description="The passport number, exactly 9 alphanumeric uppercase characters."
|
||||
)
|
||||
|
||||
surname: str = Field(
|
||||
...,
|
||||
min_length=1,
|
||||
description="The surname (family name) of the passport holder."
|
||||
)
|
||||
|
||||
given_names: str = Field(
|
||||
...,
|
||||
min_length=1,
|
||||
description="The given names (first and middle names) of the passport holder."
|
||||
)
|
||||
|
||||
@model_validator(mode='after')
|
||||
def check_expiry_date_after_issue_date(self) -> Self:
|
||||
if self.issue_date >= self.expiry_date:
|
||||
raise ValueError(f'Expiry date is not after issue date')
|
||||
return self
|
||||
|
||||
birth_date: date = Field(
|
||||
...,
|
||||
description="Date of birth of the passport holder in ISO format (YYYY-MM-DD)."
|
||||
)
|
||||
|
||||
citizenship: str = Field(
|
||||
...,
|
||||
min_length=2,
|
||||
description="The nationality or citizenship of the passport holder, preferably as a country name or ISO code."
|
||||
)
|
||||
|
||||
sex: Literal["M", "F"] = Field(
|
||||
...,
|
||||
description="Sex of the passport holder: 'M' for male, 'F' for female."
|
||||
)
|
||||
|
||||
issue_date: date = Field(
|
||||
...,
|
||||
description="Date when the passport was issued, in ISO format (YYYY-MM-DD)."
|
||||
)
|
||||
|
||||
expiry_date: date = Field(
|
||||
...,
|
||||
description="Date when the passport expires, in ISO format (YYYY-MM-DD)."
|
||||
)
|
||||
# --- Updated Validator ---
|
||||
# @model_validator(mode='after')
|
||||
# def check_expiry_date_after_issue_date(self) -> Self:
|
||||
# # Only validate if both dates are present
|
||||
# if self.issue_date is not None and self.expiry_date is not None:
|
||||
# if self.issue_date >= self.expiry_date:
|
||||
# # Raise error only if both dates are present and invalid
|
||||
# raise ValueError(f'Expiry date ({self.expiry_date}) must be after issue date ({self.issue_date})')
|
||||
# return self
|
@ -1,65 +1,67 @@
|
||||
from datetime import date
|
||||
from typing import List, Literal, Optional
|
||||
from pydantic import BaseModel, ConfigDict, EmailStr, Field
|
||||
from typing import Optional # Keep Optional, remove others
|
||||
from pydantic import BaseModel, ConfigDict # Removed Field
|
||||
|
||||
|
||||
class FromProfile(BaseModel):
|
||||
"""
|
||||
Fields which can be extracted from description.txt
|
||||
Fields which can be extracted from description.txt - All fields optional and simplified to string where possible.
|
||||
"""
|
||||
model_config = ConfigDict(validate_assignment=True, str_strip_whitespace=True)
|
||||
model_config = ConfigDict(validate_assignment=True, str_strip_whitespace=True) # Keep config if needed
|
||||
|
||||
first_name: str = Field(..., min_length=1)
|
||||
last_name: str = Field(..., min_length=1)
|
||||
date_of_birth: date
|
||||
nationality: str
|
||||
country_of_domicile: str
|
||||
gender: Literal["Female", "Male"]
|
||||
first_name: Optional[str] = None
|
||||
last_name: Optional[str] = None
|
||||
date_of_birth: Optional[str] = None # Simplified from date
|
||||
nationality: Optional[str] = None
|
||||
country_of_domicile: Optional[str] = None
|
||||
gender: Optional[str] = None # Simplified from Literal
|
||||
|
||||
# ID information
|
||||
passport_number: str = Field(..., min_length=9, max_length=9, pattern=r"^[A-Z0-9]{9}$")
|
||||
id_type: Literal["passport"]
|
||||
id_issue_date: date
|
||||
id_expiry_date: date
|
||||
passport_number: Optional[str] = None # Simplified, removed Field constraints
|
||||
id_type: Optional[str] = None # Simplified from Literal
|
||||
id_issue_date: Optional[str] = None # Simplified from date
|
||||
id_expiry_date: Optional[str] = None # Simplified from date
|
||||
|
||||
# Contact
|
||||
phone: str = Field(..., min_length=8)
|
||||
email: str = Field(min_length=5)
|
||||
address: str
|
||||
phone: Optional[str] = None # Simplified, removed Field constraints
|
||||
email: Optional[str] = None # Simplified, removed Field constraints
|
||||
address: Optional[str] = None
|
||||
|
||||
# Personal info
|
||||
politically_exposed_person: bool
|
||||
marital_status: Literal["Single", "Married", "Divorced", "Widowed"]
|
||||
highest_education: Literal["Tertiary", "Secondary", "Primary", "None"]
|
||||
politically_exposed_person: Optional[str] = None # Simplified from bool
|
||||
marital_status: Optional[str] = None # Simplified from Literal
|
||||
highest_education: Optional[str] = None # Simplified from Literal
|
||||
education_history: Optional[str] = None
|
||||
|
||||
# Employment
|
||||
employment_status: Literal["Employee", "Self-Employed", "Unemployed", "Retired", "Student", "Diplomat", "Military", "Homemaker", "Other"]
|
||||
employment_since: Optional[int] = None
|
||||
employment_status: Optional[str] = None # Simplified from Literal
|
||||
employment_since: Optional[str] = None # Simplified from int
|
||||
employer: Optional[str] = None
|
||||
position: Optional[str] = None
|
||||
annual_salary_eur: Optional[float] = None
|
||||
annual_salary_eur: Optional[str] = None # Simplified from float
|
||||
|
||||
# Wealth background
|
||||
total_wealth_range: Literal["<1.5m", "1.5m-5m", "5m-10m", "10m-20m", "20m-50m", ">50m"]
|
||||
origin_of_wealth: List[Literal["Employment", "Inheritance", "Business", "Investments", "Sale of real estate", "Retirement package", "Other"]]
|
||||
total_wealth_range: Optional[str] = None # Simplified from Literal
|
||||
# List types are often handled differently; simplifying to a single string might lose info.
|
||||
# Keeping as Optional[str] based on request, but consider if Optional[List[str]] = None is better long-term.
|
||||
origin_of_wealth: Optional[str] = None # Simplified from List[Literal]
|
||||
inheritance_details: Optional[str] = None
|
||||
|
||||
# Assets
|
||||
business_assets_eur: float = Field(..., ge=0)
|
||||
business_assets_eur: Optional[str] = None # Simplified from float, removed Field constraint
|
||||
|
||||
# Income
|
||||
estimated_annual_income: Literal["<250k", "250k-500k", "500k-1m", ">1m"]
|
||||
income_country: str
|
||||
estimated_annual_income: Optional[str] = None # Was already Optional[str]
|
||||
income_country: Optional[str] = None
|
||||
|
||||
# Account preferences
|
||||
commercial_account: bool
|
||||
investment_risk_profile: Literal["Low", "Moderate", "Considerable", "High"]
|
||||
mandate_type: Literal["Advisory", "Discretionary"]
|
||||
investment_experience: Literal["Inexperienced", "Experienced", "Expert"]
|
||||
investment_horizon: Literal["Short", "Medium", "Long-Term"]
|
||||
preferred_markets: List[str]
|
||||
commercial_account: Optional[str] = None # Simplified from bool
|
||||
investment_risk_profile: Optional[str] = None # Simplified from Literal
|
||||
mandate_type: Optional[str] = None # Simplified from Literal
|
||||
investment_experience: Optional[str] = None # Simplified from Literal
|
||||
investment_horizon: Optional[str] = None # Simplified from Literal
|
||||
# Keeping as Optional[str] based on request, but consider if Optional[List[str]] = None is better long-term.
|
||||
preferred_markets: Optional[str] = None # Simplified from List[str]
|
||||
|
||||
# Assets under management
|
||||
total_aum: float
|
||||
aum_to_transfer: float
|
||||
total_aum: Optional[str] = None # Simplified from float
|
||||
aum_to_transfer: Optional[str] = None # Simplified from float
|
Reference in New Issue
Block a user