본문 바로가기
MLOps

MLOps - 13. FastAPI

by cocacola0 2022. 5. 28.

출처 : 변성윤님 블로그.
출처 : 부스트캠프 AI Tech.

1. FastAPI 기본 지식

1.1 Path Parameter, Query Parameter

  • 웹에서 GET Method를 사용해 데이터를 전송할 수 있음
  • ID가 402인 사용자 정보를 가져오고 싶은 경우 방식
  • Path Parameter 방식
    • /users/402
    • 서버에 402라는 값을 전달하고 변수로 사용
  • Query Parameter 방식 (Query String)
    • /users?id=402
    • API 뒤에 입력 데이터를 함께 제공하는 방식으로 사용
    • Query String은 Key, Value의 쌍으로 이루어지며 &로 연결해 여러 데이터를 넘길 수 있음
  • 네이버에서 검색할 경우
    https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&uqery=광진구
  • 언제 어떤 방식을 사용해야 할까?
  • 관련한 자료를 찾아보면 상황마다 다름
    • 어떤 Resource를 식별하고 싶은 경우(그러나 kyle이란 유저는 없는 경우)
    • /users/kyle : Path
    • /users?name=kyle : Query
  • Path Parameter : 저 경로에 존재하는 내용이 없으므로 404 Error 발생
  • Query Parameter : 데이터가 없는 경우 빈 리스트가 나옴 => 추가로 Error Handling이 필요
  • Resource를 식별해야 하는 경우 : Path Parameter가 더 적합
  • 정렬, 필터링을 해야 하는 경우 : Query Parameter가 더 적합

1.1.1. Path Parameter

  • GET Method : 정보를 READ하기 위해 사용
  • 유저 정보에 접근하는 API 만들기
  • FastAPI는 데코레이터로 GET, POST를 표시
    • @app.get @app.post
  • GET Method의 인자로 있는 {user_id}가 함수의 값으로 주입
  • python 02_path_parameter.py로 웹서버를 띄운 후, localhost:8000/users/1로 접근
  • 터미널에서 Request 로그가 남음

1.1.2. Query Parameter

  • 함수의 파라미터가 Query Parameter로 사용됨
  • python3 03_query_parameter.py로 웹서버 실행
  • localhost:8000/items/로 접근시 fake_items_db[0:10]의 결과 출력
  • Query Parameter를 적용(URL 뒤에 ?를 붙이고 Key, Value 형태로 연결)
  • localhost:8000/items/?skip=3&limit=10
  • skip=3, limit=10(기본값) => fake_db_items[3:13] => 아무것도 출력되지 않음

1.2 Optional Parameter

  • 특정 파라미터는 Optional(선택적)으로 하고 싶은 경우
  • typing 모듈의 Optional을 사용
  • Optional을 사용해 이 파라미터는 Optional임을 명시(기본 값은 None)
  • python3 04_optional_parameter.py로 웹서버 실행

1.3 Request Body

  • 클라이언트에서 API에 데이터를 보낼 때, Request Body를 사용함
  • 클라이언트 => API : Request Body
  • API의 Response => 클라이언트 : Response Body
  • Request Body에 데이터가 항상 포함되어야 하는 것은 아님
  • Request Body에 데이터를 보내고 싶다면 POST Method를 사용
    • (참고) GET Method는 URL, Request Header로 데이터 전달
  • POST Method는 Request Body에 데이터를 넣어 보냄
    • Body의 데이터를 설명하는 Content-Type이란 Header 필드가 존재하고, 어떤 데이터 타입인 명시해야 함
    • 대표적인 컨텐츠 타입
      • application/x-www-form-urlencoded : BODY에 Key, Value 사용. & 구분자 사용
      • text/plain : 단순 txt 파일
      • multipartform-data : 데이터를 바이너리 데이터로 전송
  • POST 요청으로 item을 생성하는 예제
  • pydantic로 Request Body 데이터 정의
  • Type Hinting에 위에서 생성한 Class 주입
  • Request Body 데이터를 Validation
  • python3 05_request_body.py로 웹서버 실행
  • curl 등으로 POST를 실행할 수 있지만, localhost:30003/docs로 이동
  • Schemas에서 pydantic으로 정의한 내용을 볼 수 있음
  • POST 쪽을 클릭해도 해당 내용 확인할 수 있음
  • Try it out 클릭
  • curl 명령어, Response가 보임
  • 일부러 tax에 String을 넣어서 Execute
  • tax가 Float이 아니라는 메세지가 출력됨(Validation Check한 것)

1.4 Response Body

  • API의 Response => 클라이언트 : Response Body
  • Decorator의 response_model 인자로 주입 가능
  • 역할
    • Output Data를 해당 정의에 맞게 변형
    • 데이터 Validation
    • Response에 대한 Json Schema 추가
    • 자동으로 문서화
  • python3 06_response_body.py 웹 서버 실행한 후, docs 확인
  • Try it out을 누르고 Execute를 실행
  • Request 데이터와 Response 데이터가 다름

1.5 Form, File

1.5.1 Form

  • Form(입력) 형태로 데이터를 받고 싶은 경우
  • Form을 사용하려면 python-multipart를 설치해야 함
    pip install python-multipart
  • 프론트도 간단히 만들기 위해 Jinja2 설치
    pip install Jinja2
  • Form 클래스를 사용하면 Request의 Form Data에서 값을 가져옴
  • 프론트엔드를 사용하기 위해 간단히 리팩토링
  • Request 객체로 Request를 받음
  • 파이썬에서 사용할 수 있는 템플릿 엔진 : Jinja Template => 프론트엔드 구성
  • templates.TemplateResponse로 해당 HTML로 데이터를 보냄

  • Jinja Template에선 {{ }} 표현을 사용해 데이터를 사용할 수 있음
  • Form(...) : ...는 무엇일까?
    • Python ellipsis : Required(꼭 필수 요소)를 의미
  • FastAPI 웹 서버를 실행한 후 Swagger로 이동하면 Required를 볼 수 있음

1.5.2 File

  • File 업로드하고 싶은 경우
  • File을 사용할 때도 python-multipart를 설치해야 함
  • pip install python-multipart
  • “/”로 접근할 때 보여줄 HTML 코드
  • HTML에서 action으로 넘김
  • 파일을 Bytes로 표현하고, 여러 파일은 LIST에 설정
  • python3 08_file.py를 실행하고 http://101.101.216.30:30003/로 이동

2. Pydantic

  • FastAPI에서 Class 사용할 때 보이던 Pydantic
  • Data Validation / Settings Management 라이브러리
  • Type Hint를 런타임에서 강제해 안전하게 데이터 핸들링
  • 파이썬 기본 타입(String, Int 등) + List, Dict, Tuple에 대한 Validation 지원
  • 기존 Validation 라이브러리보다 빠름 (Benchmark)
  • Config를 효과적으로 관리하도록 도와줌
  • 머신러닝 Feature Data Validation으로도 활용 가능

2.1 Pydantic Validation

  • Machine Learning Model Input Validation
  • Online Serving에서 Input 데이터를 Validation하는 Case
  • Validation Check Logic
    • 조건 1: 올바른 url을 입력 받음 (url)
    • 조건 2: 1-10 사이의 정수 입력 받음 (rate)
    • 조건 3: 올바른 폴더 이름을 입력 받음(target_dir)
  • 사용할 수 있는 방법
    • 1) 일반 Python Class를 활용한 Input Definition 및 Validation
    • 2) Dataclass를(python 3.7 이상 필요) 활용한 Input Definition 및 Validation
    • 3) Pydantic을 활용한 Input Definition 및 Validation
    1. 일반 Python Class 활용시
      • Python Class로 Input Definition 및 Validation => 의미 없는 코드가 많아짐
      • 복잡한 검증 로직엔 Class Method가 복잡해지기 쉬움
      • Exception Handling을 어떻게 할지 등 커스텀하게 제어할 수 있는 있지만 메인 로직(Input을 받아서 Inference를 수행하는)에 집중하기 어려워짐

    1. Dataclass 활용시
      • 인스턴스 생성 시점에서 Validation을 수행하기 쉬움
      • 여전히 Validation 로직들을 직접 작성해야 함
      • Validation 로직을 따로 작성하지 않으면, 런타임에서 type checking을 지원하지 않음

    1. Pydantic Validation
      • 훨씬 간결해진 코드 (6라인)(vs 52라인 Python Class, vs 50라인 dataclass)
      • 주로 쓰이는 타입들(http url, db url, enum 등)에 대한 Validation이 만들어져 있음
      • 런타임에서 Type Hint에 따라서 Validation Error 발생
      • Custom Type에 대한 Validation도 쉽게 사용 가능
      • 어디서 에러가 발생했는지 location, type, message 등을 알려줌

 

2.2 Pydantic Config

  • Pydantic은 Config을 체계적으로 관리할 방법을 제공
  • 기존에 다른 라이브러리들은 어떻게 Config를 설정하고 있을까?
  • 애플리케이션은 종종 설정을 상수로 코드에 저장함 -> 하드코딩....
  • 이것은 Twelve-Factor를 위반
  • Twelve-Factor는 설정을 코드에서 엄격하게 분리하는 것을 요구함
  • Twelve-Factor App은 설정을 환경 변수(envvars나 env라고도 불림)에 저장함
  • 환경 변수는 코드 변경 없이 쉽게 배포 때마다 쉽게 변경할 수 있음
  • The Twelve-Factor App이라는 SaaS(Software as a Service)를 만들기 위한 방법론을 정리한 규칙들에 따르면, 환경 설정은 애플리케이션 코드에서 분리되어 관리되어야 함
  • 참고 글: https://12factor.net/ko/config

2.2.1 .ini, .yaml 파일 등으로 config 설정하기

  • yaml로 환경 설정을 관리할 경우, 쉽게 환경을 설정할 수 있지만, 환경에 대한 설정을 코드 하드코딩하는 형태
  • 때문에 변경 사항이 생길 때 유연하게 코드를 변경하기 어려움

2.2.2 flask-style config.py

  • Config 클래스에서 yaml, ini 파일을 불러와 python class 필드로 주입하는 과정을 구현
  • Config를 상속한 클래스에서는 Config 클래스의 정보를 오버라이딩해서 사용
  • 하지만 해당 파일의 데이터가 정상적인지 체크하거나(Validation) 또는 환경 변수로 부터 해당 필드를 오버라이딩(Overriding) 하려면 코드량이 늘어남

2.2.3 pydantic base settings

  • Validation처럼 Pydantic은 BaseSettings를 상속한 클래스에서 Type Hint로 주입된 설정 데이터를 검증할 수 있음
  • Field 클래스의 env 인자로, 환경 변수로 부터 해당 필드를 오버라이딩 할 수 있음
  • yaml, ini 파일들을 추가적으로 만들지 않고, .env 파일들을 환경별로 만들어 두거나, 실행 환경에서 유연하게 오버라이딩 할 수 있음

  • pydantic base settings - environment variable overriding
  • 위의 세 방법 모두 틀린 방법은 아님
  • 실무에서는 무조건 pydantic을 활용하기 보다는, 각 팀에서 맞는 방법을 따라가는 것이 좋음
  • 하지만 실무에서 여러 사람과 협업하는 환경에서 Human Error를 줄여주는 Pydantic의 기능들은 유용!

'MLOps' 카테고리의 다른 글

MLOps - 15. Docker  (0) 2022.05.30
MLOps - 14. FastAPI  (0) 2022.05.29
MLOps - 12. FastAPI  (0) 2022.05.27
MLOps - 11. CI/CD, Github Action  (0) 2022.05.26
MLOps - 10. Cloud  (0) 2022.05.25

댓글