pydantic

About_work·2023년 4월 18일
0

pydantic

목록 보기
1/1

사용 목적

  • 강력한 유효성 검사
    • Pydantic은 입력 데이터의 유효성을 검사하는 데 강력한 도구를 제공
    • 유효성 검사를 통해 잘못된 데이터를 방지하고, 런타임 에러를 방지할 수 있습니다.
  • 쉬운 구문 분석
    • Pydantic은 입력 데이터를 쉽게 파싱하고, Python 객체로 변환할 수 있습니다.
    • 이를 통해 Python 객체의 사용을 쉽게 만듭니다.
  • 다양한 데이터 유형 지원
    • Pydantic은 다양한 데이터 유형을 지원합니다.
    • 예를 들어, 숫자, 문자열, 불리언, 날짜 및 시간 등의 데이터를 지원합니다.

특징

  • dataclass와 사용형태가 비슷
  • Nested Dict 구조 <-> Recursive Model 변환이 가능
  • 단일 변수에 대한 validation, post validation을 -> 모듈 작성자가 decorator로 구현 가능
    • 생성한 이후에, 맴버 변수 set 시점에도 validation이 가능
  • dict / pickle 을 포함하여, 다양한 serialization method가 지원됩니다.
    • blackboard2가 편하면, dict() 로 변환해서 사용해도 될듯

사용 방법

강력한 유효성 검사

0

  • 고쳐줄 수 있는 부분들은 알아서 적절히 잘 고쳐준다. (아래 예시 참조)
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel


class User(BaseModel):
    id: int
    name = 'John Doe'
    signup_ts: Optional[datetime] = None
    friends: List[int] = []


external_data = {
    'id': '123',
    'signup_ts': '2019-06-01 12:22',
    'friends': [1, 2, '3'],
}
user = User(**external_data)
print(user.id)
#> 123
print(repr(user.signup_ts))
#> datetime.datetime(2019, 6, 1, 12, 22)
print(user.friends)
#> [1, 2, 3]
print(user.dict())
"""
{
    'id': 123,
    'signup_ts': datetime.datetime(2019, 6, 1, 12, 22),
    'friends': [1, 2, 3],
    'name': 'John Doe',
}
"""

1

  • 유효성이 틀린 부분은, 아래와 같이 에러를 내어준다.
from pydantic import ValidationError

try:
    User(signup_ts='broken', friends=[1, 2, 'not number'])
except ValidationError as e:
    print(e.json())
[
  {
    "loc": [
      "id"
    ],
    "msg": "field required",
    "type": "value_error.missing"
  },
  {
    "loc": [
      "signup_ts"
    ],
    "msg": "invalid datetime format",
    "type": "value_error.datetime"
  },
  {
    "loc": [
      "friends",
      2
    ],
    "msg": "value is not a valid integer",
    "type": "type_error.integer"
  }
]

2

from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int
    email: str
  • Person: Pydantic 모델
  • name, age, email: 필드
    • 각 필드는 데이터 유형을 지정
    • 필요한 경우 유효성 검사 규칙을 정의 가능
  • Pydantic 모델을 사용하려면, 입력 데이터를 Pydantic 모델의 인스턴스로 변환해야 합니다.
  • 다음은 입력 데이터를 Person 모델의 인스턴스로 변환하는 예시입니다.
  • 아래와 같이 입력 데이터의 타입 유효성 검사를 할 수 있습니다.
invalid_data = {
    'name': 'Alice',
    'age': 'thirty',
    'email': 'alice@example.com'
}

try:
    person = Person(**invalid_data)
except ValueError as e:
    print(e)

3

  • 아래와 같이 validator 데코레이터를 이용하여, 필드 유효성 검사 규칙을 정의할 수 있다.
from pydantic import validator

class Person(BaseModel):
    name: str
    age: int
    email: str

    @validator('age')
    def check_age(cls, v):
        if v < 0 or v > 150:
            raise ValueError('Age must be between 0 and 150')
        return v

Nested Dict 구조 <-> Recursive Model 변환이 가능

from typing import List, Optional
from pydantic import BaseModel


class Foo(BaseModel):
    count: int
    size: Optional[float] = None


class Bar(BaseModel):
    apple = 'x'
    banana = 'y'


class Spam(BaseModel):
    foo: Foo
    bars: List[Bar]


m = Spam(foo={'count': 4}, bars=[{'apple': 'x1'}, {'apple': 'x2'}])
print(m)
#> foo=Foo(count=4, size=None) bars=[Bar(apple='x1', banana='y'),
#> Bar(apple='x2', banana='y')]
print(m.dict())
"""
{
    'foo': {'count': 4, 'size': None},
    'bars': [
        {'apple': 'x1', 'banana': 'y'},
        {'apple': 'x2', 'banana': 'y'},
    ],
}
"""

단일 변수에 대한 validation, post validation을 -> 모듈 작성자가 decorator로 구현 가능

  • 생성한 이후에, 맴버 변수 set 시점에도 validation이 가능
from pydantic import BaseModel, ValidationError, validator


class UserModel(BaseModel):
    name: str
    username: str
    password1: str
    password2: str

    @validator('name')
    def name_must_contain_space(cls, v):
        if ' ' not in v:
            raise ValueError('must contain a space')
        return v.title()

    @validator('password2')
    def passwords_match(cls, v, values, **kwargs):
        if 'password1' in values and v != values['password1']:
            raise ValueError('passwords do not match')
        return v

    @validator('username')
    def username_alphanumeric(cls, v):
        assert v.isalnum(), 'must be alphanumeric'
        return v


user = UserModel(
    name='samuel colvin',
    username='scolvin',
    password1='zxcvbn',
    password2='zxcvbn',
)
print(user)
#> name='Samuel Colvin' username='scolvin' password1='zxcvbn' password2='zxcvbn'

try:
    UserModel(
        name='samuel',
        username='scolvin',
        password1='zxcvbn',
        password2='zxcvbn2',
    )
except ValidationError as e:
    print(e)
    """
    2 validation errors for UserModel
    name
      must contain a space (type=value_error)
    password2
      passwords do not match (type=value_error)
    """

쉬운 구문 분석

  • Pydantic을 사용하여, JSON 문자열을 파싱하여 Python 객체로 변환하는 예시
  • JSON , YAML, TOML, MessagePack 등의 데이터 포멧을 전부 지원
from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int
    email: str

json_str = """
{
    "name": "Alice",
    "age": 30,
    "email": "alice@example.com"
}
"""

person = Person.parse_raw(json_str)
print(person)
  • parse_raw() 메소드는 데이터를 파싱하여 Python 객체로 변환하는 역할을 합니다.
    • 이 메소드는 데이터의 유효성 검사를 수행하지 않으므로, 입력 데이터가 유효한 경우에만 사용해야 합니다.
  • 변환된 Python 객체는 Person 클래스의 인스턴스입니다.

parse_obj 메서드

  • parse_obj 메서드는 pydantic 모델 클래스의 인스턴스를 생성할 때 사용

  • 이 메서드는 딕셔너리와 같은 객체를 인수로 받아서, 해당 객체를 사용하여 pydantic 모델 클래스의 새로운 인스턴스를 만듭니다.

  • parse_obj 메서드는 일반적으로 dict나 JSON과 같은 문자열에서 파싱된 데이터를 pydantic 모델 인스턴스로 변환하는 데 사용

from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str

data = {"id": 123, "name": "John Doe"}
user = User.parse_obj(data)

__fields__

class BaseModel(pydantic.BaseModel):
    def __init__(self, **data: Any):
        flags_like = data.pop("flags_like", None)
        if flags_like:
            for name, field in self.__fields__.items():
  • 위 코드에서, __fields__ 에 대해 알아보자.
  • 위의 field 변수는 ModelField 인스턴스로, 모든 pydantic.BaseModel의 필드는 ModelField 인스턴스입니다.
  • ModelField 클래스
    • pydantic 모델의 필드 정보를 담고 있는 클래스
    • 각 필드는 ModelField 클래스의 인스턴스로 표현됩니다.
    • 필드의 메타데이터(metadata)를 저장하기 위한 속성(attribute)을 가지고 있습니다.
    • 속성(attribute)은 다음과 같습니다.
      • field
        • name: 필드의 이름
        • type: 필드의 데이터 타입
        • required: 필드가 필수(required)인지 여부
        • default: 필드의 기본값
        • validators: 필드의 유효성 검사(validation) 규칙
        • alias: 필드의 별칭(alias)
        • description: 필드의 설명(description)
        • field_info: 필드의 기타 정보를 저장하는 딕셔너리
profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글