FastAPI 기본개념
Posted by Albert 65Day 12Hour 1Min 5Sec ago [2025-12-03]
1. FastAPI란?
FastAPI는 Python으로 API를 빠르고 쉽게 만들 수 있는 현대적인 웹 프레임워크입니다. 자동 문서화, 빠른 속도, 타입 힌트 활용이 특징입니다.
2. 설치하기
먼저 Python 3.7 이상이 설치되어 있어야 합니다.
' FastAPI와 서버 실행을 위한 uvicorn 설치 pip install fastapi uvicorn
3. 가장 간단한 예제
첫 번째 API를 만들어봅시다. main.py 파일을 생성하세요.
from fastapi import FastAPI
' FastAPI 앱 인스턴스 생성
app = FastAPI()
' 루트 경로에 GET 요청 처리
@app.get("/")
def read_root():
return {"message": "Hello World"}
실행하기:
uvicorn main:app --reload
브라우저에서 http://127.0.0.1:8000에 접속하면 결과를 볼 수 있습니다.
--reload 옵션은 코드 변경 시 자동으로 서버를 재시작합니다.
4. 자동 문서화 확인
FastAPI의 강력한 기능 중 하나입니다.
- Swagger UI: http://127.0.0.1:8000/docs
- ReDoc: http://127.0.0.1:8000/redoc
여기서 API를 직접 테스트할 수 있습니다!
5. 경로 매개변수 (Path Parameters)
URL에 변수를 넣어봅시다.
@app.get("/users/{user_id}")
def read_user(user_id: int):
return {"user_id": user_id, "name": f"User {user_id}"}
http://127.0.0.1:8000/users/5를 호출하면 user_id가 5인 결과를 받습니다.
6. 쿼리 매개변수 (Query Parameters)
URL 뒤에 ?key=value 형태로 전달되는 파라미터입니다.
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}
http://127.0.0.1:8000/items/?skip=5&limit=20처럼 사용합니다.
7. 요청 본문 (Request Body) - POST 요청
데이터를 서버로 보낼 때 사용합니다. Pydantic 모델을 활용합니다.
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
description: str = None ' 선택적 필드
tax: float = None
@app.post("/items/")
def create_item(item: Item):
total = item.price
if item.tax:
total += item.tax
return {"name": item.name, "total_price": total}
8. PUT 요청 (업데이트)
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_id": item_id, "updated_item": item}
9. DELETE 요청
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
return {"message": f"Item {item_id} deleted"}
10. 데이터 검증
Pydantic을 사용한 강력한 검증 예제입니다.
from pydantic import BaseModel, Field
class User(BaseModel):
username: str = Field(..., min_length=3, max_length=20)
email: str = Field(..., regex="^[\w\.-]+@[\w\.-]+\.\w+$")
age: int = Field(..., ge=0, le=120) ' 0 이상, 120 이하
@app.post("/users/")
def create_user(user: User):
return {"user": user}
11. 응답 모델
반환할 데이터의 형태를 지정합니다.
class UserResponse(BaseModel):
username: str
email: str
' 비밀번호 같은 민감한 정보는 제외
@app.post("/users/", response_model=UserResponse)
def create_user(user: User):
' 실제로는 DB에 저장하는 로직
return user
12. 상태 코드 지정
from fastapi import status
@app.post("/items/", status_code=status.HTTP_201_CREATED)
def create_item(item: Item):
return item
13. 예외 처리
from fastapi import HTTPException
items_db = {"item1": "Item 1"}
@app.get("/items/{item_id}")
def read_item(item_id: str):
if item_id not in items_db:
raise HTTPException(status_code=404, detail="Item not found")
return {"item": items_db[item_id]}
14. 종속성 주입 (Dependency Injection)
코드 재사용을 위한 강력한 기능입니다.
from fastapi import Depends
def get_current_user(token: str):
' 실제로는 토큰 검증 로직
if token != "secret-token":
raise HTTPException(status_code=401, detail="Invalid token")
return {"username": "current_user"}
@app.get("/users/me")
def read_current_user(user: dict = Depends(get_current_user)):
return user
15. 파일 업로드
from fastapi import File, UploadFile
@app.post("/upload/")
async def upload_file(file: UploadFile = File(...)):
contents = await file.read()
return {
"filename": file.filename,
"size": len(contents)
}
16. CORS 설정 (프론트엔드 연동)
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], ' 실제로는 특정 도메인만 허용
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
17. 실전 예제: 간단한 TODO API
from typing import List
from pydantic import BaseModel
class Todo(BaseModel):
id: int
title: str
completed: bool = False
todos: List[Todo] = []
@app.get("/todos/", response_model=List[Todo])
def get_todos():
return todos
@app.post("/todos/", response_model=Todo)
def create_todo(todo: Todo):
todos.append(todo)
return todo
@app.put("/todos/{todo_id}", response_model=Todo)
def update_todo(todo_id: int, updated_todo: Todo):
for i, todo in enumerate(todos):
if todo.id == todo_id:
todos[i] = updated_todo
return updated_todo
raise HTTPException(status_code=404, detail="Todo not found")
@app.delete("/todos/{todo_id}")
def delete_todo(todo_id: int):
for i, todo in enumerate(todos):
if todo.id == todo_id:
todos.pop(i)
return {"message": "Todo deleted"}
raise HTTPException(status_code=404, detail="Todo not found")
다음 단계
이제 기본을 익혔으니 다음을 공부해보세요:
- 데이터베이스 연동 (SQLAlchemy, Tortoise ORM)
- 인증/권한 (JWT, OAuth2)
- 백그라운드 태스크
- 테스트 작성
- 배포 (Docker, 클라우드)