본문 바로가기

MLOps

[FastAPI] 경로 매개변수, 쿼리 매개변수

경로 매개변수

경로 매개변수(Path Parameters)는 흔히 우리가 말하는 URL 경로에 들어가는 변수를 의미한다. 아래의 예제에서 user_id가 경로 매개변수이다.

 

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/{user_id}")
def get_user(user_id: int): # 타입 힌트 int
    return {"user_id": user_id}

 

http 통신은 타입 없이 전부 문자열로만 통신한다. 따라서 타입힌트를 넣어준다.

 

정수형 타입이 아닌 값을 호출하면, 다음과 같이 응답코드 422와 함께 위와 같은 오류 메시지가 나타난다.

$ http :8000/users/12.3
HTTP/1.1 422 Unprocessable Entity
content-length: 104
content-type: application/json
date: Wed, 14 Apr 2021 13:59:06 GMT
server: uvicorn

{
    "detail": [
        {
            "loc": [
                "path",
                "user_id"
            ],
            "msg": "value is not a valid integer",
            "type": "type_error.integer"
        }
    ]
}

 

순서 문제

경로 동작을 만들 때 고정 경로를 갖고 있는 상황이 있을 수 있다. 이때 순서를 고려해야 한다.

 

ex) /users/me는 현재 사용자의 데이터를 가져온다.

 

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/{user_id}")
def get_user(user_id: int):
    return {"user_id": user_id}


# 추가: 현재 유저를 반환하는 앤드포인트
@app.get("/users/me")
def get_current_user():
    return {"user_id": 123}

 

위 코드를 실행한 후, http://localhost:8000/users/me 를 호출하면 아래와 같은 에러가 발생한다. /users/{user_id}는 매개변수 user_id의 값을 "me"라고 "생각하여" /users/me도 연결하기 때문이다.

 

$ http :8000/users/me
HTTP/1.1 422 Unprocessable Entity
content-length: 104
content-type: application/json
date: Wed, 14 Apr 2021 14:28:16 GMT
server: uvicorn

{
    "detail": [
        {
            "loc": [
                "path",
                "user_id"
            ],
            "msg": "value is not a valid integer",
            "type": "type_error.integer"
        }
    ]
}

 

경로 동작 순차적으로 평가되기 때문에 /users/{user_id} 이전에 /users/me를 먼저 선언해야 한다.

 

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/me")
def get_current_user():
    return {"user_id": 123}


@app.get("/users/{user_id}")
def get_user(user_id: int):
    return {"user_id": user_id}

 

쿼리 매개변수

쿼리는 쿼리는 URL에서 ? 후에 나오고 &로 구분되key=value 같은 키-값 쌍의 집합이다.

예를 들어, http://127.0.0.1:8000/items/?skip=0&limit=10 에서

쿼리 매개변수는:

  • skip: 값 0
  • limit: 값 10
from fastapi import FastAPI

app = FastAPI()


@app.get("/users")
def get_users(limit: int):
    return {"limit": limit}
$ http ':8000/users?limit=100'

 

기본값을 지정해 줄 수도 있고, 선택적으로 하려면 None 값을 기본값으로 주면 된다.

from fastapi import FastAPI

app = FastAPI()


@app.get("/users")
def get_users(limit: int = 100):  # 추가: 기본값
    return {"limit": limit}

 

논리형(Boolean)의 경우 파이썬은 True이고, JSON은 true이다. 하지만 pydantic 을 사용하기 때문에 bool형인 경우 True, true, TRUE, 1 전부 True이다. 그러므로 타입만 지정해주면 자유롭게 사용할 수 있다.

from fastapi import FastAPI

app = FastAPI()


@app.get("/users")
def get_users(is_admin: bool, limit: int = 100):  # 추가: q
    return {"is_admin": is_admin, "limit": limit}  # 추가: q

 

문자열 열거형

파이썬의 열거체(Enumeration)를 지원하고, 다중 상속도 가능하다.

from enum import Enum

from fastapi import FastAPI

app = FastAPI()

class UserLevel(str, Enum):
    a = "a"
    b = "b"
    c = "c"


@app.get("/users")
def get_users(grade: UserLevel):
    return {"grade": grade}

 

만약 정의하지 않은 값로 호출하면 에러가 발생한다.

$ http ':8000/users?grade=d'
HTTP/1.1 422 Unprocessable Entity
content-length: 173
content-type: application/json
date: Wed, 14 Apr 2021 15:42:42 GMT
server: uvicorn

{
    "detail": [
        {
            "ctx": {
                "enum_values": [
                    "a",
                    "b",
                    "c"
                ]
            },
            "loc": [
                "query",
                "grade"
            ],
            "msg": "value is not a valid enumeration member; permitted: 'a', 'b', 'c'",
            "type": "type_error.enum"
        }
    ]
}

 

ex) 열거형 클래스로 모델이름을 사용하여, 타입 어노테이션으로 경로 매개변수로 사용할 수도 있다.

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 is 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"}

경로 매개변수에 사용할 수 있는 값은 미리 정의되어 있으므로 대화형 문서에서 표시된다.

 

참고

https://fastapi.tiangolo.com/ko/tutorial/path-params/#_11

 

경로 매개변수 - FastAPI

경로 매개변수 파이썬 포맷 문자열이 사용하는 동일한 문법으로 "매개변수" 또는 "변수"를 경로에 선언할 수 있습니다: from fastapi import FastAPI app = FastAPI() @app.get("/items/{item_id}") async def read_item(item_

fastapi.tiangolo.com

https://fastapi.tiangolo.com/ko/tutorial/query-params/

 

쿼리 매개변수 - FastAPI

쿼리 매개변수 경로 매개변수의 일부가 아닌 다른 함수 매개변수를 선언할 때, "쿼리" 매개변수로 자동 해석합니다. from fastapi import FastAPI app = FastAPI() fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"

fastapi.tiangolo.com