FastAPI 시작하기
FastAPI로 빠르고 현대적인 웹 API를 만드는 방법을 배워봅시다.
FastAPI란?
FastAPI는 Python으로 API를 빠르게 개발할 수 있는 현대적인 웹 프레임워크입니다. 타입 힌트를 활용하여 자동으로 데이터 검증과 문서화를 제공합니다.
주요 특징
- 빠른 성능 - Node.js, Go와 비슷한 수준의 속도
- 자동 문서화 - Swagger UI, ReDoc 자동 생성
- 타입 안정성 - Python 타입 힌트 활용
- 비동기 지원 - async/await 완벽 지원
- 쉬운 학습 - 직관적이고 간단한 API
왜 FastAPI인가?
# Flask (전통적)
@app.route('/items/<int:item_id>')
def read_item(item_id):
# 수동으로 검증 필요
if item_id < 0:
return {"error": "Invalid ID"}, 400
return {"item_id": item_id}
# FastAPI (현대적)
@app.get("/items/{item_id}")
def read_item(item_id: int):
# 자동 검증, 자동 문서화
return {"item_id": item_id}
설치하기
# FastAPI 설치
pip install fastapi
# ASGI 서버 (Uvicorn)
pip install "uvicorn[standard]"
# 한 번에 설치
pip install "fastapi[all]"
첫 번째 API
가장 간단한 FastAPI 애플리케이션을 만들어봅시다.
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello, FastAPI!"}
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
서버 실행
# 기본 실행
uvicorn main:app --reload
# 포트 지정
uvicorn main:app --reload --port 8080
# 호스트 지정 (외부 접속 허용)
uvicorn main:app --reload --host 0.0.0.0
자동 문서 확인
서버를 실행한 후 다음 URL로 접속하세요:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI JSON: http://localhost:8000/openapi.json
경로 파라미터
URL 경로에서 값을 추출할 수 있습니다.
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/{user_id}/items/{item_id}")
def get_user_item(user_id: int, item_id: str):
return {"user_id": user_id, "item_id": item_id}
# Enum으로 제한
from enum import Enum
class ModelName(str, Enum):
alexnet = "alexnet"
resnet = "resnet"
lenet = "lenet"
@app.get("/models/{model_name}")
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"}
# 파일 경로 (특수 케이스)
@app.get("/files/{file_path:path}")
def read_file(file_path: str):
return {"file_path": file_path}
경로 파라미터 검증
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(
item_id: int = Path(
..., # 필수 파라미터
title="Item ID",
description="조회할 아이템의 ID",
ge=1, # greater than or equal (>=)
le=1000 # less than or equal (<=)
)
):
return {"item_id": item_id}
쿼리 파라미터
URL의 쿼리 스트링에서 값을 받을 수 있습니다.
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
# 기본 쿼리 파라미터
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}
# 선택적 파라미터
@app.get("/items/{item_id}")
def read_item(item_id: str, q: Optional[str] = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
# 여러 값 받기
@app.get("/items/")
def read_items(q: Optional[list[str]] = None):
return {"q": q}
# 요청: /items/?q=foo&q=bar
# 응답: {"q": ["foo", "bar"]}
# 불린 파라미터
@app.get("/items/{item_id}")
def read_item(item_id: str, short: bool = False):
item = {"item_id": item_id}
if not short:
item.update(
{"description": "This is an amazing item"}
)
return item