Aller au contenu

Secrets

!!! avertissement "🚧 Work in Progress" Cette page est un work in progress.

Sérialiser SecretStr et SecretBytes en texte brut

Par défaut, SecretStr et SecretBytes seront sérialisés comme ********** lors de la sérialisation vers json.

Vous pouvez utiliser le [field_serializer][pydantic.function_serializers.field_serializer] pour vider le secret sous forme de texte brut lors de la sérialisation en 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"}

Créez votre propre champ Secret

Pydantic fournit la classe générique Secret comme mécanisme pour créer des types de secrets personnalisés.

??? API "Documentation API" pydantic.types.Secret

Pydantic fournit la classe générique Secret comme mécanisme pour créer des types de secrets personnalisés. Vous pouvez soit paramétrer directement Secret , soit sous-classer un Secret paramétré pour personnaliser les str() et repr() d'un type de secret.

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

Vous pouvez appliquer des contraintes sur le type sous-jacent via des annotations: Par exemple:

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. La valeur d'entrée n'est pas supérieure à 0, elle génère donc une erreur de validation.
  2. La valeur d'entrée n'est pas un entier, elle génère donc une erreur de validation car le type SecretPosInt a le mode strict activé.

本文总阅读量