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

FastAPI는 현대적인 웹 API를 구축하기 위한 고성능 Python 프레임워크로, Starlette과 Pydantic을 기반으로 하고 있습니다. FastAPI는 개발자가 빠르게 API를 구축할 수 있도록 도와주지만, 이 프레임워크의 진정한 힘은 스키마와 타입 정의에 있습니다. 이 글에서는 FastAPI의 스키마를 이해하고, 응답 및 타입 정의가 어떻게 API의 안정성, 문서화, 유용성을 높이는지를 살펴보겠습니다.

1. FastAPI란?

FastAPI는 빠르고 쉽게 API를 구축할 수 있도록 도와주는 Python 웹 프레임워크입니다. 비동기 프로그래밍 지원, 데이터 검증 및 자동 문서화의 강력한 기능을 제공합니다. FastAPI는 특히 RESTful API를 설계하는 데 매우 유용하며, Pydantic을 통해 데이터 검증, 직렬화 및 문서화를 지원합니다.

2. 스키마의 개념

스키마(Schema)는 데이터 구조를 정의하는 청사진입니다. API에서 스키마를 정의함으로써 요청과 응답에서 어떤 데이터가 사용되는지 명확하게 알 수 있습니다. FastAPI에서는 Pydantic 모델을 사용하여 쉽게 스키마를 정의할 수 있습니다. 이러한 모델은 데이터의 유효성 검사를 자동으로 수행하고, 비즈니스 로직을 단순화합니다.

2.1 Pydantic 소개

Pydantic은 Python 데이터 클래스를 기반으로 하는 데이터 검증 및 설정 관리 라이브러리입니다. FastAPI와 통합되어 유효성 검사, 데이터 변환 및 스키마 생성 기능을 제공합니다. Pydantic은 타입 힌트를 사용하여 데이터를 정의하고, 덕타이핑(duck typing)을 통해 데이터 타입의 유효성을 검사합니다.

3. 타입 정의의 힘

FastAPI에서 타입 시스템은 API의 신뢰성을 높이고, 자동 문서화를 가능하게 합니다. 타입을 명시하면, FastAPI는 이를 기반으로 자동으로 API 문서를 생성합니다. 예를 들어, 사용자가 잘못된 타입의 데이터를 요청하면 FastAPI는 자동으로 오류를 반환합니다. 이를 통해 개발자는 보다 안전하고 일관된 API를 유지할 수 있습니다.

3.1 예제 코드와 설명

아래는 간단한 FastAPI 앱을 만드는 예제입니다.

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

app = FastAPI()

class Item(BaseModel):
    id: int
    name: str
    price: float

class ResponseModel(BaseModel):
    message: str
    items: List[Item]

@app.get("/items/", response_model=ResponseModel)
async def get_items():
    fake_items = [
        {"id": 1, "name": "Item 1", "price": 10.5},
        {"id": 2, "name": "Item 2", "price": 20.0},
    ]
    return {"message": "Items retrieved successfully", "items": fake_items}
        

위의 코드는 FastAPI와 Pydantic을 사용하여 간단한 GET API를 정의합니다. Item 클래스는 개별 아이템의 구조를 정의합니다. ResponseModel 클래스는 API 응답의 구조를 정의합니다. get_items 함수는 아이템 목록을 반환하며, 이때 response_model 파라미터를 사용해 응답 모델을 정의합니다. 이는 FastAPI가 자동으로 JSON 응답을 생성하고 문서화를 제공하는 데 도움을 줍니다.

4. 데이터 검증

Pydantic을 사용하면 데이터 검증을 쉽게 수행할 수 있습니다. 모델 정의 시 타입 힌트를 추가하면 FastAPI는 이 정보를 활용하여 API 요청을 검증합니다. 요청 데이터가 유효하지 않으면 FastAPI는 적절한 오류 메시지를 반환합니다.

4.1 요청 데이터 검증 예제

아래는 POST 요청으로 아이템을 추가하는 API의 예제입니다.


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

app = FastAPI()

class Item(BaseModel):
    id: int
    name: str
    price: float

items = []

@app.post("/items/", response_model=Item)
async def create_item(item: Item):
    for existing_item in items:
        if existing_item.id == item.id:
            raise HTTPException(status_code=400, detail="Item with this ID already exists.")
    items.append(item)
    return item
        

위의 코드는 POST 요청을 통해 새로운 아이템을 추가하는 API를 정의합니다. Item이 이미 존재하는지 확인하는 로직을 추가하여 데이터 유효성을 관리합니다. FastAPI는 자동으로 요청(body)을 Item 타입으로 변환하고, 타입 검증을 수행합니다.

5. 자동 문서화

FastAPI는 OpenAPI 스펙에 따라 API 문서를 자동으로 생성합니다. 이 문서에는 모든 엔드포인트, 요청 및 응답 모델이 나열되며, 사용자 친화적인 UI를 제공합니다. FastAPI의 자동화된 문서화 기능은 API의 사용성을 극대화하고, 개발자가 API를 보다 쉽게 이해하도록 도와줍니다.

5.1 Swagger UI와 ReDoc

FastAPI는 기본적으로 Swagger UI와 ReDoc을 지원합니다. 브라우저에서 http://localhost:8000/docs에 접근하면 Swagger UI를 통해 API 문서를 볼 수 있습니다. /redoc 경로를 통해 ReDoc을 사용할 수도 있습니다. 이 문서들은 API의 모든 엔드포인트, 파라미터, 데이터 모델에 대한 정보를 제공합니다.

6. 실전 예제 – 간단한 블로그 API

이제 FastAPI의 타입 정의와 스키마의 강력함을 실제로 구현해보겠습니다. 간단한 블로그 API를 구축하고, 포스트 및 댓글을 관리하는 기능을 추가해보겠습니다.

6.1 블로그 모델 정의


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

app = FastAPI()

class Comment(BaseModel):
    username: str
    content: str

class Post(BaseModel):
    id: int
    title: str
    content: str
    comments: List[Comment] = []

posts = []

@app.post("/posts/", response_model=Post)
async def create_post(post: Post):
    for existing_post in posts:
        if existing_post.id == post.id:
            raise HTTPException(status_code=400, detail="Post with this ID already exists.")
    posts.append(post)
    return post

@app.get("/posts/", response_model=List[Post])
async def get_posts():
    return posts
        

위의 코드는 블로그 포스트와 댓글을 정의하는 모델을 생성합니다. 블로그 API에는 포스트를 생성하고 조회하는 엔드포인트가 포함되어 있습니다. create_post 함수는 포스트 객체를 리스트에 추가하고, 중복 ID를 처리하기 위해 오류 처리를 수행합니다.

7. 결론

FastAPI는 빠르고 간편한 API 구축을 위한 강력한 도구입니다. Pydantic을 활용한 타입 정의와 스키마 관리 기능은 API의 안정성 및 문서화의 질을 높입니다. 이러한 기능들은 개발자가 보다 안전하고 효율적인 API를 설계할 수 있도록 도와줍니다.

본 글에서는 FastAPI의 기본 개념과 함께 스키마와 타입 정의의 중요성을 설명하였습니다. 실전 예제를 통해 API를 작성하는 과정에서 발생하는 여러 가지 상황을 다루었습니다. FastAPI의 도구들을 사용하면 API 개발이 더욱 효율적이고 즐거운 경험이 될 것입니다.

작성자: {Your Name}

날짜: {Current Date}

FastAPI 서버개발, FastAPI 애플리케이션을 Docker 컨테이너로 배포하기

FastAPI는 최신 Python 웹 프레임워크 중 하나로, 빠른 개발 속도와 높은 성능을 제공합니다. 특히 RESTful API를 쉽게 만드는 데 적합하며, 비동기 프로그래밍 모델을 지원하여 고성능 웹 서비스를 구축할 수 있습니다. 이 블로그 글에서는 FastAPI 애플리케이션을 Docker 컨테이너로 배포하는 방법을 자세히 설명하도록 하겠습니다.

목차

1. FastAPI 애플리케이션 만들기

FastAPI 애플리케이션을 만들기 위해서는 먼저 필요한 라이브러리를 설치해야 합니다. 아래 명령어를 사용하여 FastAPI와 UVicorn (ASGI 서버)을 설치합니다.

pip install fastapi uvicorn

이제 간단한 FastAPI 애플리케이션을 만들어 보겠습니다. 아래 코드는 기본적인 “Hello, World!” API를 생성합니다.

from fastapi import FastAPI

app = FastAPI()

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

위 코드를 main.py라는 이름의 파일로 저장합니다. 이 애플리케이션을 실행하기 위해서는 다음 명령어를 입력합니다.

uvicorn main:app --reload

이제 웹 브라우저를 열어 http://127.0.0.1:8000에 접속하면 {“Hello”: “World”}라는 JSON 응답을 확인할 수 있습니다.

2. Docker 환경 설정

Docker를 사용하면 FastAPI 애플리케이션을 컨테이너화하여 쉽게 배포할 수 있습니다. Docker가 설치되어 있지 않다면, [Docker 공식 웹사이트](https://www.docker.com/get-started)에서 설치할 수 있습니다.

Docker 설치가 완료되면, Docker가 정상적으로 작동하는지 확인하기 위해 아래 명령어를 입력해보세요.

docker --version

정상적으로 설치되었다면 Docker 버전이 출력될 것입니다.

3. Dockerfile 작성

Dockerfile은 Docker 이미지를 생성하기 위한 명세서입니다. FastAPI 애플리케이션을 Docker로 실행하기 위한 Dockerfile을 아래와 같이 작성합니다.

# Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9

COPY ./app /app

# 애플리케이션 디렉토리 설정
WORKDIR /app

# 필요한 패키지 설치
RUN pip install --no-cache-dir fastapi

# UVicorn 서버를 사용하여 애플리케이션 실행
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]

위 Dockerfile에서는 FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9를 사용하여 FastAPI를 위한 기본 이미지를 설정합니다. 그 다음, 애플리케이션 파일을 Docker 이미지로 복사하고, 필요한 패키지를 설치한 후 UVicorn을 통해 FastAPI 애플리케이션을 실행하도록 설정합니다.

4. Docker 이미지 빌드

Dockerfile을 작성한 후, 이제 Docker 이미지를 빌드합니다. 다음 명령어를 사용하여 Docker 이미지를 생성할 수 있습니다.

docker build -t myfastapiapp .

여기서 -t 플래그는 이미지를 태그하는 것으로, 후에 컨테이너를 실행할 때 이 태그를 사용하게 됩니다.

5. Docker 컨테이너 실행

성공적으로 Docker 이미지를 빌드한 후, 이제 컨테이너를 실행할 수 있습니다. 아래 명령어를 사용하여 컨테이너를 실행합니다.

docker run -d --name fastapi_container -p 8000:80 myfastapiapp

여기서 -d 플래그는 디태치드 모드로 컨테이너를 실행하며, --name 플래그는 컨테이너의 이름을 설정합니다. -p 플래그는 로컬의 8000 포트를 Docker 컨테이너의 80 포트와 연결합니다.

컨테이너가 실행 중인지 확인하려면 다음 명령어를 입력합니다.

docker ps

이제 웹 브라우저를 열고 http://127.0.0.1:8000에 접속하면 FastAPI 애플리케이션이 정상적으로 작동하는 것을 확인할 수 있습니다.

6. 결론

이번 글에서는 FastAPI 애플리케이션을 Docker 컨테이너로 배포하는 방법을 다뤄보았습니다. FastAPI의 설치부터 시작하여 Docker 환경 설정, Dockerfile 작성, 이미지 빌드, 컨테이너 실행까지의 모든 과정을 살펴보았습니다. 이제 여러분은 FastAPI 애플리케이션을 손쉽게 Docker로 배포할 수 있는 기반을 갖추게 되셨습니다.

Docker는 애플리케이션을 컨테이너화하여 실행 환경을 일관되게 제공해주는 강력한 도구입니다. 이를 통해 개발자는 다양한 플랫폼에서 애플리케이션을 쉽게 배포하고 관리할 수 있습니다. FastAPI와 Docker의 조합은 현대의 웹 개발에서 필수적인 기술 중 하나가 될 것입니다.

앞으로도 FastAPI와 같은 최신 기술을 활용하여 더욱 향상된 웹 서비스 개발에 도전해보시기 바랍니다!

FastAPI 서버개발, aiomysql 설치

FastAPI는 파이썬으로 작성된 현대적인 웹 프레임워크로, APIs를 빠르게 구축하고 문서화하는 데 있어 효율성을 제공합니다. 이 글에서는 FastAPI를 사용하여 백엔드 서버를 개발하는 방법과 함께 비동기 MySQL 데이터베이스 클라이언트인 aiomysql의 설치 및 활용 방법에 대해 알아보겠습니다.

1. FastAPI 소개

FastAPI는 비동기 지원을 제공하며, Starlette 및 Pydantic을 기반으로 개발되었습니다. 이 프레임워크의 가장 큰 장점 중 하나는 데이터 검증 및 직렬화가 자동으로 이루어진다는 점입니다. 이는 개발자가 API를 개발하는 데 드는 시간을 크게 단축시켜 줍니다.

1.1 FastAPI의 주요 특징

  • 비동기 지원: 매우 빠른 성능을 제공합니다.
  • 자동 API Documentation: Swagger와 ReDoc을 통해 문서화가 자동으로 이루어집니다.
  • 데이터 검증: Pydantic을 사용해 데이터 검증이 자동으로 이루어집니다.
  • 의존성 주입: 쉽게 의존성을 설정하고 관리할 수 있습니다.

2. FastAPI 설치

FastAPI를 설치하기 위해서는 pip를 사용하여 간단히 설치할 수 있습니다. 다음 명령어를 입력해 설치해 주세요:

pip install fastapi[all]

3. 기본 FastAPI 애플리케이션 만들기

FastAPI를 설치한 후, 기본 애플리케이션을 만들어 보겠습니다. 아래 예제 코드를 사용하여 main.py라는 파일을 생성하고, 다음 코드를 붙여 넣습니다:

from fastapi import FastAPI

app = FastAPI()

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

위 코드는 기본 FastAPI 애플리케이션을 설정하는 코드로, 루트 endpoint에 GET 요청을 보내면 {"Hello": "World"}라는 JSON 응답을 반환합니다. FastAPI 서버를 실행하려면 다음 명령어를 터미널에 입력하세요:

uvicorn main:app --reload

여기서 --reload 옵션은 코드 변경 시 서버를 자동으로 재시작해 주는 기능을 제공합니다. 서버가 실행되면 http://127.0.0.1:8000 주소에서 애플리케이션을 확인할 수 있습니다.

4. aiomysql 설치

이제 FastAPI 애플리케이션에 MySQL 데이터베이스를 연결하기 위해 aiomysql을 설치해 보겠습니다. aiomysql은 asyncio 기반의 MySQL 클라이언트로, 비동기적으로 MySQL과 상호작용할 수 있도록 해줍니다. aiomysql을 설치하기 위해 아래 명령어를 실행합니다:

pip install aiomysql

5. MySQL 데이터베이스 설정

설치가 완료되면 MySQL 서버를 준비해야 합니다. MySQL 서버를 실행하고, 아래 명령어를 사용하여 새 데이터베이스를 생성합니다:

CREATE DATABASE fastapi_db;

5.1 데이터베이스 테이블 생성

데이터베이스 안에 사용할 테이블을 생성해보겠습니다. 예를 들어 Users라는 테이블을 생성하고, 사용자 정보를 저장해보겠습니다:

CREATE TABLE Users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(100) NOT NULL,
        email VARCHAR(100) NOT NULL UNIQUE
    );

6. FastAPI와 aiomysql 통합

이제 FastAPI 애플리케이션에서 MySQL에 연결해 보겠습니다. 아래 코드는 FastAPI와 aiomysql을 사용하여 데이터베이스에 연결하고, 데이터를 삽입하고 조회하는 기본적인 API를 만드는 방법을 보여줍니다. 아래 코드를 main.py에 추가하세요:

import aiomysql
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional

app = FastAPI()

# MySQL 데이터베이스 연결 설정
DB_CONFIG = {
    "host": "localhost",
    "port": 3306,
    "user": "your_username",
    "password": "your_password",
    "db": "fastapi_db"
}

# 데이터 모델 정의
class User(BaseModel):
    name: str
    email: str

# 비동기 함수: 데이터베이스 연결
async def get_db_connection():
    conn = await aiomysql.connect(**DB_CONFIG)
    return conn

# 사용자 추가
@app.post("/users/", response_model=User)
async def create_user(user: User):
    conn = await get_db_connection()
    async with conn.cursor() as cursor:
        await cursor.execute("INSERT INTO Users (name, email) VALUES (%s, %s)", (user.name, user.email))
        await conn.commit()
        user_id = cursor.lastrowid
    conn.close()
    return {**user.dict(), "id": user_id}

# 사용자 목록 조회
@app.get("/users/", response_model=List[User])
async def read_users():
    conn = await get_db_connection()
    async with conn.cursor(aiomysql.DictCursor) as cursor:
        await cursor.execute("SELECT * FROM Users")
        result = await cursor.fetchall()
    conn.close()
    return result
    

6.1 API 테스트

이제 FastAPI 애플리케이션을 다시 실행한 후 API를 테스트해보세요. 예를 들어, 사용자 추가를 위해 다음과 같은 POST 요청을 보낼 수 있습니다:

curl -X POST "http://127.0.0.1:8000/users/" -H "Content-Type: application/json" -d "{\"name\": \"John\", \"email\": \"john@example.com\"}"

이 후, 사용자 목록 조회를 위해 다음 GET 요청을 보낼 수 있습니다:

curl -X GET "http://127.0.0.1:8000/users/"

7. 에러 핸들링

FastAPI에서의 에러 핸들링은 매우 간단합니다. 예를 들어, 사용자가 이메일을 중복해서 추가하려 할 경우를 처리하기 위한 기능을 추가해 보겠습니다:

from fastapi import HTTPException

@app.post("/users/", response_model=User)
async def create_user(user: User):
    conn = await get_db_connection()
    async with conn.cursor() as cursor:
        await cursor.execute("SELECT * FROM Users WHERE email = %s", (user.email,))
        existing_user = await cursor.fetchone()
        if existing_user:
            raise HTTPException(status_code=400, detail="Email already registered")
        await cursor.execute("INSERT INTO Users (name, email) VALUES (%s, %s)", (user.name, user.email))
        await conn.commit()
        user_id = cursor.lastrowid
    conn.close()
    return {**user.dict(), "id": user_id}
    

8. 마치며

FastAPI는 간단하면서도 매우 강력한 웹 프레임워크입니다. aiomysql을 통해 비동기적으로 MySQL과 연결하는 방법을 배웠습니다. 이를 통해 데이터를 효율적으로 관리하고 빠른 성능을 구현할 수 있습니다. 추가적으로, FastAPI의 다양한 기능(예: 의존성 주입, 더 복잡한 데이터 모델 등)을 탐구하며 더 발전된 애플리케이션을 만들어보길 바랍니다.

감사합니다!

FastAPI 서버개발, FastAPI의 확장 기능 및 플러그인 개발하기

FastAPI는 빠르고 현대적인 웹 프레임워크로, Python을 기반으로 RESTful API를 만드는데 최적화되어 있습니다. FastAPI는 뛰어난 성능과 직관적인 사용법 덕분에 많은 개발자들에게 사랑받고 있으며, 다양한 기능과 확장성 덕분에 복잡한 애플리케이션을 구축하는 데에도 유용합니다. 이번 글에서는 FastAPI의 확장 기능과 플러그인 개발에 대해 깊이 있게 탐구해 보겠습니다.

1. FastAPI의 기본 구조 이해하기

FastAPI를 사용하면 간단한 HTTP 엔드포인트를 신속하게 만들 수 있습니다. 다음은 FastAPI의 기본 구조를 보여주는 간단한 예제입니다.

from fastapi import FastAPI

app = FastAPI()

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

위의 코드는 가장 기본적인 FastAPI 서버를 설정하는 예제입니다. FastAPI() 객체를 생성하고, @app.get() 데코레이터를 사용하여 GET 요청에 대한 엔드포인트를 구현합니다.

2. FastAPI의 확장성 이해하기

FastAPI는 여러 가지 내장 기능을 제공하지만, 개발자는 종종 추가적인 기능을 필요로 하게 됩니다. FastAPI는 이러한 필요를 충족시키기 위해 다양한 방법으로 확장할 수 있는 구조를 갖추고 있습니다.

2.1. 의존성 주입과 확장

FastAPI는 의존성 주입 시스템을 통해 경량화된 확장을 지원합니다. 의존성을 정의하고 이를 사용할 수 있는 직접적인 방식으로, 다음과 같은 예제가 있습니다.

from fastapi import Depends

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

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

위의 예에서 get_query_param 함수는 쿼리 파라미터를 가져오는 역할을 하며, Depends를 통해 이를 엔드포인트에 주입합니다.

2.2. Middleware의 활용

FastAPI는 미들웨어를 통해 요청과 응답을 처리하는 로직을 추가할 수 있습니다. 이 기능은 로깅, 인증, CORS 설정 등 다양한 용도로 활용할 수 있습니다. 다음은 미들웨어를 설정하는 예제입니다.

from fastapi.middleware.cors import CORSMiddleware

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

@app.get("/cors/")
async def cors_example():
    return {"message": "CORS 설정이 완료되었습니다."}

위의 코드는 모든 도메인에서 이 API에 대한 요청을 허용하도록 CORS 미들웨어를 설정하는 예입니다.

3. FastAPI 플러그인 개발하기

FastAPI의 확장 기능을 더욱 활용하려면 자체 플러그인을 개발할 수 있습니다. 플러그인은 FastAPI 애플리케이션에 독립적으로 배포 가능하며, 다른 프로젝트에서도 재사용할 수 있는 구성 요소입니다.

3.1. FastAPI 플러그인 구조

플러그인을 만드려면 FastAPI의 APIRouter를 활용해야 합니다. 플러그인을 만들기 위한 기본 구조는 다음과 같습니다.

from fastapi import APIRouter

router = APIRouter()

@router.get("/plugin/")
async def plugin_example():
    return {"message": "플러그인이 작동하고 있습니다."}

위의 코드는 플러그인의 기본적인 구조를 보여줍니다. 여기서 APIRouter를 활용하여 독립적인 엔드포인트를 정의할 수 있습니다.

3.2. 플러그인 통합하기

개발한 플러그인을 FastAPI 애플리케이션에 통합하기 위해서는 다음과 같이 설정할 수 있습니다.

from fastapi import FastAPI
from my_plugin import router as my_plugin_router  # 아까 만든 플러그인 임포트

app = FastAPI()

app.include_router(my_plugin_router)

위의 경우, my_plugin에서 정의한 라우터를 메인 애플리케이션에 통합하고 있습니다.

3.3. 플러그인에서 의존성 주입 사용하기

플러그인 내에서 의존성 주입을 활용하는것도 가능합니다. 아래는 플러그인에서 의존성을 사용하는 예제입니다.

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

@router.get("/plugin_with_dependency/")
async def plugin_with_dependency(q: str = Depends(common_query_param)):
    return {"message": f"수신된 쿼리: {q}"}

위의 예제는 플러그인 내에서 의존성 주입을 통해 쿼리 파라미터를 수신하는 방법을 보여줍니다.

4. FastAPI의 오픈API와 문서화

FastAPI는 OpenAPI를 지원하여 자동으로 API 문서를 생성할 수 있습니다. Swagger UI와 ReDoc와 같은 인터페이스를 통해 API를 테스트하고 문서화할 수 있습니다. 설정은 다음과 같습니다.

app = FastAPI(title="My API", description="이 API는 FastAPI로 만들어졌습니다.", version="1.0.0")

@app.get("/api/docs")
async def get_docs():
    return {"message": "문서화된 API에 접근합니다."}

위의 코드를 통해 API의 documentation URL을 설정하고, API 엔드포인트를 문서화하는 방법을 알 수 있습니다.

5. FastAPI와 데이터베이스 통합

FastAPI를 데이터베이스와 통합하는 것은 웹 애플리케이션 개발에서 중요한 부분입니다. SQLAlchemy와 같은 ORM(Object Relational Mapping)을 사용하여 데이터베이스와의 상호작용을 간편하게 구현할 수 있습니다.

5.1. SQLAlchemy와 FastAPI

다음은 SQLAlchemy를 FastAPI와 연결하는 기본 예제입니다.

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

DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

class Item(Base):
    __tablename__ = "items"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)

Base.metadata.create_all(bind=engine)

app = FastAPI()

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

@app.post("/items/")
async def create_item(item: Item, db: Session = Depends(get_db)):
    db.add(item)
    db.commit()
    db.refresh(item)
    return item

위의 예제는 SQLite 데이터베이스를 사용하여 CRUD(Create, Read, Update, Delete) 작업을 수행하는 FastAPI 서버를 설정하는 방법을 보여줍니다.

6. FastAPI와 비동기 프로그래밍

FastAPI는 비동기 프로그래밍을 지원하여 높은 성능을 제공합니다. 데이터베이스 쿼리와 서버 간의 연결을 비동기로 처리하는 예제는 다음과 같습니다.

import asyncpg
from fastapi import FastAPI

app = FastAPI()

async def connect_db():
    conn = await asyncpg.connect(user='user', password='password', database='db', host='127.0.0.1')
    return conn

@app.get("/async-example/")
async def async_example():
    conn = await connect_db()
    row = await conn.fetch("SELECT * FROM items;")
    await conn.close()
    return row

위의 예제는 asyncpg 라이브러리를 사용하여 PostgreSQL과 비동기적으로 연결하는 예제입니다.

7. 결론

FastAPI는 RESTful API를 신속하게 개발할 수 있는 강력한 프레임워크입니다. 이번 글에서는 FastAPI의 확장 기능과 플러그인 개발 방법에 대해 살펴보았습니다. 의존성 주입, 미들웨어, 플러그인 구조 및 데이터베이스 통합, 비동기 프로그래밍 등 다양한 기능을 통해 FastAPI를 더욱 효과적으로 활용할 수 있습니다. 이러한 지식을 바탕으로 여러분의 프로젝트에서 FastAPI를 적용하고, 멋진 웹 애플리케이션을 만들어 보시기 바랍니다.

FastAPI와 함께 할 멋진 개발 경험을 쌓으시길 바랍니다!

FastAPI 서버개발, 서버리스(SERVERLESS) 아키텍처에서 FastAPI 사용하기

최근 몇 년 동안, 서버리스 아키텍처는 개발자들 사이에서 인기를 얻고 있습니다. 이는 전통적인 서버 구축과 관리의 복잡함에서 벗어나, 코드를 작성하고 배포하는 데 집중할 수 있게 해줍니다. 본 글에서는 FastAPI를 활용하여 서버리스 아키텍처를 구축하는 방법에 대해 자세히 설명하겠습니다.

1. 서버리스 아키텍처란?

서버리스 아키텍처는 개발자가 서버를 직접 관리하지 않고 클라우드 서비스 제공업체에 의해 자동으로 스케일링되고 관리되는 웹 애플리케이션을 구축하는 방법입니다. 이 때 사용되는 서버는 일시적이며 불필요한 서버 관리 작업으로부터 해방될 수 있습니다.

서버리스 아키텍처의 장점은 다음과 같습니다:

  • 비용 효율성: 사용한 만큼만 지불하므로, 유지비용이 적고 비용을 절감할 수 있습니다.
  • 자동 확장: 트래픽이 증가할 때 자동으로 리소스를 할당하므로 수요에 맞춰 조정이 가능합니다.
  • 빠른 배포: 개발자는 비즈니스 로직에 집중하고 인프라 관리에서 벗어날 수 있습니다.

2. FastAPI란?

FastAPI는 Python을 사용하여 API를 구축하기 위한 매우 효율적인 웹 프레임워크입니다. 이는 비동기 프로그래밍을 지원하고, 자동으로 OpenAPI 및 JSON Schema 문서를 생성하며, 빠른 성능을 자랑합니다. FastAPI를 선택하는 이유는 다음과 같습니다:

  • 높은 성능: Starlette를 기반으로 하여 높은 처리량을 자랑합니다.
  • 쉬운 사용법: 기초적인 Python 지식만으로도 쉽게 API를 구축할 수 있습니다.
  • 유효성 검사: Pydantic을 사용하여 데이터 유효성을 자동으로 검사합니다.

3. FastAPI와 서버리스: AWS Lambda로 시작하기

FastAPI를 서버리스 아키텍처에서 사용할 수 있는 곳 중 하나는 AWS Lambda입니다. AWS Lambda는 이벤트 기반으로 서버 코드가 실행되는 컴퓨팅 서비스입니다. 이 연재에서는 FastAPI 애플리케이션을 AWS Lambda에서 실행하는 방법을 설명하겠습니다.

3.1. AWS Lambda와 API Gateway 설정하기

FastAPI 애플리케이션을 AWS Lambda에서 실행할 수 있도록 하기 위해, AWS Lambda와 Amazon API Gateway를 설정해야 합니다.

  1. AWS 계정을 만들고 AWS Management Console에 로그인합니다.
  2. 서비스 목록에서 “Lambda”를 선택한 후 “함수 생성”을 클릭합니다.
  3. 함수 이름을 입력하고 런타임을 “Python 3.x”로 설정 후 “함수 생성”을 클릭합니다.
  4. 함수가 생성되면, “API Gateway” 트리거를 추가합니다.

3.2. FastAPI 애플리케이션 코드 작성하기

FastAPI 애플리케이션을 작성해 보겠습니다. 아래 코드는 기본적인 FastAPI 앱의 예입니다.


from fastapi import FastAPI

app = FastAPI()

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

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

위 코드는 FastAPI 앱을 생성하고 두 개의 엔드포인트를 정의합니다. 첫 번째 엔드포인트는 루트 URL로 요청받을 때 “Hello, World!” 메시지를 반환하며, 두 번째 엔드포인트는 아이템 ID와 쿼리 파라미터를 받아 해당 정보를 반환합니다.

3.3. AWS Lambda에 FastAPI 배포하기

AWS Lambda에 FastAPI 애플리케이션을 배포하려면, Zappa라는 도구를 사용할 수 있습니다. Zappa는 Python 웹 애플리케이션을 서버리스 환경에서 손쉽게 배포할 수 있게 도와주는 프레임워크입니다. 아래 단계로 진행해 보겠습니다.

  1. Zappa 설치하기:
  2. pip install zappa
  3. Zappa 설정 파일 생성하기:
  4. zappa init
  5. 배포하기:
  6. zappa deploy

3.4. CORS 설정하기

서버리스 아키텍처에서 FastAPI 애플리케이션이 다른 도메인에서 요청을 받을 수 있도록 CORS(Cross-Origin Resource Sharing) 설정이 필요할 수 있습니다. FastAPI에서는 CORS 미들웨어를 쉽게 추가할 수 있습니다.


from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 허용할 도메인 목록
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
    

4. FastAPI와 데이터베이스 연동하기

FastAPI와 데이터베이스를 연결하여 실제 애플리케이션을 만드는 것도 가능합니다. SQLAlchemy를 사용하여 FastAPI와 관계형 데이터베이스를 쉽게 연동할 수 있습니다.

4.1. SQLAlchemy 설치하기

pip install sqlalchemy databases

4.2. FastAPI로 데이터베이스 CRUD 작업 구현하기


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

DATABASE_URL = "sqlite:///./test.db"

engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

class Item(Base):
    __tablename__ = "items"

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

Base.metadata.create_all(bind=engine)

@app.post("/items/")
async def create_item(item: Item):
    db = SessionLocal()
    db.add(item)
    db.commit()
    db.refresh(item)
    db.close()
    return item
    

4.3. 비동기 데이터베이스 연결

FastAPI는 비동기 작업을 지원하므로, 데이터베이스 연결 시 비동기 ORM 라이브러리를 사용할 수도 있습니다. databases 라는 라이브러리를 활용하여 비동기로 데이터베이스와 연결해 보겠습니다.


import databases

database = databases.Database(DATABASE_URL)

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

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

@app.post("/async-items/")
async def create_async_item(item: Item):
    query = Item.__table__.insert().values(name=item.name, price=item.price)
    last_record_id = await database.execute(query)
    return {**item.dict(), "id": last_record_id}
    

5. 테스트 및 디버깅

FastAPI는 내장된 테스트 클라이언트를 제공하여 API를 쉽게 테스트할 수 있습니다. pytest와 함께 사용해 보겠습니다. FastAPI 앱을 테스트하려면, 다음과 같이 작성할 수 있습니다.


from fastapi.testclient import TestClient

client = TestClient(app)

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

6. 결론

FastAPI와 서버리스 아키텍처는 함께 사용될 때 고성능의 비즈니스 로직을 처리할 수 있는 훌륭한 조합이 됩니다. AWS Lambda와 같은 서버리스 플랫폼을 활용하여, 트래픽 변화에 따른 유연한 리소스 관리가 가능합니다. FastAPI의 간결한 문법과 빠른 개발 속도로 인해, 개발자들은 애플리케이션의 구현에 더욱 집중하고 개선할 수 있습니다.

오늘 다룬 내용을 바탕으로 실습을 진행하고, 여러분의 프로젝트에 FastAPI와 서버리스 아키텍처를 접목해 보시기 바랍니다. 빠른 성장과 혁신을 위한 좋은 선택이 될 것입니다.