Flasgger를 활용한 Flask API 문서화 가이드

프로젝트 개요

Flasgger는 Flask 애플리케이션에서 OpenAPI 스펙을 자동 추출하고, Swagger UI를 통해 API를 시각적으로 탐색하고 테스트할 수 있게 해주는 확장 라이브러리입니다. YAML, Python 딕셔너리, Marshmallow 스키마 등 다양한 방식으로 데이터 유효성을 검증할 수 있어 API 개발 생산성을 크게 향상시킵니다.

환경 설정 및 설치

먼저 가상 환경을 생성하고 활성화합니다:

python -m venv api_env
source api_env/bin/activate  # Windows: api_env\Scripts\activate

필요한 패키지를 설치합니다:

pip install flask flasgger

기본 Flask 애플리케이션 구축

app.py 파일을 생성하고 다음 코드를 추가합니다:

from flask import Flask, jsonify, request
from flasgger import Swagger

app = Flask(__name__)
Swagger(app)

@app.route('/users/', methods=['GET'])
def get_user(user_id):
    """
    사용자 정보 조회 엔드포인트
    특정 사용자의 상세 정보를 반환합니다
    ---
    tags:
      - 사용자 관리
    parameters:
      - name: user_id
        in: path
        type: integer
        required: true
        description: 조회할 사용자의 고유 ID
    responses:
      200:
        description: 사용자 정보 조회 성공
        schema:
          id: User
          properties:
            user_id:
              type: integer
            username:
              type: string
            email:
              type: string
    """
    users = {
        1: {'username': 'kim', 'email': 'kim@example.com'},
        2: {'username': 'lee', 'email': 'lee@example.com'},
    }
    user = users.get(user_id)
    if not user:
        return jsonify({'error': '사용자를 찾을 수 없습니다'}), 404
    return jsonify({'user_id': user_id, **user})

if __name__ == '__main__':
    app.run(debug=True)

애플리케이션 실행:

python app.py

브라우저에서 http://localhost:5000/apidocs에 접근하면 Swagger UI 인터페이스를 확인할 수 있습니다.

YAML을 활용한 API 스펙 정의

docstring에 YAML 형식으로 API 문서를 작성하는 방법을 알아봅니다:

@app.route('/products', methods=['POST'])
def create_product():
    """
    상품 생성 엔드포인트
    새로운 상품을 데이터베이스에 등록합니다
    ---
    tags:
      - 상품 관리
    parameters:
      - name: body
        in: body
        required: true
        schema:
          id: Product
          required:
            - name
            - price
          properties:
            name:
              type: string
              description: 상품명
              example: 노트북
            price:
              type: number
              description: 상품 가격
              example: 150000
            category:
              type: string
              description: 카테고리
              default: 전자제품
    responses:
      201:
        description: 상품 생성 성공
      400:
        description: 유효성 검증 실패
    """
    payload = request.json
    return jsonify({
        'id': 101,
        'name': payload['name'],
        'price': payload['price'],
        'status': 'created'
    }), 201

Marshmallow를 활용한 데이터 검증

Marshmallow 스키마를 정의하고 이를 통해 요청 데이터를 검증합니다:

from flask import Flask, jsonify, request
from flasgger import Swagger, swag_from
from marshmallow import Schema, fields, ValidationError

app = Flask(__name__)
swagger = Swagger(app)

class OrderSchema(Schema):
    product_id = fields.Integer(required=True)
    quantity = fields.Integer(required=True, validate=lambda x: 1 <= x <= 100)
    customer_name = fields.Str(required=True)
    shipping_address = fields.Str(required=False)

@app.route('/orders', methods=['POST'])
@swag_from({
    'tags': ['주문 관리'],
    'parameters': [{
        'name': 'body',
        'in': 'body',
        'required': True,
        'schema': {
            'id': 'Order',
            'required': ['product_id', 'quantity', 'customer_name'],
            'properties': {
                'product_id': {'type': 'integer', 'description': '상품 ID'},
                'quantity': {'type': 'integer', 'description': '주문 수량'},
                'customer_name': {'type': 'string', 'description': '고객 이름'},
                'shipping_address': {'type': 'string', 'description': '배송지'}
            }
        }
    }],
    'responses': {
        '201': {'description': '주문 생성 성공'},
        '400': {'description': '입력 데이터 오류'}
    }
})
def create_order():
    schema = OrderSchema()
    try:
        validated_data = schema.load(request.json)
    except ValidationError as err:
        return jsonify({'validation_errors': err.messages}), 400
    
    return jsonify({
        'order_id': 5001,
        'status': 'pending',
        **validated_data
    }), 201

if __name__ == '__main__':
    app.run(debug=True)

외부 YAML 파일 활용

별도의 YAML 파일에 API 스펙을 정의하고 swag_from으로 로드할 수 있습니다:

# apispec.yml
---
tags:
  - 카테고리 관리
parameters:
  - name: category_id
    in: path
    type: integer
    required: true
    description: 카테고리 ID
responses:
  200:
    description: 카테고리 삭제 성공
  404:
    description: 카테고리를 찾을 수 없음
@app.route('/categories/', methods=['DELETE'])
@swag_from('apispec.yml')
def delete_category(category_id):
    return jsonify({'message': f'카테고리 {category_id}가 삭제되었습니다'}), 200

주요 확장 프로그램

Flask-RESTful: RESTful API 구축을 위한 Flask 확장이며, Flasgger와 함께 사용하면 API 개발 워크플로우를 효율화할 수 있습니다.

Marshmallow: ORM/ODM에 의존하지 않는 데이터 직렬화 및 검증 라이브러리로, 복잡한 데이터结构的 유효성을 검증하고 객체로 변환하는 역할을 합니다.

태그: flask swagger openapi rest-api marshmallow

5월 24일 18:11에 게시됨