コンテンツにスキップ

Secrets

🚧 Work in Progress

This page is a work in progress.

このページは、翻訳時点(2024/08)では本家では作成途中です。

Serialize SecretStr and SecretBytes as plain-text

デフォルトでは、jsonにシリアライズする際、SecretStrSecretBytes***********としてシリアライズされます。

field_serializerを使用すると、jsonにシリアライズするときにシークレットをプレーンテキストとしてダンプできます。

from pydantic import BaseModel, SecretBytes, SecretStr, field_serializer


class Model(BaseModel):
    password: SecretStr
    password_bytes: SecretBytes

    @field_serializer('password', 'password_bytes', when_used='json')
    def dump_secret(self, v):
        return v.get_secret_value()


model = Model(password='IAmSensitive', password_bytes=b'IAmSensitiveBytes')
print(model)
#> password=SecretStr('**********') password_bytes=SecretBytes(b'**********')
print(model.password)
#> **********
print(model.model_dump())
"""
{
    'password': SecretStr('**********'),
    'password_bytes': SecretBytes(b'**********'),
}
"""
print(model.model_dump_json())
#> {"password":"IAmSensitive","password_bytes":"IAmSensitiveBytes"}

Create your own Secret field

Pydanticでは、カスタムのsecret型を作成するためのメカニズムとして、汎用のSecretクラスを提供しています。

API Documentation

pydantic.types.Secret

Pydanticでは、カスタムのsecret型を作成するためのメカニズムとして、汎用のSecretクラスを提供しています。 Secretを直接パラメータ化するか、パラメータ化されたSecretをサブクラス化して、secret型のstr()repr()をカスタマイズすることができます。

from datetime import date

from pydantic import BaseModel, Secret

# Using the default representation
SecretDate = Secret[date]


# Overwriting the representation
class SecretSalary(Secret[float]):
    def _display(self) -> str:
        return '$****.**'


class Employee(BaseModel):
    date_of_birth: SecretDate
    salary: SecretSalary


employee = Employee(date_of_birth='1990-01-01', salary=42)

print(employee)
#> date_of_birth=Secret('**********') salary=SecretSalary('$****.**')

print(employee.salary)
#> $****.**

print(employee.salary.get_secret_value())
#> 42.0

print(employee.date_of_birth)
#> **********

print(employee.date_of_birth.get_secret_value())
#> 1990-01-01

アノテーションを使用して、基礎となる型に制約を適用できます。

次に例を示します。

from typing_extensions import Annotated

from pydantic import BaseModel, Field, Secret, ValidationError

SecretPosInt = Secret[Annotated[int, Field(gt=0, strict=True)]]


class Model(BaseModel):
    sensitive_int: SecretPosInt


m = Model(sensitive_int=42)
print(m.model_dump())
#> {'sensitive_int': Secret('**********')}

try:
    m = Model(sensitive_int=-42)  # (1)!
except ValidationError as exc_info:
    print(exc_info.errors(include_url=False, include_input=False))
    """
    [
        {
            'type': 'greater_than',
            'loc': ('sensitive_int',),
            'msg': 'Input should be greater than 0',
            'ctx': {'gt': 0},
        }
    ]
    """

try:
    m = Model(sensitive_int='42')  # (2)!
except ValidationError as exc_info:
    print(exc_info.errors(include_url=False, include_input=False))
    """
    [
        {
            'type': 'int_type',
            'loc': ('sensitive_int',),
            'msg': 'Input should be a valid integer',
        }
    ]
    """
  1. 入力値が0より大きくないため、検証エラーが発生します。
  2. 入力値が整数ではないため、SecretPosInt型でstrictモードが有効になっているため、検証エラーが発生します。