FastAPI 서버개발, Poetry를 통한 파이썬 환경 구축

최근 들어 웹 애플리케이션 개발에 있어 FastAPI는 그 빠른 성능과 사용의 용이성 덕분에 많은 인기를 끌고 있습니다. 특히 비동기 처리를 지원하여 높은 처리량을 요구하는 애플리케이션에 적합합니다. 이번 글에서는 FastAPI를 사용한 서버 개발 과정과 함께 Poetry를 활용한 파이썬 환경 관리 방법에 대해 자세히 알아보겠습니다.

1. FastAPI란?

FastAPI는 Starlette 위에 구축된 현대적인 웹 프레임워크로, 빠르고 효율적인 API 개발을 위한 도구입니다. Python 3.6 이상에서 사용할 수 있으며, 주요 특징으로는 다음과 같은 점들이 있습니다:

  • 빠른 성능: FastAPI는 비동기 및 동기 기능 모두를 지원하며, Uvicorn 서버 위에서 매우 빠르게 작동합니다.
  • 자동 문서화: API를 정의할 때 사용한 타입 힌트에 기반하여 Swagger UI와 Redoc을 자동 생성합니다.
  • 간편한 입력 검증: Pydantic을 통해 요청 데이터의 검증과 직렬화/역직렬화를 손쉽게 처리할 수 있습니다.

2. Poetry란?

Poetry는 Python 프로젝트 관리를 위한 도구로, 패키지 의존성 관리와 프로젝트 환경을 통합적으로 제공합니다. 다른 패키지 관리 툴들과의 차별점은 다음과 같습니다:

  • 간편한 의존성 관리: Poetry는 pyproject.toml 파일에 의존성을 명세하며, 이를 통해 의존성 충돌을 방지합니다.
  • 가상 환경 자동 생성: 각 프로젝트별로 독립적인 가상 환경을 자동으로 생성하고 활성화합니다.
  • 버전 잠금: poetry.lock 파일에 버전을 잠궈 재현 가능한 환경을 제공합니다.

3. FastAPI 서버 개발 환경 구축하기

3.1. Poetry 설치

Poetry를 설치하기 위해 다음 명령어를 사용합니다:

curl -sSL https://install.python-poetry.org | python3 -

설치 후, 아래 명령어로 PATH를 설정합니다:

export PATH="$HOME/.local/bin:$PATH"

3.2. 새 프로젝트 생성

이제 새로운 FastAPI 프로젝트를 생성해 보겠습니다. 프로젝트 폴더를 만들어주고 해당 폴더로 이동한 후, Poetry로 새 프로젝트를 초기화합니다:

mkdir my_fastapi_project
cd my_fastapi_project
poetry init

변수에 대한 질문이며, 기본값을 사용하거나 필요한 정보를 입력합니다. 이후, Poetry가 생성한 pyproject.toml 파일이 프로젝트 루트 디렉토리에 생성됩니다.

3.3. FastAPI 및 Uvicorn 설치

FastAPI와 Uvicorn을 설치합니다. Uvicorn은 ASGI 서버로, FastAPI 애플리케이션을 실행할 수 있게 해줍니다:

poetry add fastapi uvicorn

4. FastAPI 애플리케이션 구현하기

4.1. 기본 FastAPI 애플리케이션

프로젝트 디렉토리에 main.py 파일을 생성하고 아래와 같이 내용을 작성합니다:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
    return {"Hello": "World"}

4.2. 서버 실행

이제 서버를 실행해볼 차례입니다. 아래 명령어를 입력하면 Uvicorn 서버가 실행됩니다:

poetry run uvicorn main:app --reload

브라우저에서 http://127.0.0.1:8000로 접근하면 “Hello, World!” 메시지를 확인할 수 있습니다. 또한, Swagger UI는 http://127.0.0.1:8000/docs에서 확인 가능합니다.

5. 데이터 모델 정의 및 CRUD API 만들기

5.1. Pydantic 모델 생성

Pydantic을 사용하여 데이터 모델을 정의합니다. models.py 파일을 생성하고 다음 코드를 추가합니다:

from pydantic import BaseModel

class Item(BaseModel):
    id: int
    name: str
    description: str = None
    price: float
    tax: float = None

5.2. CRUD 기능 구현

이제 main.py 파일에 CRUD 기능을 구현해 보겠습니다. 간단한 메모리 데이터베이스를 사용하여 데이터를 저장하고 조회하는 기능을 추가합니다:

from fastapi import FastAPI
from typing import List
from models import Item

app = FastAPI()

items = {}

@app.post("/items/", response_model=Item)
async def create_item(item: Item):
    items[item.id] = item
    return item

@app.get("/items/", response_model=List[Item])
async def read_items():
    return list(items.values())

@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: int):
    return items[item_id]

@app.put("/items/{item_id}", response_model=Item)
async def update_item(item_id: int, item: Item):
    items[item_id] = item
    return item

@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
    del items[item_id]
    return {"message": "Item deleted"}

5.3. 테스트

서버를 실행한 후, Swagger UI를 통해 API를 테스트할 수 있습니다. 각 메서드를 클릭하여 요청을 보내고 응답을 확인합니다.

6. 마무리 및 추가 리소스

FastAPI와 Poetry를 통한 개발 환경 구축 과정을 살펴보았습니다. 이러한 도구들은 특히 비동기 기능과 작업의 단순성을 제공하므로, 빠르게 RESTful API를 개발할 수 있게 도와줍니다.

FastAPI에 대해 더 알고 싶다면 공식 문서와 다양한 튜토리얼을 참고해 보세요:

이 튜토리얼을 통해 FastAPI와 Poetry의 기초를 익히고, 실무에서의 활용에 대한 감각을 익히셨기를 바랍니다. Happy Coding!

FastAPI 서버개발, DB 조작, R Read

FastAPI는 비동기적, 고성능 웹 프레임워크로, Python을 기반으로 하며, RESTful API를 손쉽게 개발할 수 있도록 돕습니다. 이 글에서는 FastAPI를 사용하여 데이터베이스에서 정보를 읽는 방법에 대해 살펴보겠습니다. 데이터베이스 조작의 기본적인 구성 요소인 R(Read)에 중점을 두고 진행할 것입니다. 예제로는 SQLite 데이터베이스를 사용하여 기본적인 CRUD(Create, Read, Update, Delete) 조작을 수행하겠습니다.

1. FastAPI 소개

FastAPI는 다음과 같은 주요 특징을 가지고 있습니다:

  • 빠른 성능: Starlette 및 Pydantic을 기반으로 하여 비동기 처리를 지원합니다.
  • 자동 문서화: OpenAPI 및 JSON Schema를 기반으로 자동으로 API 문서를 생성합니다.
  • 타입 힌트 지원: Python 타입의 이점을 사용하여 코드의 가독성과 안전성을 높입니다.

2. 프로젝트 설정

우선 FastAPI 및 필요한 패키지를 설치하겠습니다. 다음 명령어를 사용하여 프로젝트 환경을 설정합니다:

pip install fastapi uvicorn sqlalchemy

2.1 SQLite 데이터베이스

SQLite는 간단하게 사용할 수 있는 파일 기반의 데이터베이스로, 개발 초기 단계에서 매우 유용합니다.

2.2 데이터베이스 모델 정의

SQLAlchemy를 사용하여 데이터베이스 모델을 정의합니다. 아래는 사용자 정보를 저장하기 위한 간단한 모델입니다.

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

# 데이터베이스 베이스 모델 정의
Base = declarative_base()

# 사용자 모델 정의
class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String, index=True)
    email = Column(String, unique=True, index=True)

# 데이터베이스 엔진 및 세션 생성
engine = create_engine("sqlite:///./test.db")
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# 데이터베이스 생성
Base.metadata.create_all(bind=engine)

3. FastAPI 앱 생성

FastAPI 앱을 생성하고, 기본적인 엔드포인트를 구현하겠습니다. 아래는 사용자 정보를 조회하는 API를 완성하는 코드입니다.

from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session

# FastAPI 앱 생성
app = FastAPI()

# 데이터베이스 세션 생성
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# 사용자 조회 API 엔드포인트
@app.get("/users/{user_id}", response_model=User)
def read_user(user_id: int, db: Session = Depends(get_db)):
    db_user = db.query(User).filter(User.id == user_id).first()
    if db_user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return db_user

4. 실행 및 테스트

이제 FastAPI 서버를 실행할 준비가 되었습니다. 아래 명령어로 서버를 실행합니다:

uvicorn main:app --reload

서버가 정상적으로 실행되면 브라우저에서 http://127.0.0.1:8000/docs에 접속하여 자동 생성된 API 문서를 확인할 수 있습니다. 이곳에서 사용자 정보를 요청할 수 있습니다.

5. 결론

이 글에서는 FastAPI를 사용하여 SQLite 데이터베이스로부터 데이터를 읽어오는 방법을 다뤘습니다. FastAPI의 직관적인 API 설계와 SQLAlchemy를 통해 쉽게 CRUD 작업을 수행할 수 있습니다. 추후에는 데이터 생성(Create), 수정(Update), 삭제(Delete)의 구현에 대해서도 다룰 예정입니다. FastAPI는 비즈니스 로직이 복잡해질수록 더 효과적이므로, 실제 응용 프로그램에서의 활용을 적극 추천합니다.

6. 참고 자료

FastAPI 서버개발, 사용자 인증

오늘날의 웹 애플리케이션은 사용자 인증이 필수적입니다. 사용자의 신원을 확인하고 보호하기 위해 다양한 인증 방법이 존재합니다. 본 포스트에서는 FastAPI를 사용하여 사용자 인증을 구현하는 방법에 대해 자세히 설명하겠습니다. FastAPI는 Python으로 쓰인 현대적인 웹 프레임워크로, 빠른 성능과 쉽게 사용할 수 있는 API 설계로 인기를 끌고 있습니다.

1. FastAPI 소개

FastAPI는 Python 3.6 이상에서 사용할 수 있으며, AsyncIO를 기반으로 비동기 프로그래밍을 지원합니다. 또한 자동 문서화 기능을 제공하여 Swagger UI 및 ReDoc을 통해 API 문서를 쉽게 생성할 수 있습니다. FastAPI는 Pydantic을 기반으로 데이터 검증 및 설정 관리를 효율적으로 처리합니다.

2. 사용자 인증의 중요성

사용자 인증은 사용자의 신원을 확인하고, 이를 기반으로 권한을 부여하는 과정입니다. 이는 다음과 같은 이유로 중요합니다:

  • 보안성: 사용자 데이터 보호 및 유출 방지
  • 접근 제어: 사용자에 따라 권한 부여 및 제한
  • 사용자 경험: 개인화된 서비스 제공

3. FastAPI에서의 사용자 인증 기법

FastAPI에서 사용자 인증을 구현할 수 있는 방법은 여러 가지가 있습니다. 가장 일반적인 방법은 JWT (JSON Web Token)를 사용하는 것입니다. JWT는 사용자를 인증하고 정보를 안전하게 전송할 수 있는 토큰 기반 인증 방법입니다.

4. 필요한 라이브러리 설치

FastAPI와 JWT를 사용하기 위해 필요한 라이브러리를 설치합니다. 아래 명령어를 사용하여 필요한 패키지를 설치하세요:

pip install fastapi uvicorn python-jose passlib[bcrypt]

5. 기본 FastAPI 설정

FastAPI 애플리케이션을 설정합니다. 다음 코드를 사용하여 기본 FastAPI 애플리케이션을 만드세요:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
    return {"Hello": "World"}

6. 사용자 모델 및 데이터베이스 설정

이제 사용자 모델을 정의하고 데이터베이스에 연결합니다. SQLAlchemy를 사용하여 데이터베이스와의 상호작용을 간단하게 처리할 수 있습니다. 아래는 기본적인 사용자 모델 코드입니다:

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    username = Column(String, unique=True, index=True)
    hashed_password = Column(String)

위 코드에서 사용자 모델을 정의했습니다. `username`과 `hashed_password`를 통해 기본적인 사용자 정보를 저장할 수 있습니다.

7. 비밀번호 해싱

사용자의 비밀번호를 안전하게 저장하기 위해 해싱을 사용합니다. Passlib 라이브러리를 사용하여 비밀번호를 해싱하고 검증할 수 있습니다:

from passlib.context import CryptContext

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def get_password_hash(password):
    return pwd_context.hash(password)

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

8. 사용자 추가 및 등록 엔드포인트

사용자를 등록할 수 있는 엔드포인트를 추가합니다. 사용자가 비밀번호를 안전하게 저장하도록 해싱 후 데이터베이스에 저장할 수 있습니다:

from fastapi import Depends, HTTPException
from sqlalchemy.orm import Session

Base.metadata.create_all(bind=engine)

# Create the user
@app.post("/users/")
def create_user(username: str, password: str, db: Session = Depends(get_db)):
    hashed_password = get_password_hash(password)
    db_user = User(username=username, hashed_password=hashed_password)
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

9. JWT 토큰 생성

로그인 후 JWT 토큰을 생성하여 반환하는 엔드포인트를 추가합니다:

from datetime import datetime, timedelta
from jose import JWTError, jwt

SECRET_KEY = "your_secret_key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

def create_access_token(data: dict, expires_delta: timedelta = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

10. 로그인 엔드포인트

사용자가 로그인할 수 있도록 엔드포인트를 추가합니다.

@app.post("/token")
async def login(username: str, password: str, db: Session = Depends(get_db)):
    user = db.query(User).filter(User.username == username).first()
    if not user or not verify_password(password, user.hashed_password):
        raise HTTPException(status_code=400, detail="잘못된 사용자명 또는 비밀번호")
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(data={"sub": user.username}, expires_delta=access_token_expires)
    return {"access_token": access_token, "token_type": "bearer"}

11. 보호된 엔드포인트 설정

JWT 토큰으로 보호된 엔드포인트를 설정합니다. 사용자가 인증된 경우에만 접근할 수 있도록 구현합니다:

from fastapi import Security, Depends
from fastapi.security import OAuth2PasswordBearer

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

async def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):
    credentials_exception = HTTPException(status_code=401, detail="유효하지 않은 자격 증명", headers={"WWW-Authenticate": "Bearer"})
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
    except JWTError:
        raise credentials_exception
    user = db.query(User).filter(User.username == username).first()
    if user is None:
        raise credentials_exception
    return user

@app.get("/users/me")
async def read_users_me(current_user: User = Depends(get_current_user)):
    return current_user

12. FastAPI 서버 실행

모든 설정이 완료되었으니, 이제 FastAPI 서버를 실행할 준비가 되었습니다. 아래 명령어로 서버를 실행하세요:

uvicorn main:app --reload

위 명령어를 통해 FastAPI 서버가 `http://127.0.0.1:8000`에서 실행됩니다.

13. Swagger UI를 통한 API 문서화

FastAPI는 Swagger를 통해 자동으로 API 문서를 생성합니다. 브라우저에서 `http://127.0.0.1:8000/docs`로 이동하면 API 문서를 확인할 수 있습니다.

14. 결론

FastAPI를 사용한 사용자 인증 구현 방법에 대해 알아보았습니다. 비밀번호 해싱, JWT 기반 인증을 포함한 사용자 등록 및 로그인 기능을 제공하는 API를 구축했습니다. FastAPI의 강력한 기능을 통해 효율적으로 사용자 인증을 처리할 수 있습니다.

노트: 실제 애플리케이션에서는 비밀키와 같은 중요한 정보를 환경 변수에 저장하거나 더 안전한 방식으로 관리하는 것이 좋습니다.

15. 참고 자료

FastAPI 서버개발, 스키마 – 응답, 응답 타입 정의

FastAPI는 현대적인 웹 API를 구축하는 데 최적화된 Python 웹 프레임워크로, 성능과 빠른 개발 속도를 제공합니다. FastAPI의 주요 장점 중 하나는 데이터 유효성 검사와 자동 문서 생성을 위한 Pydantic의 사용입니다. 본 글에서는 FastAPI에서 응답 스키마를 정의하는 방법과 다양한 응답 타입을 설정하는 방법에 대해 깊이 있게 알아보겠습니다.

1. FastAPI와 Pydantic 소개

FastAPI는 백엔드 서버 개발을 위한 고성능 프레임워크로, RESTful API를 간편하게 구축할 수 있게 도와줍니다. FastAPI의 핵심 특징 중 하나는 Pydantic을 통한 데이터 유효성 검사 및 직렬화입니다. Pydantic을 사용하면 데이터 모델을 선언적으로 정의할 수 있으며, 데이터의 유효성을 체크할 수 있습니다.

예를 들어, 사용자의 정보를 담는 데이터 모델을 아래와 같이 정의할 수 있습니다.

from pydantic import BaseModel

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

2. FastAPI에서의 응답 스키마 정의

FastAPI에서 API의 응답을 정의하려면 Pydantic 모델을 사용합니다. 이 모델은 API가 클라이언트에게 반환하는 데이터의 구조를 정의합니다. 이렇게 하면 일관된 응답 형식을 보장하고 클라이언트는 예측 가능한 방식으로 데이터를 처리할 수 있습니다.

다음은 사용자의 정보를 반환하는 API 엔드포인트를 만드는 예제입니다.

from fastapi import FastAPI

app = FastAPI()

@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
    return User(id=user_id, name="John Doe", email="johndoe@example.com")

위 코드에서 response_model=User를 설정함으로써 FastAPI는 이 API가 반환하는 데이터가 User 모델의 형식에 맞도록 자동으로 유효성 검사를 수행합니다. 그리고 스웨거 문서에서도 이 모델의 구성 정보를 확인할 수 있습니다.

3. 복잡한 응답 모델 정의

API의 응답은 때로는 단순하지 않을 수 있습니다. 여러 개의 모델을 포함한 복잡한 응답 구조를 정의해야 할 수도 있습니다. 예를 들어, 게시물과 그에 대한 댓글을 포함하는 구조를 생각해 보겠습니다.

class Comment(BaseModel):
    id: int
    content: str
    user_id: int

class Post(BaseModel):
    id: int
    title: str
    content: str
    comments: List[Comment]  # 댓글 목록

이러한 모델을 사용하여 게시물 정보를 반환하는 엔드포인트를 정의할 수 있습니다.

from typing import List

@app.get("/posts/{post_id}", response_model=Post)
async def get_post(post_id: int):
    comments = [Comment(id=1, content="Great post!", user_id=1), 
                Comment(id=2, content="Thanks for sharing!", user_id=2)]
    return Post(id=post_id, title="My First Post", content="This is the content.", comments=comments)

4. 응답 타입 정의와 자동 문서화

FastAPI는 자동으로 API 문서를 생성합니다. 위의 예제에서 API의 메타데이터는 FastAPI가 자동으로 생성하여 스웨거(Swagger)와 ReDoc 문서화 도구에서 확인할 수 있습니다. 응답 모델을 정의함으로써 클라이언트는 API를 사용할 때 어떤 형태의 데이터를 받을 수 있는지 명확하게 알 수 있습니다.

또한, FastAPI는 충분한 API 문서를 자동으로 제공하므로 프론트엔드 개발자가 필요한 API 정보를 쉽게 확인할 수 있습니다. 아래와 같이 문서화된 내용을 확인할 수 있습니다.

uvicorn main:app --reload

브라우저에서 http://127.0.0.1:8000/docs를 열면 Swagger UI를 통해 API의 모든 엔드포인트와 그 응답 형태를 확인할 수 있습니다.

5. 응답 시나리오: 성공, 실패 응답

실제 애플리케이션에서는 성공적인 응답뿐만 아니라 오류 처리도 포함되어야 합니다. FastAPI는 HTTPException을 사용하여 오류 응답을 정의할 수 있습니다. 아래 예시는 사용자가 존재하지 않을 경우 404 오류 응답을 반환하는 방법을 보여줍니다.

from fastapi import HTTPException

@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
    if user_id != 1:  # 존재하지 않는 사용자 ID
        raise HTTPException(status_code=404, detail="User not found")
    return User(id=user_id, name="John Doe", email="johndoe@example.com")

5.1. 커스텀 오류 응답 모델

또한, 오류 발생 시에 반환하는 커스텀 응답 모델을 정의할 수도 있습니다. 예를 들어, 오류 응답을 나타내는 모델을 정의하고 이를 사용하여 일관된 오류 메시지를 클라이언트에 전달할 수 있습니다.

class ErrorResponse(BaseModel):
    detail: str
    status_code: int

@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
    return JSONResponse(
        status_code=exc.status_code,
        content={"detail": exc.detail, "status_code": exc.status_code},
    )

위와 같이 설정하면, 모든 HTTPException에 대해 일관된 구조의 오류 응답을 제공할 수 있습니다. 클라이언트에서는 응답을 쉽게 처리할 수 있습니다.

6. 응답 스키마와 API 버전 관리

API를 운영하다 보면 스키마가 변경되는 경우가 발생할 수 있습니다. 이를 잘 관리하기 위해 API 버전 관리를 고려해야 합니다. FastAPI는 경로에 버전 정보를 추가하여 서로 다른 버전의 API를 동시에 운영할 수 있습니다.

app_v1 = FastAPI()
app_v2 = FastAPI()

@app_v1.get("/users/{user_id}", response_model=User)
async def get_user_v1(user_id: int):
    return User(id=user_id, name="John Doe", email="janedoe@example.com")

@app_v2.get("/users/{user_id}", response_model=User)
async def get_user_v2(user_id: int):
    return User(id=user_id, name="Jane Doe", email="johndoe@example.com")

# Uvicorn을 통해 앱 실행
# uvicorn main:app_v1 --reload
# uvicorn main:app_v2 --reload

이렇게 각각의 버전마다 다른 응답을 제공할 수 있으므로, 기존 API를 사용하는 클라이언트는 새로운 변화에 영향을 받지 않고, 점진적으로 업데이트할 수 있습니다.

7. 결론

FastAPI는 그 자체의 뛰어난 성능과 직관적인 문서화, 유효성 검사 기능으로 인해 데이터 기반 애플리케이션을 개발하는 데 매우 유용한 도구입니다. 본 포스트에서는 FastAPI에서 응답 스키마를 정의하는 방법과 다양한 응답 타입 처리 방식을 자세히 살펴보았습니다.

스키마 정의는 API의 안정성과 일관성을 보장하는 데 매우 중요하며, 특히 여러 클라이언트 앱에서 사용할 때 그 중요성이 더욱 두드러집니다. FastAPI를 통해 빠르고 효율적으로 API를 구축하고 관리하는 방법을 이해하는 데 도움이 되었기를 바랍니다. 이제 여러분은 FastAPI를 사용하여 강력한 백엔드 시스템을 구축할 준비가 되었습니다!

FastAPI 서버개발, 배포, 의존 라이브러리 관리

FastAPI는 현대 웹 API를 구축하기 위해 설계된 고속 웹 프레임워크로, 파이썬의 타입 힌트를 활용하여 개발 효율성과 코드 품질을 한층 끌어올립니다. 본 글에서는 FastAPI의 기본 개념부터 시작하여, 서버 배포, 의존 라이브러리 관리에 대한 체계적인 설명과 함께 실용적인 예제 코드를 제공합니다.

1. FastAPI 소개

FastAPI는 비동기 프로그래밍을 지원하며, Python 3.6 이상에서 작동합니다. 이는 Starlette와 Pydantic을 기반으로 하며, 다음과 같은 특징을 가지고 있습니다:

  • 빠른 성능: FastAPI는 NodeJS의 Express, Go의 Gin과 같은 다른 프레임워크와 유사한 성능을 자랑합니다.
  • 자동화된 문서화: OpenAPI 및 JSON Schema를 기반으로 하여 자동으로 API 문서화가 이루어집니다.
  • 유효성 검사 및 직렬화: Pydantic을 사용하여 데이터 유효성 검사 및 직렬화를 지원합니다.

2. FastAPI 설치 및 기본 설정

FastAPI를 설치하기 위해 아래의 pip 명령어를 사용할 수 있습니다.

pip install fastapi uvicorn

2.1. 간단한 FastAPI 애플리케이션 만들기

아래의 코드는 기본적인 FastAPI 서버의 구조를 보여줍니다. 이 예제에서는 ‘/items/{item_id}’ 경로로 GET 요청을 처리하는 간단한 애플리케이션을 생성합니다.

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

2.2. 서버 실행

위 코드를 main.py로 저장한 후 아래의 명령어로 서버를 실행합니다.

uvicorn main:app --reload

3. API 문서 자동 생성

FastAPI는 자동으로 API 문서를 생성하며, 브라우저에서 http://127.0.0.1:8000/docs에 접속하여 Swagger UI를 확인할 수 있습니다. 또한 http://127.0.0.1:8000/redoc를 통해 ReDoc 형식으로도 확인할 수 있습니다. 이는 개발 시 큰 도움이 되며, 클라이언트와의 소통에도 유용합니다.

4. 데이터 모델링과 Pydantic

FastAPI는 Pydantic을 이용하여 데이터 유효성을 검사하고 모델링을 지원합니다. 다음은 Pydantic을 사용하여 데이터 모델을 정의하는 예제입니다.

from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None

@app.post("/items/")
async def create_item(item: Item):
    return item

5. 의존성 주입

FastAPI는 의존성 주입을 통해 필요한 부분에서 최적의 코드 재사용성을 제공합니다. 아래는 의존성을 사용하여 데이터베이스 연결을 처리하는 예제입니다.

from fastapi import Depends

def get_query(q: str = None):
    return q

@app.get("/items/")
async def read_items(q: str = Depends(get_query)):
    return {"q": q}

6. 배포

FastAPI 애플리케이션을 배포하기 위해 여러 방법이 있으며, 일반적으로는 Docker와 클라우드 서비스 (AWS, GCP, Azure 등)를 사용합니다. 아래는 Docker를 이용한 배포 예시입니다.

6.1. Dockerfile 작성하기

프로젝트 루트 디렉토리에 Dockerfile을 생성하고 아래와 같이 작성합니다.

FROM python:3.9

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", "80"]

6.2. Docker Compose 설정

Docker Compose를 사용하면 여러 컨테이너를 관리하기 용이합니다. 아래는 예시 docker-compose.yml 파일입니다.

version: '3.8'

services:
  fastapi:
    build: .
    ports:
      - "8000:80"

6.3. 배포하기

Docker를 이용한 애플리케이션의 배포는 다음과 같은 명령어로 실행할 수 있습니다:

docker-compose up --build

7. 의존 라이브러리 관리

의존 라이브러리를 관리하기 위해 requirements.txt 파일을 사용합니다. 필요한 패키지를 설치 후 pip freeze 명령어로 생성할 수 있습니다.

pip freeze > requirements.txt

7.1. 가상 환경 설정

가상 환경을 통해 프로젝트마다 라이브러리를 독립적으로 관리할 수 있습니다. 아래의 명령어로 가상 환경을 설정하고 활성화할 수 있습니다.

python -m venv venv
source venv/bin/activate  # Linux/Mac
venv\Scripts\activate  # Windows

8. 결론

FastAPI는 데이터 모델링, API 문서화, 의존성 주입 등 다양한 기능을 통해 개발자에게 혜택을 제공합니다. 또한 Docker와의 조합으로 배포 또한 원활하게 이뤄질 수 있습니다. FastAPI를 통해 클린하고 유지보수하기 쉬운 서버 측 애플리케이션을 빠르게 개발할 수 있습니다.

References