Experimental Features¶
このセクションには、Pydanticの新しい実験的な機能に関するドキュメントがあります。これらの機能は変更または削除される可能性があり、Pydanticの恒久的な一部にする前にフィードバックと提案を求めています。
試験的な機能の詳細については、Version Policyを参照してください。
Feedback¶
実験的な機能に関するフィードバックを歓迎しますでIssueを開いて、考え、要望、提案を共有してください。
また、既存のフィードバックを読み、既存の問題に自分の考えを追加することもお勧めします。
Warnings on Import¶
experimentalモジュールから試験的な機能をインポートすると、その機能が試験的であることを示す警告メッセージが表示されます。この警告を無効にするには、次のようにします。
import warnings
from pydantic import PydanticExperimentalWarning
warnings.filterwarnings('ignore', category=PydanticExperimentalWarning)
Pipeline API¶
Pydantic v2.8.0では、既存のAPIよりも型安全な方法でパース(バリデーション)、制約、変換を構成できる実験的な"パイプライン"APIが導入されました。 このAPIは変更または削除される可能性があります。Pydanticの恒久的な一部にする前に、フィードバックと提案を求めています。
API Documentation
一般に、パイプラインAPIは、検証中に入力データに適用する一連のステップを定義するために使用されます。 パイプラインAPIは、既存のPydantic APIよりも型安全で構成可能なように設計されています。
パイプラインの各ステップは次のとおりです。
- 指定された型に対してpydantic検証を実行する検証ステップ
- データを変更する変換ステップ
- 条件に対してデータをチェックする制約ステップ
- 条件に対してデータをチェックし、
Falseが返された場合にエラーを発生させる述部ステップ
以下の例は、複雑さを犠牲にして網羅的にしようとするものであることに注意してください。型アノテーションでこれだけ多くの変換を記述している場合は、UserInモデルとUserOutモデル(以下の例)を使用するか、または同様の変換をidomaticプレーンPythonコードで行うことを検討してください。
これらのAPIは、コードの節約が大きく、追加される複雑さが比較的小さい状況を対象としています。
from __future__ import annotations
from datetime import datetime
from typing_extensions import Annotated
from pydantic import BaseModel
from pydantic.experimental.pipeline import validate_as, validate_as_deferred
class User(BaseModel):
name: Annotated[str, validate_as(str).str_lower()] # (1)!
age: Annotated[int, validate_as(int).gt(0)] # (2)!
username: Annotated[str, validate_as(str).str_pattern(r'[a-z]+')] # (3)!
password: Annotated[
str,
validate_as(str)
.transform(str.lower)
.predicate(lambda x: x != 'password'), # (4)!
]
favorite_number: Annotated[ # (5)!
int,
(validate_as(int) | validate_as(str).str_strip().validate_as(int)).gt(
0
),
]
friends: Annotated[list[User], validate_as(...).len(0, 100)] # (6)!
family: Annotated[ # (7)!
list[User],
validate_as_deferred(lambda: list[User]).transform(lambda x: x[1:]),
]
bio: Annotated[
datetime,
validate_as(int)
.transform(lambda x: x / 1_000_000)
.validate_as(...), # (8)!
]
- 文字列を小文字にします。
- 整数がゼロより大きくなるように制約します。
- 正規表現パターンに一致するように文字列を制約します。
- 下位レベルのtransform、constrain、predicateメソッドも使用できます。
`or&`演算子を使ってステップを結合します(論理ORやAND)。- 最初の位置引数として
Ellipsis、...を指定してvalidate_as(...)を呼び出すことは、validate_as(<field type>)を意味します。任意の型を受け入れるにはvalidate_as(Any)を使用してください。 - 再帰型の場合、
validate_as_deferredを使用して、型を定義する前に型自体を参照できます。 - 他のステップの前または後に
validate_as()を呼び出して、前処理または後処理を行うことができます。
Mapping from BeforeValidator, AfterValidator and WrapValidator¶
validate_asメソッドは、BeforeValidator、AfterValidatorおよびWrapValidatorを定義するための、より型安全な方法です。
from typing_extensions import Annotated
from pydantic.experimental.pipeline import transform, validate_as
# BeforeValidator
Annotated[int, validate_as(str).str_strip().validate_as(...)] # (1)!
# AfterValidator
Annotated[int, transform(lambda x: x * 2)] # (2)!
# WrapValidator
Annotated[
int,
validate_as(str)
.str_strip()
.validate_as(...)
.transform(lambda x: x * 2), # (3)!
]
- 文字列を整数として解析する前に、文字列から空白を取り除きます。
- 整数を解析した後、2を掛けます。
- 文字列から空白を取り除き、整数として検証してから、2を掛けます。
Alternative patterns¶
シナリオに応じて、さまざまな代替パターンを使用できます。
一例として、上記のUserInとUserOutパターンを考えてみましょう。
from __future__ import annotations
from pydantic import BaseModel
class UserIn(BaseModel):
favorite_number: int | str
class UserOut(BaseModel):
favorite_number: int
def my_api(user: UserIn) -> UserOut:
favorite_number = user.favorite_number
if isinstance(favorite_number, str):
favorite_number = int(user.favorite_number.strip())
return UserOut(favorite_number=favorite_number)
assert my_api(UserIn(favorite_number=' 1 ')).favorite_number == 1
この例では、上記の例よりも理解しやすく、型チェックなども簡単な慣用的なPythonコードを使用しています。 選択するアプローチは、実際にはユース・ケースによって異なります。 適切なパターンを選択するためには、冗長性、パフォーマンス、ユーザーに意味のあるエラーを返すことの容易さなどを比較する必要があります。 可能だからといって、パイプラインAPIのような高度なパターンを乱用することに注意してください。