시작에 앞서
해당 내용은 <가장 빠른 풀스택을 위한 Flask & FastAPI>, Dave Lee 지음. BJ Public 출판.
내용을 토대로 작성되었습니다. 보다 자세한 사항은 해당 교재를 참고하시기 바랍니다.
이전 내용
FastAPI 요청
웹 애플리케이션에서의 요청(request)은 클라이언트가 서버로부터 정보를 얻거나 서버에 정보를 전달하기 위해 보내는 HTTP 메시지이다. FastAPI 를 사용하면 이러한 요청 데이터를 쉽게 처리하고 관리할 수 있다.
FastAPI 에서 쿼리 매개변수 다루기
FastAPI에서는 Query 클래스를 사용하여 쿼리 매개변수를 선언하고 검증 규칙을 추가할 수 있다. 이 클래스를 함수의 매개변수 기본값으로 사용하면 해당 매개변수가 쿼리 매개변수임을 FastAPI에 알려준다.
★ 쿼리 매개변수: URL에서 ? 기호 뒤에 오는 키-값 쌍으로 이루어진 문자열.
from fastapi import FastAPI, Query
app = FastAPI()
# '/users/' 경로에 대한 GET 요청을 처리하는 경로 연산 정의
# 이 경로 연산은 쿼리 매개변수 'q'를 받아들임
@app.get("/users/")
def read_users(q:str = Query(None, max_length=50)):
# 쿼리 매개변수 'q'는 선택적이며, 최대 길이가 50이라는 제약 조건
# Query()의 첫 번째 인자로 None을 전달함으로써 'q' 가 선택적임을 명시
return {"q": q}
▶ 이 예시에서는 /users/ 경로에 대한 GET 요청을 처리하는 함수 read_users()를 정의했다. 이 함수는 q라는 쿼리 매개변수를 받으며, Query 클래스를 통해 이 매개변수가 선택적이며 최대 길이가 50이라는 것을 FastAPI 에 알려준다.
- curl 명령어
curl -X GET "http://127.0.0.1:800/users/?q=somequery"
▶ 위 curl 명령은 /users/ 엔드포인트로 GET 요청을 보내고, 쿼리 매개변수 q에 "somequery" 값을 전달.
서버는 이 값을 받아 {"q": "somequery"} 형태의 JSON 응답을 반환한다.
Query 클래스의 주요 옵션
Query(default, 옵션리스트)
- default: 매개변수의 기본 값 지정. 이 값이 None 이면 매개변수는 선택적이 된다
[옵션 리스트]
다음 옵션 리스트 중 필요한 설정을 넣을 수 있다.
- alias: 매개변수의 별칭 지정. 이를 통해 URL에서 사용하는 이름과 함수 내에서 사용하는 이름을 다르게 할 수 있다.
- deprecated: 매개변수가 더 이상 사용되지 않음을 명시. 이는 API 문서에 표시되어 사용자가 해당 매개변수를 사용하지 않도록 경고.
- title: 매개변수의 설명 제목을 지정. 이는 주로 API 문서에서 매개변수를 설명할 때 사용
- description: 매개변수에 대한 설명 추가. 이 설명은 API 문서에 표시되어 매개변수의 사용 목적이나 기대되는 값 등을 설명
- min_length & max_length: 문자열 매개변수에 대한 최소 또는 최대 길이 지정
- ge(greater than or equal to): 매개변숫값이 지정된 값 이상이여야 함을 명시
- le(less than or equal to): 매개변숫값이 지정된 값 이하여야 함을 명시
- regex: 매개변숫값이 일치해야 하는 정규 표현식 패턴을 지정
- example: 매개변수의 예시 값 제공. 이는 문서에서 매개변수의 예상 입력값을 보여주는 데 도움.
◆ alias
이 기능은 API의 내부 구현을 숨기거나, 클라이언트에게 보다 친숙한 또는 직관적인 매개변수 이름을 제공하고자 할 때 유용
from fastapi import FastAPI, Query
app = FastAPI()
# '/items/' 경로 연산 정의
# 'internal_query' 매개변수는 외부에서는 'search' 라는 이름의 쿼리 매개변수로 접근
@app.get("/items/")
def read_users(internal_query: str = Query(None, alias="search")):
# 클라이언트는 'search' 라는 이름으로 쿼리 매개변수 전송
# FastAPI 애플리케이션은 이를 'internal_query' 라는 내부 변수로 처리
return {"query_handled": internal_query}
▶ /items/ 경로에 대한 GET 요청을 처리할 때 클라이언트가 search 라는 이름으로 전송한 쿼리 매개변수를 서버 내부에서는 internal_query 라는 변수명으로 처리.
◆ deprecated
특정 쿼리 매개변수가 구식이 되었거나 더이상 사용되지 않을 때 deprecated=True 로 설정하여 API 사용자에게 해당 매개변수를 향후 사용하지 말 것을 권장하는 명확한 신호를 보낸다. (개발자가 API를 진화시키고 변경 사항을 관리)
from fastapi import FastAPI, Query
app = FastAPI()
# '/users/' 경로 연산 정의
# 'q' 매개변수를 deprecated로 표시하여 이 매개변수가 더이상 사용되지 않음을 표시
@app.get("/users/")
def read_users(q:str = Query(None, deprecated=True)):
# 클라이언트는 'q'라는 이름으로 쿼리 매개변수를 전송할 수 있으나,
# 이 매개변수는 곧 지원되지 않을 예정임을 명시
return {"q": q}
[테스트 방법]
1) Swagger UI (http://127.0.0.1:8000/docs)에 접속
2) /users/ 엔드포인트 문서를 확인하면, q 매개변수에 더이상 사용되지 않음을 나타내는 표시를 확인할 수 있다.
◆ description
이 옵션을 사용하면 쿼리 매개변수에 대한 상세한 설명을 추가할 수 있고, 이 설명은 Swagger UI 와 같은 API 문서화 도구에서 해당 쿼리 매개변수 옆에 표시되어 API 사용자가 해당 매개변수의 용도를 쉽게 이해할 수 있게 해준다. (복잡하거나 추가적인 컨텍스트가 필요한 매개변수를 문서화할 때 유용)
from fastapi import FastAPI, Query
app = FastAPI()
# '/info/' 경로 연산 정의
# 'info' 매개변수에 대한 설명을 Query의 description 옵션을 통해 추가
@app.get("/info/")
def read_info(info:str = Query(None, description="정보를 입력해 주세요")):
# 클라이언트는 'info'라는 이름으로 쿼리 매개변수를 전송할 수 있고,
# 이 매개변수에 대한 설명은 Swagger UI에서 확인
return {"info": info}
FastAPI에서 description 옵션을 활용함으로써 API의 사용성을 향상시키고 사용자에게 명확한 지침을 제공할 수 있다. 이는 API의 이해도를 높이고, 사용자가 API를 올바르게 사용할 수 있도록 안내하는 중요한 역할을 한다.
요청 바디
◆ HTTP 프로토콜과 요청
- 프로토콜: 컴퓨터나 원격 장치 간 통신을 위한 규칙의 집합. 이러한 규칙은 네트워크 상에서 정보가 어떻게 전송되어야 하는지를 정의한다.
일반적인 통신 프로토콜에는 TCP/IP, HTTP, FTP 등이 있다.
- HTTP(HyperText Ttransfer Protocol): 웹에서 데이터를 교환하기 위한 프로토콜. WWW(Wordl Wide Web)의 기초가 되는 이 프로토콜은 클라이언트와 서버 간에 HTML 문서나 이미지 같은 리소스를 요청하고 전송하는 데 사용된다.
HTTP는 상태가 없는 프로토콜 이지만, 쿠키 등의 기술을 사용하여 상태 정보를 유지할 수 있다.
- HTTP 요청(HTTP Request): 클라이언트가 서버에 특정 작업을 요청하는 메시지. 이는 일반적으로 웹 브라우저(클라이언트)에서 웹 서버로 정보를 얻거나, 서버상의 데이터를 수정하기 위해 사용된다.
[HTTP 요청 구성]
- Method: 서버에 요청하는 작업의 유형 정의 (예, GET, POST, PUT)
- URL: 요청이 지시되는 리소스의 위치
- Headers: 요청에 대한 메타데이터를 포함하여 인증, 캐싱, 클라이언트 유형 등의 정보를 담음
- Body: 일부 HTTP 메서드(POST, PUT)에서 사용되며, 전송할 데이터를 담음
◆ FastAPI에서의 요청 바디 처리
요청 바디(request body): 클라이언트가 서버로 전송하는 데이터의 본문.
주로 POST, PUT, PATCH 메서드를 사용할 때 볼 수 있으며, 서버가 수행해야 할 상세한 작업이나 서버에 제출할 데이터 포함.
HTTP 프로토콜은 이러한 요청을 사용하여 웹상의 다양한 작업을 수행한다.
FastAPI 는 요청 바디를 처리하는 강력한 매커니즘을 제공하는데, 클라이언트로부터 서버로 전송되는 데이터 (특히 복잡한 구조의 데이터)를 캡처하고 처리할 때 Body() 함수를 사용(POST, PUT, PATCH 매서드에서 사용됨).
GET 요청은 데이터를 서버로부터 검색하기 위해 사용되며, 일반적으로 데이터를 전송하는 바디를 포함하지 않는다.
GET 요청의 데이터는 URL의 일부인 쿼리 매개변수 또는 URL 경로에 포함되어 전송된다. 따라서 GET 요청에서는 Body() 함수를 사용하지 않으며, 대신 Query(), Path(), 또는 Header() 와 같은 다른 함수들을 사용하여 매개변수를 정의한다.
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
def read_items(item_id: int = Query(...)):
# item_id는 쿼리 매개변수를 통해 전달
return {"item_id": item_id}
Body() 함수는 이러한 경우에는 적합하지 않으며, 그 사용은 요청 바디가 필요한 POST, PUT, PATCH 메서드에 국한된다.
from fastapi import FastAPI, Body
app = FastAPI()
# POST 메서드로 '/items/' 경로에 데이터를 전송하는 경로 연산 정의
@app.post("/items/")
def create_item(item: dict = Body(...)): # (...)은 필수 / (None)은 선택
# 클라이언트가 전송하는 JSON 바디 데이터를 'item' 이라는 변수로 받음
# 'dict' 타입은 JSON 바디가 Python 딕셔너리로 파싱될 것임을 나타냄
# Body(...)는 이 필드가 클라이언트로부터 필수로 제공되어야 함을 나타냄
return {"item": item}
▶ create_item() 함수는 클라이언트로부터 JSON 형식의 데이터를 받아 처리.
여기서 Body(...)의 줄임표는 해당 필드가 필수라는 것을 의미, 클라이언트가 요청 바디에 'item' 데이터를 포함하지 않으면 FastAPI는 에러 발생.
* 필드가 필수가 아닌 경우에는 (선택) Body(None)을 사용하여 기본값을 None으로 설정 가능.
[테스트: curl 명령어]
POST 방식이므로 curl 명령으로 데이터 전송
curl -X POST "http://127.0.0.1:8000/items/" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"key\":\"value\"}"
curl 명령은 POST 메서드를 사용하여 /items/ 경로로 JSON 데이터 전송.
서버는 {"item": {"key": "value"}} 형태의 JSON 응답 반환. 이 응답은 클라이언트가 보낸 데이터가 서버에 의해 올바르게 수신되고 처리되었음을 나타낸다.
◆ 요청 바디의 다양한 옵션
FastAPI에서 Body() 함수를 사용하여 요청 바디를 정의할 때, 추가적인 옵션을 제공하여 API의 요구 사항을 더욱 세밀하게 조정할 수 있다. 이러한 옵션들을 통해 클라이언트로부터 받은 데이터를 더욱 정밀하게 제어하고, API 문서화를 통해 사용자에게 유용한 정보를 제공할 수 있다.
from fastapi import FastAPI, Body
app = FastAPI()
@app.post("/advanced_items/")
def create_advanced_item(
item: dict = Body(
defalut=None, # 필수가 아닌 필드 기본값 설정
example={"key": "value"}, # 문서에 표시될 예시 값
media_type="application/json", # 미디어 타입 명시
alias="item_alias", # 별칭 설정 (실제 사용 X)
title="Sample Item", # 문서 제목
description="This is a sample item", # 상세 설명
deprecated=False)): # 사용 중단 여부
return {"item": item}
[코드에 사용된 옵션의 기능들]
- default: 이 필드가 선택적임을 나타내며, 기본값으로 None을 설정하여 바디 데이터가 제공되지 않은 경우 처리.
- example: 자동 문서화 도구에서 해당 필드에 대해 예시 값 제공. 이는 API 사용자가 요청을 구성하는 방법을 이해하는 데 도움.
- media_type: 요청 바디의 미디어 타입 지정. (여기서는 JSON 형식의 데이터 타입을 전송받을 것임을 명시)
- alias: 요청 바디의 JSON 필드에 대한 별칭 설정.
- title: 문서에서 바디에 대해 보여줄 제목 설정.
- description: 요청 바디에 대한 상세 설명 제공.
- deprecated: 이 필드가 더 이상 사용되지 않는다고 표시하는 옵션. (여기서는 False 로, 사용이 중단되지 않음)
[테스트]
curl -X POST "http://127.0.0.1:8000/advanced_items/" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"key\":\"value\"}"
제목과 설명은 FastAPI의 자동 문서화 기능(하단 링크) 에서 확인할 수 있다.
http://127.0.0.1:8000/docs
예시에서 제시된 alias는 실제 코드에서 사용되지 않으므로, 요청 바디는 {"key": "value"} 형태로 보내야 한다.
다음 내용
'[파이썬 Projects] > <파이썬 웹개발>' 카테고리의 다른 글
[파이썬] FastAPI - 템플릿 (0) | 2024.08.21 |
---|---|
[파이썬] FastAPI - 예외 처리(exception handling) (0) | 2024.08.20 |
[파이썬] FastAPI - 응답 클래스 (0) | 2024.08.19 |
[파이썬] FastAPI - 응답 모델 (0) | 2024.08.18 |
[파이썬] FastAPI - Pydantic (2) (0) | 2024.08.17 |