FastAPI 서버개발, 비동기 대응 DB 접속 함수

FastAPI는 Python의 빠르고 현대적인 웹 프레임워크로, 비동기 프로그래밍을 통해 높은 성능을 발휘합니다. 이 글에서는 FastAPI에서 비동기 데이터베이스 접속 함수를 구현하는 방법에 대해 상세히 설명하고, 예제 코드를 통해 몸소 경험할 수 있도록 하겠습니다. FastAPI의 비동기 기능은 대규모 웹 애플리케이션이나 높은 동시성이 요구되는 API 서버를 구축할 때 특히 강력한 성능을 제공합니다.

1. 비동기 프로그래밍이란?

비동기 프로그래밍은 여러 작업을 동시에 처리할 수 있게 해주는 프로그래밍 모델입니다. 기존의 동기 프로그래밍에서는 작업 하나가 끝날 때까지 다음 작업을 기다려야 했지만, 비동기 프로그래밍에서는 하나의 작업이 진행되는 동안 다른 작업을 동시에 처리할 수 있습니다. 이는 특히 I/O 바운드 작업에서 큰 이점을 제공합니다.

1.1 비동기 프로그래밍의 장점

  • 성능 증가: 여러 I/O 작업을 동시에 처리하여 대기 시간을 줄일 수 있습니다.
  • 리소스 효율성: CPU 사용률을 최적화하고, 낮은 자원으로 많은 클라이언트를 처리할 수 있습니다.
  • 응답성 향상: 서버가 특정 작업을 기다리는 시간이 줄어들어 사용자가 더 빠르게 응답을 받을 수 있습니다.

2. FastAPI 소개

FastAPI는 Python 3.6+을 위한 현대적인 웹 프레임워크로, 빠르고, 직관적이며, 자동 완성을 제공합니다. FastAPI의 가장 큰 장점 중 하나는 ASGI(Asynchronous Server Gateway Interface)를 기반으로 하여 비동기 처리를 지원한다는 것입니다. 이는 웹 소켓이나 데이터베이스와 같은 비동기 I/O를 처리하는 데 매우 유리합니다.

FastAPI는 또한 Pydantic을 사용하여 데이터 유효성을 검사하고 JSON 직렬화를 제공하여 개발자가 보다 간편하게 API를 개발할 수 있도록 돕습니다.

3. 비동기 데이터베이스 접근 방법

데이터베이스에 비동기적으로 접근하기 위해서는 비동기 지원을 위한 ORM(Object Relational Mapping) 라이브러리를 사용해야 합니다. 여기서는 SQLAlchemyDatabases 라이브러리를 조합하여 비동기 DB 접속 함수를 구현하는 예제를 살펴보겠습니다.

3.1 필요한 라이브러리 설치

FastAPI 애플리케이션을 시작하기 위해 필요한 패키지를 설치합니다. 다음과 같은 명령어를 터미널에 입력하여 설치합니다:

pip install fastapi uvicorn sqlalchemy databases asyncpg

위 명령어는 FastAPI 프레임워크, ASGI 서버(Uvicorn), SQLAlchemy ORM, Databases 비동기 라이브러리, PostgreSQL 데이터베이스 드라이버를 설치합니다.

3.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, index=True)
    username = Column(String, unique=True, index=True)
    email = Column(String, unique=True, index=True)

3.3 데이터베이스 연결 설정

비동기 데이터베이스 연결을 위해 Databases 라이브러리를 사용하여 데이터베이스 연결을 설정합니다.

DATABASE_URL = "postgresql+asyncpg://user:password@localhost/dbname"
database = Database(DATABASE_URL)
engine = create_engine(DATABASE_URL)
Base.metadata.create_all(bind=engine)

위 코드에서 DATABASE_URL은 사용자의 데이터베이스 정보를 입력해야 합니다. 데이터베이스 사용자가 user, 비밀번호가 password이며, 데이터베이스 이름이 dbname인 PostgreSQL 데이터베이스에 연결하는 URI입니다.

3.4 비동기 데이터베이스 함수 구현

이제 필요한 비동기 데이터베이스 작업 함수를 구현합니다.

from databases import Database

async def get_user(database: Database, user_id: int):
    query = "SELECT * FROM users WHERE id = :id"
    return await database.fetch_one(query, values={"id": user_id})

async def create_user(database: Database, username: str, email: str):
    query = "INSERT INTO users(username, email) VALUES (:username, :email)"
    await database.execute(query, values={"username": username, "email": email})

위 함수는 각각 사용자를 데이터베이스에서 조회하고, 새 사용자를 생성하는 비동기 함수입니다. fetch_one 메소드는 데이터베이스 쿼리에 대한 단일 결과를 비동기적으로 반환하고, execute 메소드는 INSERT 작업을 수행합니다.

3.5 FastAPI 앱과 비동기 데이터베이스 함수 연결

FastAPI 애플리케이션을 설정하고, 비동기 데이터베이스 함수를 해당 엔드포인트에 연결합니다.

from fastapi import FastAPI

app = FastAPI()

@app.on_event("startup")
async def startup():
    await database.connect()

@app.on_event("shutdown")
async def shutdown():
    await database.disconnect()

@app.get("/users/{user_id}")
async def read_user(user_id: int):
    user = await get_user(database, user_id)
    return user

@app.post("/users/")
async def create_new_user(username: str, email: str):
    await create_user(database, username, email)
    return {"msg": "User created successfully"}

위 코드에서 애플리케이션의 시작 시 database.connect()를 호출하여 데이터베이스에 연결하고, 종료 시 database.disconnect()를 호출하여 연결을 종료합니다. 사용자를 조회하는 read_user 엔드포인트와 새 사용자를 생성하는 create_new_user 엔드포인트도 설정했습니다.

4. 테스트와 검증

이제 FastAPI 애플리케이션을 실행하고 비동기 API를 테스트할 준비가 되었습니다. 다음 명령어로 서버를 실행합니다:

uvicorn main:app --reload

웹 브라우저에서 http://localhost:8000/docs에 접속하면 FastAPI의 문서화된 API 인터페이스를 확인할 수 있습니다. 여기서 비동기적으로 정의한 API를 테스트할 수 있습니다.

4.1 사용자 생성 테스트

/users/ 엔드포인트로 POST 요청을 보내어 사용자를 생성할 수 있습니다. 예시 요청 본문은 다음과 같습니다:

{
    "username": "testuser",
    "email": "test@example.com"
}

4.2 사용자 조회 테스트

/users/{user_id} 엔드포인트로 GET 요청을 보내어 사용자를 조회할 수 있습니다. 예를 들어 /users/1 요청을 보내면 ID가 1인 사용자의 정보를 받을 수 있습니다.

5. 결론

FastAPI 모바일 애플리케이션을 위한 강력하고 효율적인 백엔드 서버를 구축하는 데 필요한 기본적인 비동기 데이터베이스 접속 함수를 성공적으로 구현했습니다. 이 예제를 통해 FastAPI의 비동기 기능을 활용하여 동시성을 높이고, 더 많은 클라이언트 요청을 처리할 수 있는 옵션을 갖추게 되었습니다. 이러한 구조는 특히 트래픽이 높은 애플리케이션에서 성능을 극대화할 수 있습니다.

추가적으로, 데이터베이스와의 비동기 작업을 위한 다양한 라이브러리와 기술도 존재하므로, 각각의 요구사항에 맞게 커스터마이징하여 사용하시기 바랍니다. 이 글이 여러분의 FastAPI 개발에 도움이 되기를 바랍니다.

FastAPI 서버개발, 기본 경로 설정 및 HTTP 메서드(POST, GET, PUT, DELETE) 처리

FastAPI는 Python을 기반으로 한 현대적인 웹 프레임워크로, API를 쉽게 구축하고 배포할 수 있는 강력한 기능을 제공합니다. 본 강좌에서는 FastAPI를 사용하여 기본 경로를 설정하고, HTTP 메서드(POST, GET, PUT, DELETE)를 처리하는 방법에 대해 상세히 설명하겠습니다. 이 과정에서 필요한 설정과 예제 코드를 제공하니 참고하시기 바랍니다.

1. FastAPI 설치 및 기본 설정

FastAPI를 사용하기 위해서는 Python 환경이 필요합니다. Python 3.6 이상이 설치되어 있는지 확인한 후, FastAPI와 Uvicorn(비동기 웹 서버)를 설치합니다. 이를 위해 다음 명령어를 사용합니다:

pip install fastapi uvicorn

2. FastAPI 서버 실행하기

FastAPI 애플리케이션을 작성하기 위해 기본적인 구조를 설정해보겠습니다. 아래와 같이 main.py 파일을 생성하고 다음 코드를 입력합니다:

from fastapi import FastAPI

app = FastAPI()

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

위 코드는 FastAPI 서버의 가장 기본적인 예제로, 서버가 실행되면 / 경로로 접근했을 때 “Hello, FastAPI!”라는 메시지를 반환합니다.

서버를 실행하려면 터미널에서 다음 명령어를 사용합니다:

uvicorn main:app --reload

브라우저를 열고 http://127.0.0.1:8000로 이동하면 “Hello, FastAPI!” 메시지를 확인할 수 있습니다.

3. HTTP 메서드 처리

FastAPI는 다양한 HTTP 메서드를 지원합니다. 주요 HTTP 메서드에는 GET, POST, PUT, DELETE가 있습니다. 각각의 메서드를 사용하여 API를 설계하여 보겠습니다.

3.1 GET 메서드

GET 메서드는 서버에서 데이터를 조회할 때 사용됩니다. 예를 들어, 다음 코드는 특정 사용자의 정보를 조회하는 API를 구현합니다:

@app.get("/users/{user_id}")
async def read_user(user_id: int):
    return {"user_id": user_id, "name": "User Name"}

위 코드는 /users/{user_id} 경로에서 GET 요청을 처리합니다. 사용자 ID를 입력받아 해당 ID에 대한 사용자 정보를 반환합니다.

3.2 POST 메서드

POST 메서드는 서버에 새로운 데이터를 생성할 때 사용됩니다. 다음 예제는 사용자를 추가하는 API입니다:

from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int

@app.post("/users/")
async def create_user(user: User):
    return {"user_id": 1, "name": user.name, "age": user.age}

위의 예제에서 User 클래스는 Pydantic을 사용하여 데이터 모델을 정의합니다. 사용자가 POST 요청을 통해 전달하는 데이터는 User 클래스의 인스턴스로 변환됩니다.

3.3 PUT 메서드

PUT 메서드는 서버에 존재하는 데이터를 수정할 때 사용됩니다. 아래의 코드는 사용자의 정보를 업데이트하는 API입니다:

@app.put("/users/{user_id}")
async def update_user(user_id: int, user: User):
    return {"user_id": user_id, "updated_name": user.name, "updated_age": user.age}

여기서 사용자의 ID와 업데이트할 정보를 수정하여 반환합니다.

3.4 DELETE 메서드

DELETE 메서드는 서버에서 정보를 삭제할 때 사용됩니다. 다음은 사용자를 삭제하는 API의 예입니다:

@app.delete("/users/{user_id}")
async def delete_user(user_id: int):
    return {"message": f"User {user_id} has been deleted."}

이 API는 특정 사용자의 ID를 받아 해당 사용자 삭제에 대한 메시지를 반환합니다.

4. FastAPI의 데이터 검증

FastAPI는 Pydantic을 통해 데이터 검증을 지원합니다. 위 예제에서 User 클래스를 사용하여 이름과 나이를 검증했습니다. 올바른 데이터 형식을 지정함으로써 API가 정확하게 작동하도록 보장할 수 있습니다.

5. FastAPI와 데이터베이스 연동

대부분의 웹 애플리케이션에서는 데이터를 데이터를 저장하고 검색하기 위해 데이터베이스와의 연동이 필요합니다. FastAPI와 SQLAlchemy를 사용하면 데이터베이스와 통신할 수 있습니다. 여기서는 SQLite를 예로 들어보겠습니다.

from fastapi import FastAPI, Depends
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session

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 UserModel(Base):
    __tablename__ = "users"

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

이제 데이터베이스를 초기화하고, FastAPI와 연동하는 방법을 살펴보겠습니다:

Base.metadata.create_all(bind=engine)

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

GET 메서드에 데이터베이스에서 사용자 정보를 가져오는 로직을 작성해보겠습니다:

@app.get("/users/{user_id}")
async def read_user(user_id: int, db: Session = Depends(get_db)):
    user = db.query(UserModel).filter(UserModel.id == user_id).first()
    return user if user else {"message": "User not found"}

6. FastAPI 문서화

FastAPI의 가장 큰 장점 중 하나는 자동으로 API 문서를 생성해준다는 점입니다. Swagger UI를 통해 API를 쉽게 테스트하고 문서화할 수 있습니다. 서버를 실행한 후 http://127.0.0.1:8000/docs로 접속하면 Swagger UI에서 API를 확인할 수 있습니다.

7. 보안 및 인증

실제 애플리케이션에서는 사용자 인증 및 보안이 중요합니다. FastAPI는 OAuth2를 지원하여 JWT 토큰 기반 인증을 구현할 수 있습니다. 이 부분은 추가적인 구현이 필요하므로 FastAPI의 공식 문서를 참고하시기 바랍니다.

8. 결론

FastAPI는 현대적인 웹 애플리케이션 개발에 적합한 강력한 프레임워크입니다. 본 강좌에서는 기본적인 경로 설정 및 HTTP 메서드 처리를 다루었습니다. FastAPI를 사용하여 여러분만의 RESTful API를 구현해보길 바랍니다. 추가적인 내용이 필요하시면 FastAPI 공식 문서에서 더욱 다양한 기능과 사용법을 학습하실 수 있습니다.

여러분의 프로젝트에 FastAPI를 적용해 보시기 바랍니다.

FastAPI 서버개발, Jinja, 필터

FastAPI는 현대적인 웹 API를 구축하기 위한 Python 웹 프레임워크입니다. 비동기 프로그래밍을 지원하며, 자동으로 문서화된 API를 생성할 수 있는 장점이 있습니다. 이 글에서는 FastAPI 서버를 개발하고, Jinja 템플릿 엔진을 사용하여 HTML 템플릿을 렌더링하며, Jinja의 필터를 활용하는 방법에 대해 자세히 설명하겠습니다.

FastAPI란?

FastAPI는 Python 3.6+을 지원하며, Starlette와 Pydantic을 기반으로 한 웹 프레임워크입니다. 주된 장점은 다음과 같습니다:

  • 비동기 지원: 비동기 프로그래밍을 통해 더 많은 요청을 처리할 수 있습니다.
  • 자동 문서화: OpenAPI 및 JSON Schema를 기반으로 자동으로 API 문서를 생성합니다.
  • 높은 성능: 비동기 처리 덕분에 높은 성능을 자랑합니다.

FastAPI 설치 및 기본 서버 설정

FastAPI를 설치하기 위해서는 pip를 사용하여 다음과 같이 설치합니다:

pip install fastapi uvicorn

설치가 완료되면 기본 FastAPI 서버를 설정해 보겠습니다. 다음 코드를 main.py라는 파일에 작성하십시오:

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
async def read_root():
    return "

안녕하세요, FastAPI!

"

서버를 실행하기 위해서는 아래와 같이 uvicorn을 사용합니다:

uvicorn main:app --reload

브라우저에서 http://127.0.0.1:8000로 접속하면 “안녕하세요, FastAPI!”라는 메시지를 확인할 수 있습니다.

Jinja2 템플릿 사용하기

템플릿 엔진은 HTML 파일을 동적으로 렌더링할 수 있게 해줍니다. FastAPI는 Jinja2를 지원합니다. Jinja2를 설치하기 위해 다음을 사용합니다:

pip install jinja2

Jinja2를 설정하기 위해 다음과 같이 코드를 수정합니다:

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from fastapi import Request

app = FastAPI()
templates = Jinja2Templates(directory="templates")

@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

위 코드에서 Jinja2Templates 클래스를 사용하여 템플릿 디렉토리를 설정했습니다. 이제 templates 폴더를 만들고 index.html 파일을 생성하여 다음과 같은 내용을 추가합니다:

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>FastAPI와 Jinja2</title>
</head>
<body>
    <h1>FastAPI와 Jinja2 템플릿 예제</h1>
    <p>안녕하세요, FastAPI!</p>
</body>
</html>

Jinja2의 필터 사용하기

Jinja2에서 필터를 사용하면 템플릿에서 변수를 변경하거나 가공할 수 있습니다. 예를 들어, 날짜 형식을 변환하거나, 텍스트를 대문자나 소문자로 변경하는 등의 작업을 할 수 있습니다.

이제 Jinja2 필터를 사용하여 변수를 처리하는 방법을 살펴보겠습니다. index.html 파일을 다음과 같이 수정합니다:

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>FastAPI와 Jinja2</title>
</head>
<body>
    <h1>FastAPI와 Jinja2 템플릿 예제</h1>
    <p>안녕하세요, FastAPI!</p>

    <p>현재 시간: {{ current_time|strftime("%Y-%m-%d %H:%M:%S") }}</p>
</body>
</html>

각 요청 시 현재 시간이 표시되는 기능을 추가해 보겠습니다. 이를 위해 FastAPI에 시간 정보를 넘겨주어야 합니다. main.py를 다음과 같이 수정합니다:

from datetime import datetime

@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
    current_time = datetime.now()
    return templates.TemplateResponse("index.html", {"request": request, "current_time": current_time})

이제 브라우저에서 페이지를 새로 고침하면 현재 날짜와 시간이 형식화되어 나타납니다.

기본 제공 필터

Jinja2에서 제공하는 기본 필터들 중 일부를 소개하겠습니다:

  • lower: 문자열을 소문자로 변환합니다.
  • upper: 문자열을 대문자로 변환합니다.
  • capitalize: 첫 글자를 대문자로 변환합니다.
  • title: 각 단어의 첫 글자를 대문자로 변환합니다.
  • replace: 문자열에서 특정 부분을 대체합니다.

예를 들어, 문자열을 대문자로 변환하는 예를 보여드리겠습니다. index.html를 다음과 같이 수정합니다:

    <p>대문자 변환: {{ "hello fastapi"|upper }}</p>

위의 코드를 추가하면 “hello fastapi”라는 문자열이 대문자로 변환되어 출력됩니다.

자체 정의 필터 만들기

Jinja2에서는 사용자가 직접 필터를 정의할 수도 있습니다. FastAPI에서 Jinja2 템플릿에 새로운 필터를 추가하는 방법은 다음과 같습니다. 먼저 필터 함수를 정의합니다:

def custom_filter(value: str) -> str:
    return value.replace("FastAPI", "빠른 API")

그 다음, 이 필터를 템플릿 환경에 등록합니다:

from fastapi import FastAPI
from fastapi.templating import Jinja2Templates

app = FastAPI()
templates = Jinja2Templates(directory="templates")

templates.env.filters['custom_filter'] = custom_filter

마지막으로 index.html에서 이 필터를 사용하여 아래와 같이 업데이트합니다:

    <p>사용자 정의 필터 적용: {{ "FastAPI는 빠르고 쉬운 웹 프레임워크입니다 "|custom_filter}}</p>

결론

FastAPI를 사용한 웹 서버 개발과 Jinja2 템플릿 엔진을 활용한 동적 템플릿 렌더링 방법을 살펴보았습니다. 또한 필터를 사용하여 데이터를 표시하는 방법과 사용자 정의 필터를 만드는 방법도 알아보았습니다. 이 조합을 통해 다양한 웹 애플리케이션을 손쉽게 개발할 수 있습니다.

더 많은 정보를 얻으시려면 FastAPI 공식 문서Jinja2 공식 문서를 참고하시기 바랍니다.

FastAPI 서버개발, Docker 설치

현대적인 웹 애플리케이션 개발에 있어 FastAPI는 빠르고, 직관적이며, 현대적인 프레임워크로 많은 개발자들에게 사랑받고 있습니다. 본 문서에서는 FastAPI로 백엔드 서버를 개발하는 과정과 이를 Docker를 통해 컨테이너화하는 방법에 대해 자세히 설명하겠습니다. FastAPI의 장점을 살리고, Docker를 활용하여 개발 환경을 표준화하고 배포의 용이성을 극대화할 수 있습니다.

목차

1. FastAPI 소개

FastAPI는 Pydantic과 Starlette를 기반으로 하는 Python web framework으로, RESTful API를 쉽게 구축할 수 있도록 설계되었습니다. 모델 정의, 자동화된 API 문서화, 비동기 처리를 지원하며, 높은 성능과 직관적인 문법으로 인기를 얻고 있습니다. FastAPI는 다음과 같은 주요 기능을 제공합니다:

  • 자동 문서화: OpenAPI와 JSON Schema를 기반으로 하는 자동화된 문서화 기능.
  • 비동기 프로그래밍: Python의 async/await를 활용하여 높은 성능을 지원.
  • 타입 힌트: Pydantic을 통해 데이터 검증 및 변환 지원.
  • 미들웨어 및 의존성 주입: 다양한 미들웨어와 의존성 관리 기능으로 효율적인 코드 작성.

2. FastAPI 설치

FastAPI와 Uvicorn을 설치하기 위해 Python이 설치되어 있어야 합니다. Python 3.6 이상이 필요하며, 다음과 같이 FastAPI와 Uvicorn을 설치할 수 있습니다:

pip install fastapi uvicorn

설치가 완료되면, 필요한 경우 Pydantic과 같은 추가 라이브러리도 설치할 수 있습니다.

3. FastAPI 기본 예제

FastAPI로 간단한 RESTful API 서버를 만들어 보겠습니다. 아래의 코드는 기본적으로 사용자 정보를 추가하고 조회하는 API를 구현합니다:

from fastapi import FastAPI
from pydantic import BaseModel
from typing import List

app = FastAPI()

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

users = []

@app.post("/users/", response_model=User)
async def create_user(user: User):
    users.append(user)
    return user

@app.get("/users/", response_model=List[User])
async def get_users():
    return users

이 코드는 POST 요청을 통해 사용자를 생성하고, GET 요청을 통해 사용자 목록을 조회하는 API를 제공합니다. 서버를 실행하려면 다음과 같은 커맨드를 사용합니다:

uvicorn main:app --reload

이제 http://127.0.0.1:8000/docs에 접속하면 Swagger UI를 통해 API 문서를 확인하고 테스트할 수 있습니다.

4. Docker 소개

Docker는 애플리케이션을 독립적인 컨테이너에서 실행할 수 있도록 도와주는 플랫폼입니다. 컨테이너는 빠르고 경량화된 실행 환경을 제공하여 다양한 환경에서 실행할 수 있는 애플리케이션을 쉽게 배포할 수 있습니다. Docker를 사용하면 다음과 같은 이점을 얻을 수 있습니다:

  • 일관된 환경: 개발 환경과 프로덕션 환경 간의 차이를 줄입니다.
  • 빠른 배포: 컨테이너를 사용하면 복잡한 설치 과정 없이 빠르게 배포할 수 있습니다.
  • 확장성: 쉽게 확장하고, 여러 개의 컨테이너를 동시에 관리할 수 있습니다.

5. Docker 설치

Docker를 설치하는 과정은 운영 체제에 따라 다르지만, 대체로 다음과 같은 단계를 따릅니다. 여기서는 Ubuntu를 기준으로 설명합니다:

  1. Docker의 공식 GPG 키를 추가합니다:
  2. sudo apt-get remove docker docker-engine docker.io containerd runc
    sudo apt-get update
    sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  3. Docker를 설치합니다:
  4. sudo apt-get update
    sudo apt-get install docker-ce
  5. Docker가 정상적으로 설치되었는지 확인합니다:
  6. sudo docker --version

이제 Docker를 사용할 준비가 완료되었습니다.

6. Docker로 FastAPI 애플리케이션 배포

FastAPI 애플리케이션을 Docker에서 실행하기 위해서는 Dockerfile을 작성해야 합니다. 다음은 FastAPI 애플리케이션을 위한 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"]

위의 Dockerfile에서 requirements.txt에는 FastAPI와 Uvicorn을 포함시킵니다:

fastapi
uvicorn

이제 Docker 이미지를 빌드할 수 있습니다:

sudo docker build -t fastapi-app .

그리고 다음 명령어로 Docker 컨테이너를 실행합니다:

sudo docker run -d -p 80:80 fastapi-app

이제 http://localhost/docs에 접속하여 FastAPI 애플리케이션을 확인할 수 있습니다.

7. 결론

이 글에서는 FastAPI로 RESTful API 서버를 구축하고, Docker를 통해 이를 컨테이너화하는 방법에 대해 설명했습니다. FastAPI는 빠르고 효율적인 웹 개발을 지원하며, Docker는 복잡한 배포 과정을 단순화하여 개발자들이 더 나은 경험을 할 수 있도록 도와줍니다. 이러한 도구들을 활용하여 개발 환경을 표준화하고, 효율적인 배포를 이루는 것이 가능합니다.

FastAPI와 Docker를 활용한 개발에 대한 더 많은 예제와 정보는 공식 문서를 참고하시기 바랍니다. 이제 여러분의 애플리케이션을 더 잘 관리하고 배포할 준비가 되셨기를 바랍니다!

FastAPI 서버개발, 요청 및 응답 데이터 검증 및 변환

FastAPI는 간단하고 효율적인 웹 API를 구축할 수 있는 현대적인 프레임워크입니다. Python의 타입 힌트를 적극적으로 활용하여 코드의 가독성을 높이고, 자동으로 OpenAPI 및 JSON Schema를 생성하는 등의 특성을 갖추고 있습니다. 이번 강좌에서는 FastAPI에서 요청 및 응답 데이터의 검증 및 변환 방법에 대해 자세히 알아보겠습니다.

1. 데이터 검증의 필요성

웹 서버는 클라이언트로부터 다양한 형태의 데이터 요청을 받습니다. 이러한 데이터는 종종 예상하지 못한 형식이나 값을 가질 수 있으며, 이로 인해 서버에서 오류가 발생하거나 잘못된 동작을 유발할 수 있습니다. 따라서 데이터의 유효성을 검사하고, 필요시 변환하는 과정이 중요합니다.

2. FastAPI에서의 데이터 검증

FastAPI는 Pydantic이라는 데이터 검증 라이브러리를 사용하여 요청 및 응답 데이터의 검증을 수행합니다. Pydantic의 모델을 선언하고 유효성 검사를 수행하는 방법을 살펴보겠습니다.

2.1 Pydantic 모델 정의하기

Pydantic 모델은 요청 데이터의 구조를 정의하며, 각 필드에 대한 데이터 타입과 제약 조건을 설정할 수 있습니다. 다음은 사용자 정보를 정의하는 Pydantic 모델의 예시입니다.

from pydantic import BaseModel, EmailStr, conint

class User(BaseModel):
    name: str
    email: EmailStr
    age: conint(ge=0)  # 0 이상의 정수

위의 모델은 사용자의 이름, 이메일, 나이를 저장하는 구조체를 정의합니다. 여기서 EmailStr는 유효한 이메일 형식인지 검사하며, conint는 정수 값을 기준으로 제약 조건을 설정합니다.

2.2 FastAPI 엔드포인트에서 데이터 검증하기

이제 이 Pydantic 모델을 FastAPI의 엔드포인트에 사용하여 클라이언트로부터 오는 요청을 검증할 수 있습니다.

from fastapi import FastAPI, HTTPException

app = FastAPI()

@app.post("/users/")
async def create_user(user: User):
    return user

위의 엔드포인트는 POST 요청을 처리하고, 요청 본문에서 사용자 정보를 가져와 검증합니다. 만약 요청 데이터가 유효하지 않다면 FastAPI는 자동으로 422 Unprocessable Entity 오류를 반환합니다.

3. 응답 데이터 검증 및 변환

FastAPI는 응답 데이터도 Pydantic 모델을 사용하여 추천합니다. 이는 응답 형식을 일관되게 유지하고 클라이언트가 받을 데이터를 정확히 알고 있게 합니다.

3.1 응답 모델 정의하기

응답 데이터의 형태도 Pydantic 모델로 정의할 수 있습니다. 예를 들어, 사용자가 생성된 후 반환할 데이터의 형태를 정의합니다.

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

3.2 엔드포인트에서 응답 데이터 사용하기

@app.post("/users/", response_model=UserResponse)
async def create_user(user: User):
    user_id = 1  # 예를 들어, 사용자 ID를 1로 설정
    return UserResponse(id=user_id, name=user.name, email=user.email)

이제 응답 데이터는 UserResponse 모델에 따라 검증되고 변환됩니다. 클라이언트는 명확하게 어떤 형태의 데이터를 받을 수 있는지 알 수 있습니다.

4. 데이터 변환

FastAPI는 요청 데이터 및 응답 데이터의 구조를 변환할 수 있는 방법을 제공합니다. 예를 들어, 클라이언트가 UUID 형식의 ID를 보낸다고 가정할 때, 이를 정수형 ID로 변환하는 방법을 설명합니다.

4.1 UUID 검증 및 변환

from uuid import UUID

class User(BaseModel):
    name: str
    email: EmailStr
    id: UUID  # UUID로 ID를 정의

이 경우 FastAPI는 클라이언트가 보낸 데이터를 자동으로 UUID 형태로 변환합니다.

4.2 변환 예제 코드

@app.post("/users/", response_model=UserResponse)
async def create_user(user: User):
    user_id = str(user.id)  # UUID에서 문자열로 변환
    # DB에 사용자 정보를 저장하는 로직 추가
    return UserResponse(id=user_id, name=user.name, email=user.email)

5. 전체 예제

전체적인 코드를 종합하여 FastAPI 애플리케이션을 구현하겠습니다. 아래 예시는 사용자 정보를 생성하는 API로, 데이터 검증 및 응답 변환을 포함합니다.

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, EmailStr, conint
from uuid import UUID
import uvicorn

class User(BaseModel):
    name: str
    email: EmailStr
    id: UUID

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

app = FastAPI()

@app.post("/users/", response_model=UserResponse)
async def create_user(user: User):
    user_id = str(user.id)  # UUID에서 문자열로 변환
    # DB에 사용자 정보를 저장하는 로직 추가
    return UserResponse(id=user_id, name=user.name, email=user.email)

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

6. 결론

FastAPI를 사용하여 요청 및 응답 데이터의 검증 및 변환 과정을 간편하게 처리할 수 있는 방법에 대해 알아보았습니다. 이는 서버의 안정성을 증가시키고, 클라이언트와의 통신을 명확하게 하여 개발 효율성을 높이는 데 기여합니다. FastAPI의 데이터 검증 및 변환 기능을 활용하면, 복잡한 비즈니스 로직을 간단하게 구현할 수 있습니다.

이 글을 통해 FastAPI의 장점과 데이터 검증 및 변환 프로세스를 이해하고, 실제 애플리케이션 개발에 적용할 수 있게 되기를 바랍니다.

7. 참고 문서