return item
@app.get(“/items/”, response_model=List[Item])
async def read_items():
return list(items.values())
@app.get(“/items/{item_name}”, response_model=Item)
async def read_item(item_name: str):
if item_name in items:
return items[item_name]
return {“error”: “Item not found”}
@app.put(“/items/{item_name}”, response_model=Item)
async def update_item(item_name: str, item: Item):
if item_name in items:
items[item_name] = item
return item
return {“error”: “Item not found”}
@app.delete(“/items/{item_name}”, response_model=Item)
async def delete_item(item_name: str):
if item_name in items:
return items.pop(item_name)
return {“error”: “Item not found”}
코드 설명
위의 코드는 Create, Read, Update, Delete 기능을 갖춘 엔드포인트를 정의합니다. POST 메서드는 새로운 아이템을 생성하며, GET 메서드로 모든 아이템을 조회하거나 특정 아이템을 조회할 수 있습니다. PUT 메서드는 기존 아이템을 수정할 때 사용되고, DELETE 메서드는 아이템을 삭제하는 역할을 합니다.
3. CRUD API 테스트하기
CRUD 기능을 테스트하는 테스트 케이스도 추가해보겠습니다.
def test_create_item():
response = client.post("/items/", json={"name": "Item1", "price": 10.0})
assert response.status_code == 200
assert response.json() == {"name": "Item1", "description": None, "price": 10.0, "tax": None}
def test_read_items():
response = client.get("/items/")
assert response.status_code == 200
assert isinstance(response.json(), list)
def test_update_item():
response = client.put("/items/Item1", json={"name": "Item1", "price": 12.0})
assert response.status_code == 200
assert response.json() == {"name": "Item1", "description": None, "price": 12.0, "tax": None}
def test_delete_item():
response = client.delete("/items/Item1")
assert response.status_code == 200
assert response.json() == {"name": "Item1", "description": None, "price": 12.0, "tax": None}
코드 설명
각 테스트 함수는 API의 CRUD 기능을 검증합니다. test_create_item 함수는 새로운 아이템을 생성하고, test_read_items 함수는 모든 아이템을 조회합니다. test_update_item은 특정 아이템을 수정하며, test_delete_item은 아이템을 삭제하는 기능을 테스트합니다.
FastAPI의 보안과 인증
FastAPI는 OAuth2와 JWT 토큰 기반 인증을 지원합니다. 보안이 필요한 API 엔드포인트에 대한 인증 방법을 설명하겠습니다.
1. OAuth2PasswordBearer 사용하기
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
# 사용자 인증 로직 (여기서는 생략)
return {"access_token": form_data.username, "token_type": "bearer"}
2. 보호된 엔드포인트 만들기
로그인 후 액세스 토큰을 통해 보호된 엔드포인트를 만들어보겠습니다.
@app.get("/secure-data")
async def read_secure_data(token: str = Depends(oauth2_scheme)):
return {"data": "This is protected data"}
코드 설명
위 코드는 /token 경로에서 로그인 시 액세스 토큰을 생성하고, 생성된 토큰을 통해 /secure-data 경로에 접근하도록 설정합니다. Depends()를 사용하여 인증이 필요한 기능을 구현했습니다.
3. 보안 테스트
보호된 엔드포인트를 테스트하기 위해 인증 후 토큰을 사용할 수 있습니다.
def test_secure_data():
response = client.post("/token", data={"username": "testuser", "password": "testpassword"})
token = response.json().get("access_token")
response = client.get("/secure-data", headers={"Authorization": f"Bearer {token}"})
assert response.status_code == 200
assert response.json() == {"data": "This is protected data"}
결론
이 포스트에서는 FastAPI를 사용하여 간단한 API 서버를 구축하고, FastAPI의 테스트 클라이언트를 활용하여 다양한 API 엔드포인트를 테스트하는 방법에 대해 배웠습니다. FastAPI를 통해 고성능의 API를 쉽게 생성할 수 있으며, TestClient를 이용해 안정적이고 신뢰성 있는 테스트를 진행할 수 있습니다. 다양한 기능과 확장성을 바탕으로 FastAPI를 활용한 프로젝트를 진행해보시길 바랍니다.