FastAPI 2

태그: ,

카테고리: ,


출처 : FastAPI

🚫 아래 내용은 주관적인 생각이므로 사실과 다를 수 있습니다.



Path Parameters

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id):
    return {"item_id": item_id}
  • 경로에 파라미터/변수를 파이썬 f스트링 문법과 동일하게 선언 가능
  • 패스 파라미터 item_id의 값이 read_item 함수의 인자 item_id로 전달됨
  • 127.0.0.1:8000/items/foo 요청시 반환값은
    {"item_id":"foo"}
    

Path parameters with types

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}
  • 파이썬 기본 타입들을 사용해 함수 내 패스 파라미터의 타입을 지정 가능
  • 타입에러 자동 반환

Data conversion

  • 위 코드처럼 타입 지정시, 문자열로 입력 받아도 자동 형변환 = “3” -> 3

Data validation

  • 타입 지정 후, 자동 형변환이 불가한 값을 입력시 아래의 HTTP error 반환
      {
          "detail": [
              {
                  "loc": [
                      "path",
                      "item_id"
                  ],
                  "msg": "value is not a valid integer",
                  "type": "type_error.integer"
              }
          ]
      }
    
  • int 타입 지정 후, 소수(float) 타입 입력시에도 위와 유사한 에러 반환

Documentation

  • Base URL 뒤에 “/docs”를 추가하면(127.0.0.1:8000/docs)
    Swagger UI로 구성된 API 문서 자동 출력
  • “/docs” 외의 대안으로 “/redoc” 또한 가능

Pydantic

  • 모든 데이터 타입 검증은 Pydantic을 통해 진행되므로
    Pydantic의 모든 장점을 이용 가능

Order matters

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}


@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}
  • 위와 같이 구체적인 경로를 먼저 선언해줘야 순서의 문제가 발생하지 않음
  • 만약 read_user 함수를 먼저 선언하게 되면,
    “/users/me” 호출시, {“user_id”: “me”}를 반환 받을 수도 있음

Predefined values

  • 만약 경로에 패스 파라미터를 사용중이고,
    해당 패스 파라미터로 넘겨받을 값들이 제한적이어야 한다면,
    파이썬의 Enum을 사용할 수 있다

Create an Enum class

  • 아래와 같이 Enum을 임포트하고 str, Enum을 상속받는 클래스를 정의한다
from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name == ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}

    if model_name.value == "lenet":
        return {"model_name": model_name, "message": "LeCNN all the images"}

    return {"model_name": model_name, "message": "Have some residuals"}
  • Enum 사용은 파이썬 3.4 이상부터 가능하다

Declare a path parameter

  • 위 코드처럼 미리 정의한 Enum 타입을 패스 파라미터 타입으로 지정이 가능

Check the docs

  • 패스 파라미터 타입으로 Enum 타입을 지정하면, docs 문서에서도 반영이 된다

Working with Python enumerations

  • 그렇게 패스 파라미터로 받은 값은 지정된 Enum의 멤버가 된다
  • 파라미터로 전달 받은 값을 Enum 멤버와 비교연산자로 비교 가능
  • Enum 멤버의 실제 값을 얻으려면 .value 사용
  • Enum 멤버 반환시에는 해당 값으로 자동 변환되어 반환
    return ModelName.alexnet
    -> "alexnet"
    

Path parameters containing paths

  • 패스 파라미터로 경로를 받는 경우 Starlette 내부 기능을 이용한다

Path convertor

@app.get("/files/{file_path:path}")
async def read_file(file_path: str):
  • 위와 같이 :path만 뒤에 붙여주면 된다
  • 경로값 앞에 “/”가 붙을 경우(/myfile.txt)
    최종 경로가 “files//myfile.txt”가 되어 “//” 발생 가능


Query Parameters

from fastapi import FastAPI

app = FastAPI()

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]


@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
    return fake_items_db[skip : skip + limit]
  • 함수 파라미터 중 패스 파라미터로 기재되지 않은 파라미터들은
    자동으로 쿼리 파라미터로 지정된다
  • 쿼리는 키-밸류 페어로 구성되며 URL 뒤에 “?”으로 시작해 “&”으로 구분된다
    예제 -> http://127.0.0.1:8000/items/?skip=0&limit=10
    
  • URL의 부분인 이상 쿼리 파라미터의 타입들은 String이지만,
    타입을 명시해뒀다면, 지정된 타입으로 자동 형변환이 된다

Defaults

  • 기본값을 지정했다면 해당 파라미터를 생략해도 기본값으로 값이 전달된다

Optional parameters

  • 아래와 같이 Optional과 기본값으로 None을 설정하면
    비필수 파라미터를 지정할 수 있다
      @app.get("/items/{item_id}")
      async def read_item(item_id: str, q: Optional[str] = None):
          if q:
              return {"item_id": item_id, "q": q}
          return {"item_id": item_id}
    

Query parameter type conversion

  • bool 타입도 쿼리 파라미터로 받을 수 있으며,
    falsy한 값이 아니라면 True값의 bool로 자동 변환해준다

Multiple path and query parameters

  • 다수의 패스 파라미터 또한 동시에 사용가능하며,
    이 때에는 딱히 특정한 순서대로 선언할 필요가 없다

Required query parameters

  • 쿼리 파라미터의 기본값을 지정하지 않으면 필수 파라미터가 된다
    @app.get("/items/{item_id}")
    async def read_user_item(item_id: str, needy: str):
      item = {"item_id": item_id, "needy": needy}
      return item
    
  • 만약 필수 파라미터의 값을 생략하면 아래와 같은 error가 발생한다
      {
          "detail": [
              {
                  "loc": [
                      "query",
                      "needy"
                  ],
                  "msg": "field required",
                  "type": "value_error.missing"
              }
          ]
      }
    
  • 패스 파라미터에서 다뤘던 Enum 또한 같은 방식으로 사용이 가능하다


Request Body

Query Parameters and String Validations

Path Parameters and Numeric Validations

댓글남기기