from functools import cache from typing import Annotated import phonenumbers import pycountry from pydantic import BaseModel, BeforeValidator, Field, WithJsonSchema from ows_text_campaigns.adapters.scanner import ContentRecommendations def _validate_phone_number(value: str) -> str: try: numobj = phonenumbers.parse(value) except phonenumbers.NumberParseException: raise ValueError(f"{value} is not a valid phone number format") from None if not phonenumbers.is_valid_number(numobj): raise ValueError(f"{value} is not a valid phone number") return phonenumbers.format_number(numobj, phonenumbers.PhoneNumberFormat.E164) PhoneNumberStr = Annotated[ str, BeforeValidator(_validate_phone_number), WithJsonSchema( { "type": "string", "format": "phone", } ), ] @cache def _get_country_codes() -> list[str]: return [ getattr(country, "alpha_2") for country in pycountry.countries if hasattr(country, "alpha_2") ] def _validate_country_code(value: str) -> str: value = value.upper() if value not in _get_country_codes(): raise ValueError(f"{value} is not a valid country code") return value CountryCode = Annotated[str, BeforeValidator(_validate_country_code)] class ArtistContentRecommendations(BaseModel): opt_in_message: ContentRecommendations = Field(alias="optInMessage") welcome_message: ContentRecommendations = Field(alias="welcomeMessage")