🐍
Pydanticの拡張クラスで小文字化まで行う
始めに
PydanticでEmailStrを拡張する
という記事を書きました。今回の記事では、PydanticでEmailStrを拡張する
で行ったことをさらに拡張して、大文字小文字のどちらでもパラメータを受け取りつつ、小文字化してアプリケーションで受け取れるようにさらに拡張します。
環境
- Python
- 3.12.7
- Pydantic
- 2.9.2
実装
以前に追加したロジックでvalidate_half_and_full_email
のレスポンスを小文字化します。
from typing import Type, Any
import re
from pydantic import EmailStr, validator, GetCoreSchemaHandler
from pydantic_core import core_schema
class CustomEmailStr(EmailStr):
@classmethod
def validate_half_and_full_email(cls, value: str) -> str:
if not re.search(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", value):
raise ValueError("ERROR.EMAIL_VALIDATION")
return value.lower() # ここだけ変更
@classmethod
def __get_pydantic_core_schema__(cls, source_type: Type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
email_schema = handler.generate_schema(EmailStr)
return core_schema.chain_schema(
[
email_schema,
core_schema.no_info_after_validator_function(
cls.validate_half_and_full_email,
core_schema.str_schema()
),
]
)
次のテストで大文字を小文字化できていることがわかります。
class _Test(BaseModel):
email: CustomEmailStr
class TestIsValid:
@pytest.mark.parametrize(
"value",
[
("aiueo@example.com"),
("AIUEO@example.com"),
],
)
def test_is_lower(self, value):
assert _Test(email=value).email == value.lower()
ソースコード
終わりに
記事としてはEmailStr
を継承しているのでユースケースとしてはかなり狭いのですが、他にも拡張した型を使用することがあると思うのでその時に役に立てばよいかと考えております。
Discussion