본문 바로가기
기타

[Python/FastAPI] 1. API 정의 - HTTP Request (1)

2023. 3. 16.
반응형

지난 포스트에서는 FastAPI가 무엇이고 어떤 장점이 있는지 알아보았습니다. 이번에는 실무에 바로 적용하기 위해 가장 먼저 알아야할 HTTP Request 기능을 알아보겠습니다.

 

 

[Python/FastAPI] 0. Overview

새로 이직한 회사에서 Python의 FastAPI를 사용하고 있어 FastAPI에 대해 알아보았습니다. 기존 코드를 이해하기 위해 API 구현 관련 기능들을 앞으로 알아볼 계획입니다. 이번 포스트에서는 FastAPI가

dct-wonjung.tistory.com

 

FastAPI의 API 정의 - HTTP Request

FastAPI에서 API를 정의하려면 어떻게 해야할까? HTTP 요청에 필요한 정보들은 다음과 같다.

- Method
- URL
- Header
- Parameter
- Body
- ...

클라이언트가 요청할 수 있는 API를 만들기 위해서 위의 요소들을 정의해주어야 한다. FastAPI에서는 이 요소들을 어떻게 표현하는지 알아보자.

 

API의 Path Operation

  • 데코레이터를 이용해 경로와 동작을 정의한다. 여기서 경로는 URL Path, 동작은 HTTP Method를 의미한다.
    • 파이썬에서는 @something과 같은 문법을 Decorator(데코레이터)라고 한다.
@app.get("/")
@app.post("/member")
@app.put()
@app.delete()
  • 위처럼 데코레이터를 함수에 붙여, 요청이 들어왔을 때 매핑된 함수가 호출되도록 한다. 
@app.get("/users/me")
async def func1():
	...

@app.get("/users/{user_name}")
async def func2():
	...
  • path operation은 등록 순서대로 우선순위를 갖는다. 따라서 더 구체적은 API를 먼저 선언해야 한다.
    • GET /users/me를 호출하면 func1 함수가 실행되고, GET /users/you를 호출하면 func2가 실행된다.

 

API 정의 시 파라미터의 구분

  • FastAPI에서는 Path parameter, Query parameter, Request body를 모두 함수의 파라미터에 선언한다.
  • FastAPI는 이들을 어떻게 구분해서 API를 만들어줄까?
    • 경로내에 선언되어 있는 변수 -> Path parameter
    • singular type으로 선언된 변수 -> Query parameter
      • singular type: int, float, str, bool 등
    • Pydantic 모델(BaseModel)로 정의된 타입의 변수 -> Request body
  • 또한 Path, Query, Body가 기본값인 변수도 각 유형의 파라미터로 인식한다.

 

Path parameter 정의

# path parameter 이용
@app.get("/items/{item_id}")
def read_item(item_id):
	return {"item_id": item_id}

# 타입을 지정하는 경우
@app.get("/items/{item_id}")
def read_item(item_id: int):
	return {"item_id": item_id}
  • 경로 내에 {something}을 이용하여 경로 파라미터를 선언할 수 있다.
  • 메소드 파라미터 선언부에 타입을 함께 지정할 수 있다.
    • FastAPI가 자동으로 요청값을 파싱한다.
    • 데이터 타입이 맞지 않아 파싱에 실패하면 HTTP 오류를 반환한다.

경로를 포함하는 path parameter

  • /files/home/wjy/hello.txt에서 /files/{file_path}를 사용하여 “/home/wjy/hello.txt”라는 경로를 얻고 싶을 수 있다.
  • OpenAPI에서는 이를 선언하는 방법을 지원하지 않지만, FastAPI에서는 Starlette 내부 도구를 이용하여 지원하고 있다.
@app.get("/files/{file_path:path}")
async def read_file(file_path: str):
	return {"file_path": file_path}
  • :path를 통해 파라미터가 경로 형식이어야 함을 나타낼 수 있다.
  • /로 시작하는 경로의 경우에는 이중 슬래시로 표현해야 한다.
    • (ex) /files//home/wjy/hello.txt

Enum 사용하기

from enum import Enum

...

class BrowserName(str, Enum):
	chrome = "chrome"
	whale = "whale"
	safari = "safari"

...

@app.get("/browsers/{browser_name}")
async def get_browser(browser_name: BrowserName):
	if browser_name is BrowserName.chrome:
    return {"browser_name": browser_name, "message": "this is chrome"}
  if browser_name is BrowserName.whale:
    return {"browser_name": browser_name, "message": "this is whale of Naver"}
  return {"browser_name": browser_name, "message": "this is others"}
  • Path parameter, Query parameter에 enum 타입을 사용할 수 있다.
    • Enum을 임포트하여 str와 Enum을 상속하는 서브 클래스를 생성한다.
    • 파라미터에 해당 서브 클래스 타입을 지정한다.
  • browser_name 파라미터를 BrowserName 타입으로 선언했기 때문에, 해당 값이 string 타입이면서 범위 안에 속해야 함을 FastAPI가 알고 검증할 수 있다.
  • browser_name.value로 enum값에 직접 접근할 수 있다.
    • browser_name (enum의 멤버)로 반환하면 FastAPI가 응답 생성 시에 enum 값으로 변환해준다.

 

Path로 추가기능 사용하기

from fastapi import Path

...

# use Path as default
@app.get("/items/{item_id}")
async def read_items(item_id: int = Path(title="The ID of the item to get", ge=1)):
	...
  • fastapi의 Path를 사용해서 경로 파라미터에 메타데이터와 제약조건을 추가할 수 있다.
    • int, float → gt, ge, lt, le
728x90
반응형

댓글