목록으로

프로그래밍 · Python

Python FastAPI 실전 가이드: 개념, 설치, API 서버 개발과 배포까지

BeanCon
Python FastAPI API 서버 개발을 표현한 대표 이미지

Python FastAPI의 개념과 설치부터 Path/Query Parameter, Request Body, Response Model, Router, CRUD, DB 연동, 인증, 테스트, 배포, 실무 프로젝트 구조까지 정리했습니다.

목차

1. FastAPI란?

FastAPI는 Python으로 API 서버를 빠르고 안정적으로 개발할 수 있도록 만든 현대적인 웹 프레임워크입니다. 공식 설명에 따르면 FastAPI는 Python 표준 타입 힌트를 기반으로 API를 구축하는 고성능 웹 프레임워크입니다.

FastAPI는 이름처럼 빠른 API 개발에 초점을 둡니다. 단순히 실행 속도만 빠른 것이 아니라, 개발자가 코드를 작성하고 테스트하고 문서화하는 전체 흐름을 빠르게 만들어줍니다.

FastAPI가 많이 사용되는 분야
  • REST API 서버
  • 백엔드 서비스
  • AI 모델 서빙 API
  • RAG 시스템 API
  • 데이터 처리 서버
  • 사내 자동화 API
  • 마이크로서비스
  • 관리자 도구용 백엔드

FastAPI의 가장 큰 매력은 Python 타입 힌트만 잘 작성해도 요청 검증, 응답 직렬화, API 문서 생성이 자동으로 이루어진다는 점입니다.

2. FastAPI가 주목받는 이유

기존 Python 웹 프레임워크로는 Django와 Flask가 많이 사용되었습니다. Django는 강력하지만 구조가 크고, Flask는 가볍지만 기능을 직접 조립해야 하는 경우가 많습니다.

FastAPI는 그 중간에서 가볍지만 실무에 필요한 기능을 갖추고 있고, 코드량은 줄이면서도 타입 안정성과 문서화를 강화합니다.

특징설명
빠른 개발적은 코드로 API 서버 구현 가능
높은 성능ASGI 기반 비동기 처리 지원
타입 힌트 기반Python 타입으로 요청/응답 검증
자동 문서화Swagger UI, ReDoc 자동 생성
Pydantic 연동데이터 검증과 직렬화 지원
의존성 주입인증, DB 세션, 공통 로직 재사용 가능
비동기 지원async, await 기반 고성능 API 개발 가능

FastAPI는 OpenAPI 기반 문서를 자동 생성하며, API 경로, 파라미터, 요청 본문, 보안 정보 등을 표준화된 방식으로 표현할 수 있습니다.

3. FastAPI 기본 아키텍처 이해

FastAPI 요청 처리 흐름
Client
HTTP Request
FastAPI Router
Path Operation Function
Business Logic / Database / External API
Response Model
HTTP Response

예를 들어 사용자가 /users/1 주소로 요청을 보내면 FastAPI는 해당 URL과 HTTP Method를 기준으로 실행할 함수를 찾습니다.

@app.get("/users/{user_id}")
def read_user(user_id: int):
    return {"user_id": user_id}

여기서 중요한 점은 user_id: int입니다. FastAPI는 이 타입 힌트를 보고 사용자가 문자열을 넣었는지, 숫자를 넣었는지 자동으로 검사합니다. 잘못된 값이 들어오면 개발자가 직접 예외 처리를 하지 않아도 자동으로 오류 응답을 반환합니다.

4. FastAPI 설치 준비

FastAPI를 사용하려면 Python이 먼저 설치되어 있어야 합니다. Python 공식 다운로드 페이지에서는 여러 활성 버전이 제공되고 있으며, 2026년 기준 Python 3.14, 3.13, 3.12, 3.11 등이 활성 릴리스로 안내되고 있습니다.

실무에서는 보통 Python 3.11 이상을 권장합니다.

python --version

# Mac/Linux
python3 --version

5. 가상환경 생성

프로젝트별 패키지 충돌을 막기 위해 가상환경을 사용하는 것이 좋습니다.

macOS / Linux

mkdir fastapi-demo
cd fastapi-demo

python3 -m venv .venv
source .venv/bin/activate

Windows PowerShell

mkdir fastapi-demo
cd fastapi-demo

python -m venv .venv
.venv\Scripts\Activate.ps1

가상환경이 활성화되면 터미널 앞에 (.venv)처럼 표시됩니다.

6. FastAPI와 Uvicorn 설치

FastAPI 서버를 실행하려면 ASGI 서버가 필요합니다. 대표적으로 Uvicorn을 사용합니다. Uvicorn은 Python용 ASGI 웹 서버이며 HTTP/1.1과 WebSocket을 지원합니다.

pip install fastapi uvicorn

# 또는 표준 옵션 포함
pip install "fastapi[standard]"

# 설치 확인
pip list

7. 첫 번째 FastAPI 서버 만들기

프로젝트 루트에 main.py 파일을 생성합니다.

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {
        "message": "Hello, FastAPI!"
    }

서버를 실행합니다.

uvicorn main:app --reload

실행 후 브라우저에서 http://127.0.0.1:8000 주소로 접속합니다.

{
  "message": "Hello, FastAPI!"
}
항목의미
mainPython 파일 이름
appFastAPI 인스턴스 변수명
--reload코드 변경 시 서버 자동 재시작

8. 자동 API 문서 확인

FastAPI의 강력한 장점 중 하나는 API 문서를 자동 생성한다는 것입니다.

http://127.0.0.1:8000/docs

http://127.0.0.1:8000/redoc

Swagger UI 문서와 ReDoc 문서를 통해 API를 브라우저에서 확인하고 테스트할 수 있습니다. FastAPI 공식 튜토리얼도 기능별로 단계적으로 학습할 수 있도록 구성되어 있습니다.

9. Path Parameter 사용하기

Path Parameter는 URL 경로 안에 들어가는 변수입니다.

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
def read_item(item_id: int):
    return {
        "item_id": item_id
    }
요청응답
GET /items/10{ "item_id": 10 }
GET /items/apple숫자가 아닌 값이므로 FastAPI가 자동으로 검증 오류를 반환

10. Query Parameter 사용하기

Query Parameter는 URL 뒤에 ?key=value 형태로 전달되는 값입니다.

@app.get("/search")
def search_items(keyword: str, page: int = 1):
    return {
        "keyword": keyword,
        "page": page
    }
요청응답
GET /search?keyword=python&page=2{ "keyword": "python", "page": 2 }
page: int = 1

11. Request Body 처리하기

POST, PUT 요청에서는 보통 JSON Body를 사용합니다. FastAPI에서는 Pydantic 모델을 사용해 요청 데이터를 정의합니다.

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float
    is_available: bool = True

@app.post("/items")
def create_item(item: Item):
    return {
        "message": "Item created",
        "item": item
    }
{
  "name": "Keyboard",
  "price": 59000,
  "is_available": true
}

FastAPI는 이 JSON을 자동으로 Item 객체로 변환하고 타입을 검증합니다.

12. Response Model 사용하기

응답 구조를 명확하게 제한하고 싶다면 response_model을 사용합니다.

from pydantic import BaseModel

class UserResponse(BaseModel):
    id: int
    name: str
    email: str

@app.get("/users/{user_id}", response_model=UserResponse)
def get_user(user_id: int):
    return {
        "id": user_id,
        "name": "Kim",
        "email": "kim@example.com",
        "password": "secret"
    }

응답에는 password가 포함되지 않습니다. 이 방식은 민감한 정보 노출을 막는 데 매우 유용합니다.

{
  "id": 1,
  "name": "Kim",
  "email": "kim@example.com"
}

13. HTTP Method별 API 작성

@app.get("/items")
def list_items():
    return {"message": "list"}

@app.post("/items")
def create_item():
    return {"message": "create"}

@app.put("/items/{item_id}")
def update_item(item_id: int):
    return {"message": "update", "item_id": item_id}

@app.delete("/items/{item_id}")
def delete_item(item_id: int):
    return {"message": "delete", "item_id": item_id}
Method용도
GET조회
POST생성
PUT전체 수정
PATCH일부 수정
DELETE삭제

14. 비동기 API 개발

FastAPI는 async def를 지원합니다.

@app.get("/async-example")
async def async_example():
    return {
        "message": "async response"
    }

비동기 함수는 외부 API 호출, 비동기 DB 접근, 파일 처리, WebSocket 등 I/O 작업이 많은 서버에서 유리합니다.

하지만 무조건 async를 붙인다고 빨라지는 것은 아닙니다. CPU 연산이 많은 작업은 비동기보다 별도 워커, 큐, 백그라운드 작업 구조가 더 적합할 수 있습니다.

15. 의존성 주입 Depends 이해하기

FastAPI의 핵심 기능 중 하나가 Dependency Injection, 즉 의존성 주입입니다. 공식 문서에 따르면 의존성 주입은 path operation 함수가 필요한 요소를 선언하면 FastAPI가 해당 의존성을 제공하는 방식입니다.

from fastapi import Depends, FastAPI

app = FastAPI()

def common_parameters(page: int = 1, size: int = 10):
    return {
        "page": page,
        "size": size
    }

@app.get("/items")
def read_items(params: dict = Depends(common_parameters)):
    return params
요청응답
GET /items?page=2&size=20{ "page": 2, "size": 20 }
의존성 주입이 자주 사용되는 상황
  • DB 세션 주입
  • 로그인 사용자 확인
  • JWT 인증 처리
  • 공통 파라미터 처리
  • 권한 검사
  • 설정 객체 주입
  • 서비스 클래스 주입

16. Router로 API 구조 분리하기

프로젝트가 커지면 모든 API를 main.py에 작성하면 관리가 어렵습니다. 다음처럼 구조를 나누는 것이 좋습니다.

fastapi-demo/
 ├── main.py
 ├── routers/
 │   ├── users.py
 │   └── items.py
 ├── schemas/
 │   └── user.py
 ├── services/
 │   └── user_service.py
 └── database.py

routers/users.py

from fastapi import APIRouter

router = APIRouter(
    prefix="/users",
    tags=["Users"]
)

@router.get("/")
def list_users():
    return [
        {"id": 1, "name": "Kim"},
        {"id": 2, "name": "Lee"}
    ]

main.py

from fastapi import FastAPI
from routers import users

app = FastAPI()

app.include_router(users.router)

이제 GET /users 주소로 접근할 수 있습니다.

17. 간단한 CRUD API 서버 만들기

메모리 기반 Todo API를 만들어보겠습니다.

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()

class TodoCreate(BaseModel):
    title: str
    completed: bool = False

class TodoResponse(BaseModel):
    id: int
    title: str
    completed: bool

todos = []
next_id = 1

@app.post("/todos", response_model=TodoResponse)
def create_todo(todo: TodoCreate):
    global next_id

    new_todo = {
        "id": next_id,
        "title": todo.title,
        "completed": todo.completed
    }

    todos.append(new_todo)
    next_id += 1

    return new_todo

@app.get("/todos", response_model=list[TodoResponse])
def list_todos():
    return todos

@app.get("/todos/{todo_id}", response_model=TodoResponse)
def get_todo(todo_id: int):
    for todo in todos:
        if todo["id"] == todo_id:
            return todo

    raise HTTPException(status_code=404, detail="Todo not found")

@app.put("/todos/{todo_id}", response_model=TodoResponse)
def update_todo(todo_id: int, todo_update: TodoCreate):
    for todo in todos:
        if todo["id"] == todo_id:
            todo["title"] = todo_update.title
            todo["completed"] = todo_update.completed
            return todo

    raise HTTPException(status_code=404, detail="Todo not found")

@app.delete("/todos/{todo_id}")
def delete_todo(todo_id: int):
    for todo in todos:
        if todo["id"] == todo_id:
            todos.remove(todo)
            return {"message": "Todo deleted"}

    raise HTTPException(status_code=404, detail="Todo not found")

이 예제는 DB 없이 메모리에 데이터를 저장합니다. 서버를 재시작하면 데이터는 사라집니다. 실무에서는 MySQL, PostgreSQL, SQLite, MongoDB 같은 데이터베이스를 연결합니다.

18. FastAPI와 데이터베이스 연동 개념

실무 FastAPI 서버 구조
API Router
Service Layer
Repository / ORM
Database
방식설명
SQLAlchemyPython 대표 ORM
SQLModelFastAPI 생태계와 잘 어울리는 ORM
Tortoise ORM비동기 ORM
asyncpgPostgreSQL 비동기 드라이버
aiomysqlMySQL 비동기 드라이버

간단한 구조 예시는 다음과 같습니다.

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/users")
def list_users(db: Session = Depends(get_db)):
    return db.query(User).all()

Depends(get_db)를 사용하면 API 함수마다 DB 연결 생성과 종료를 반복 작성하지 않아도 됩니다.

19. 환경변수 관리

운영 환경에서는 DB 비밀번호, API Key, JWT Secret 등을 코드에 직접 적으면 안 됩니다. .env 파일을 사용합니다.

DATABASE_URL=mysql+pymysql://user:password@localhost:3306/app
JWT_SECRET=my-secret-key

Python에서는 pydantic-settings를 많이 사용합니다.

pip install pydantic-settings

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    database_url: str
    jwt_secret: str

    class Config:
        env_file = ".env"

settings = Settings()

20. CORS 설정

프론트엔드와 백엔드 도메인이 다르면 CORS 설정이 필요합니다. 예를 들어 React, Next.js 프론트엔드가 http://localhost:3000에서 실행되고 FastAPI가 http://localhost:8000에서 실행된다면 CORS를 허용해야 합니다.

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost:3000",
    "https://example.com"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

개발 중에는 *를 사용할 수 있지만, 운영 환경에서는 반드시 허용할 도메인을 명확히 지정하는 것이 좋습니다.

21. 인증과 보안

FastAPI에서 구현할 수 있는 인증 방식
  • API Key 인증
  • Basic Auth
  • OAuth2
  • JWT 인증
  • 세션 기반 인증
  • 외부 인증 서버 연동
JWT 인증 흐름
사용자가 ID/PW로 로그인
서버가 Access Token 발급
클라이언트가 Authorization Header에 토큰 포함
서버가 토큰 검증
정상 토큰이면 API 접근 허용
Authorization: Bearer eyJhbGciOi...
실무 보안 고려사항
  • 비밀번호는 bcrypt 등으로 해시 처리
  • JWT Secret은 환경변수로 관리
  • Access Token 만료 시간 설정
  • Refresh Token 분리
  • HTTPS 사용
  • 관리자 API 접근 제한
  • Swagger 문서 운영 노출 제한

22. 예외 처리

FastAPI에서는 HTTPException으로 명확한 HTTP 오류 응답을 만들 수 있습니다.

from fastapi import HTTPException

@app.get("/users/{user_id}")
def get_user(user_id: int):
    if user_id != 1:
        raise HTTPException(
            status_code=404,
            detail="User not found"
        )

    return {
        "id": 1,
        "name": "Kim"
    }
{
  "detail": "User not found"
}

공통 예외 처리도 가능합니다.

from fastapi import Request
from fastapi.responses import JSONResponse

@app.exception_handler(ValueError)
async def value_error_handler(request: Request, exc: ValueError):
    return JSONResponse(
        status_code=400,
        content={"message": str(exc)}
    )

23. 로깅 구성

운영 서버에서는 print()보다 로깅을 사용해야 합니다.

import logging

logger = logging.getLogger("app")

@app.get("/health")
def health_check():
    logger.info("Health check requested")
    return {"status": "ok"}
실무에서 남기면 좋은 로그
  • 요청 URL
  • 응답 상태 코드
  • 처리 시간
  • 사용자 ID
  • 에러 스택
  • 외부 API 호출 결과
  • DB 오류
  • 인증 실패 기록

24. 테스트 작성

FastAPI는 테스트 작성이 비교적 쉽습니다.

pip install pytest httpx

test_main.py

from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_read_root():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {
        "message": "Hello, FastAPI!"
    }
pytest

API 서버는 기능이 늘수록 예외 케이스가 복잡해집니다. 따라서 CRUD, 인증, 권한, 입력 검증, DB 오류 상황을 테스트로 묶어두는 것이 좋습니다.

25. FastAPI 배포 구조

개발 환경에서는 다음 명령어로 충분합니다.

uvicorn main:app --reload

하지만 운영 환경에서는 --reload를 사용하지 않습니다.

uvicorn main:app --host 0.0.0.0 --port 8000
일반적인 운영 배포 구조
Client
Nginx
Uvicorn / Gunicorn
FastAPI
Database / Redis / External API

Dockerfile

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

requirements.txt

fastapi
uvicorn
pydantic-settings
docker build -t fastapi-demo .
docker run -p 8000:8000 fastapi-demo

26. FastAPI 실무 활용 분야

분야설명
AI API 서버LLM, RAG, 이미지 분석, 음성 인식 모델을 API로 제공할 때 적합합니다.
내부 관리 API사내 시스템 자동화, 배치 트리거, 로그 조회, 관리자 기능 API로 활용할 수 있습니다.
마이크로서비스기능별로 작은 API 서버를 분리할 때 가볍고 빠르게 구성할 수 있습니다.
데이터 파이프라인 API크롤링, ETL, 데이터 정제, 통계 처리 작업을 API로 실행하는 구조에 적합합니다.
프론트엔드 백엔드 서버React, Vue, Next.js 같은 프론트엔드와 연동하기 좋은 REST API 서버를 만들 수 있습니다.
AI API 서버 예시
사용자 질문
FastAPI
Vector DB 검색
LLM 호출
응답 반환

27. FastAPI 장점과 단점

장점

장점설명
개발 속도코드량이 적고 구조가 직관적
자동 문서화Swagger UI, ReDoc 자동 생성
타입 안정성타입 힌트 기반 검증
비동기 지원고성능 I/O 처리 가능
테스트 용이성API 테스트 작성이 쉬움
AI 서비스 친화적Python AI 생태계와 결합 쉬움

단점

단점설명
대규모 기본 구조 부족Django처럼 완성된 풀스택 구조는 아님
설계 자유도 높음팀별 아키텍처 규칙이 필요
비동기 이해 필요잘못 사용하면 오히려 복잡해짐
ORM 선택 고민SQLAlchemy, SQLModel 등 선택 필요
운영 노하우 필요로깅, 모니터링, 배포 구성을 직접 설계해야 함

28. 추천 프로젝트 구조

실무에서는 다음 구조를 추천합니다.

app/
 ├── main.py
 ├── core/
 │   ├── config.py
 │   └── security.py
 ├── api/
 │   └── v1/
 │       ├── routers/
 │       │   ├── users.py
 │       │   └── items.py
 │       └── dependencies.py
 ├── schemas/
 │   ├── user.py
 │   └── item.py
 ├── models/
 │   ├── user.py
 │   └── item.py
 ├── services/
 │   ├── user_service.py
 │   └── item_service.py
 ├── repositories/
 │   ├── user_repository.py
 │   └── item_repository.py
 ├── db/
 │   ├── session.py
 │   └── base.py
 └── tests/
     ├── test_users.py
     └── test_items.py

역할을 나누면 유지보수가 쉬워집니다.

디렉터리역할
api라우터, 엔드포인트
schemas요청/응답 모델
modelsDB 모델
services비즈니스 로직
repositoriesDB 접근
core설정, 보안
dbDB 연결
tests테스트 코드

29. FastAPI 개발 시 주의할 점

FastAPI는 빠르게 개발할 수 있지만, 아무 구조 없이 만들면 유지보수가 어려워질 수 있습니다. 다음 원칙을 지키는 것이 좋습니다.

FastAPI 실무 개발 원칙
  • main.py에 모든 코드를 넣지 않는다.
  • Router, Schema, Service, Repository를 분리한다.
  • 요청 모델과 응답 모델을 구분한다.
  • 환경변수로 설정을 관리한다.
  • 운영 환경에서는 /docs 노출을 제한한다.
  • DB 세션은 의존성 주입으로 관리한다.
  • 인증/권한 로직을 공통화한다.
  • API 버전을 /api/v1처럼 관리한다.
  • 예외 응답 형식을 통일한다.
  • 테스트 코드를 작성한다.

30. 결론

FastAPI는 Python 백엔드 개발에서 매우 강력한 선택지입니다. 단순한 API 서버부터 AI 모델 서빙, RAG 시스템, 마이크로서비스, 사내 자동화 서버까지 폭넓게 사용할 수 있습니다.

FastAPI의 핵심
  • 타입 힌트
  • 자동 검증
  • 자동 문서화

여기에 비동기 처리, 의존성 주입, Pydantic 모델, Router 구조를 결합하면 실무에서도 충분히 안정적인 API 서버를 만들 수 있습니다.

처음에는 작은 CRUD API부터 시작하는 것이 좋습니다. 이후 DB 연동, 인증, Docker 배포, Nginx 연동, 모니터링까지 확장하면 FastAPI는 단순한 학습용 프레임워크가 아니라 실제 서비스를 지탱하는 든든한 백엔드 엔진이 됩니다.

댓글

0

댓글을 불러오는 중입니다.