pydantic이 무엇인고?

생각하는 마리오네트·2023년 10월 5일
0

삽지니어링

목록 보기
6/10
post-thumbnail

FastAPI에 대해서 공부를 하던중 공식문서에서 pydantic 이라는 녀석을 만나게 되었고, 이친구를 알아보자.

Python에서는 유효성 검사를 위한 패키지들이 있다. pydantic은 타입의 제약조건을 보장하기 위한 라이브러리로서 validation library와는 다른 parsing라이브러리 라고 한다.

차이점으로서 validation library의 경우 입력 데이터의 타입을 제약한다는 점이 있지만, pydantic은 출력 모델의 유형과 제약조건을 보장하는 점이다.

그렇다면 여기서 유효성을 검증한다, 데이터를 검증한다라는게 무슨 의미일까??

복잡한 서비스 로직이 있다고 가정했을때, 개발자가 원하는 방향으로 흐르게 만들어야 하지만, 사용자들의 잘못된 입력으로 인해서 문제가 발생할 수 있는 부분을 방지하기 위해서 특정 유형과 제약조건을 통해서 유효성 검사를 사용합니다.

pydantic역시 api호출시 출력 모델의 유형과 제약조건을 보장시키기 위한다고 보면된다.

(해당 글은 이 블로그 에서 요약 했습니다.)

Install pydantic

pip install pydantic

Import & Class

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None

FastAPI 공식문서에 나오는 예제를 가지고 왔다.
pydantic은 내장된 Type Hint를 사용해서 각각의 변수들의 데이터 유형을 결정해 줍니다.

Item 클래스의 내부를 살펴보겠습니다.

Name : 문자열이 와야하며, 변수의 명은 name입니다. 또한 이 필드는 반드시 포함되어야 합니다.
descriptio : 문자열이 올 수있으며, 변수의 명은 description입니다. 해당 필드는 반드시 포함될 필요는 없으며, 설정을 따로 하지 않는다면 기본값으로 None을 가집니다.
price : 실수형 변수이며, 변수의 명은 price입니다. 해당 필드는 반드시 포함되어야 합니다.
tax : 실수형 변수가 올 수 있으며, 변수의 명은 tax입니다. 또한 해당 변수는 반드시 포함 될 필요는 없으며, 설정을 따로 하지 않는다면 기본값인 None을 가집니다.

Field Types

pydentic은 python 표준라이브러리에서 사용하는 공통타입을 거의 다 지원하고 있습니다.

  • bool
  • str
  • int
  • float
  • list
  • tuple
  • dict
  • set
  • datetime.date
  • datetime.time
  • datetime.datetime
  • enum.Enum
    등등

Constrained types

Constrained Type을 통해 자신의 제한을 적용할 수 있습니다.

from pydantic import BaseModel

class Item(BaseModel):
    name: constr(min_length = 2, max_length = 5)
    description: Union[str, None] = None
    price: conint(gt = 1000, lt = 2000)
    tax: Union[float, None] = None

Strict types

검증된 값이 해당 유형이거나 해당 유형의 하위 유형인 경우에만 유효성 검사를 통과하는 엄격한 제한을 찾고있다면 strict type을 사용해볼 수 있습니다.

  • StrictStr
  • StrictInt
  • StrictFloat
  • StrictBool

Validator

상속된 클래스 내부의 유효성 검사기 데코레이터를 사용하여 고유한 사용자 지정 유효성 검사기를 만들 수 있다.

다음 예시의 경우 id가 4자리 인지 확인하고 Confirm_password가 비밀번호 필드와 일치하는지 확인하는 다음 예를 살펴보겠습니다.

from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel, ValidationError, validator
class User(BaseModel):
    id: int
    username : str
    password : str
    confirm_password : str
    alias = 'anonymous'
    timestamp: Optional[datetime] = None
    friends: List[int] = []
    @validator('id') # 1번
    def id_must_be_4_digits(cls, v):
        if len(str(v)) != 4:
            raise ValueError('must be 4 digits')
        return v
    @validator('confirm_password') # 2번
    def passwords_match(cls, v, values, **kwargs):
        if 'password' in values and v != values['password']:
            raise ValueError('passwords do not match')
        return v

validator를 사용하기 전에는 타입을 통해서 유효성 검사를 했지만, 우리가 원하는 방식의 유효성 검사를 하기위해서 pydantic의 validator데코레이터를 사용하게 되는데 위의 코드의 설명은 아래와같다.

주석 1번을 보면 id_must_be_4_digits함수인데 이것은 ID값의 길이가 반드시 4자리가 되어야하는 규칙을 만들기 위한 함수이다.
@validator와 괄호안에 사용하고자 하는 필드를 넣으주면된다. 즉, @validator('id') 는 'id'필드를 인자로 사용하겠다는 의미이다.
함수에는 인자로 cls 와 v가 들어가있는데 cls는 우리가 아는 self와 같은 의미이며, v는 @validator의 괄호에 넣어준 필드값이라고 보면된다.

주석2번의 코드를 풀어보면 confirm_password필드를 사용하는 validator이며 passwords_match함수는 비밀번호가 일치하는지 여부에 대한 유효성 검사함수이다.

이 함수의 인자를 보면 values가 있는데, values의 경우는 User클래스의 전체 필드를 의미한다.

따라서 함수의 조건문에는 password가 필드내에 있으면서 비밀번호가 일치하면 이라는 조건을 가지고 있는것이다.

profile
문제를해결하는도구로서의"데이터"

0개의 댓글