Flask OpenAPI 문서와 Swagger UI 노출 예제 Flask-Smorest RESTX 설정 가이드
📌 파이썬 Flask로 OpenAPI 문서화와 Swagger UI를 몇 분 만에 완성하는 실전 예제
프로덕션에서 API를 운영하다 보면 문서와 실제 동작이 어긋나 버리는 순간이 가장 아프죠.
팀원이 바뀌거나 클라이언트가 늘수록 자동화된 문서화의 유용함이 커집니다.
이 글은 Flask 기반 프로젝트에서 OpenAPI 문서와 Swagger UI를 깔끔하게 노출하는 방법을 다룹니다.
특히 Flask-Smorest와 Flask-RESTX 두 가지 대표 라이브러리를 비교·이해하기 쉽게 정리해, 상황에 맞는 선택과 설정을 도와드립니다.
설치부터 기본 설정, 스키마 정의, 보안 스키마, 예제 코드 구성까지 핵심만 골라 안내합니다.
복잡한 문서 작성 없이도 OpenAPI 스펙을 자동 생성하고, 개발·QA·프론트엔드 협업자 모두가 즐겨 쓰는 Swagger UI를 안정적으로 노출하는 흐름을 목표로 합니다.
엔드포인트별 요청·응답 모델을 명확히 하고, 인증이 필요한 API에는 Bearer 토큰 같은 보안 정의를 적용해 실사용에 무리가 없도록 구성합니다.
또한 로컬 실행과 배포 환경에서의 차이를 고려해 URL 경로와 버전 네임스페이스를 정리하고, 새 팀원이 합류해도 바로 이해할 수 있는 프로젝트 구조를 제안합니다.
📋 목차
🚀 Flask에서 OpenAPI와 스웨거 UI 개요
Flask는 파이썬 진영에서 가장 널리 쓰이는 경량 웹 프레임워크로, RESTful API 서버 구축에 자주 활용됩니다.
단순히 API를 작성하는 것에서 끝나지 않고, 클라이언트와 협업하기 위해서는 OpenAPI 스펙과 Swagger UI 같은 자동 문서화 기능이 필수적입니다.
OpenAPI는 REST API를 설명하는 표준 포맷이며, Swagger UI는 이를 기반으로 인터랙티브하게 API를 테스트할 수 있는 웹 UI를 제공합니다.
전통적으로 Flask는 기본 제공 기능에 이러한 문서화를 포함하지 않습니다.
따라서 확장 라이브러리를 설치해야 하는데, 대표적으로 Flask-Smorest와 Flask-RESTX 두 가지 접근 방식이 있습니다.
이들은 각각 장단점이 뚜렷합니다.
Flask-Smorest는 Marshmallow 스키마와 잘 결합되어 직관적이고 깔끔한 API 스펙 정의가 가능하며, Flask-RESTX는 Swagger UI 노출과 네임스페이스 구조화가 강력한 장점입니다.
📌 OpenAPI와 Swagger UI가 필요한 이유
단순히 문서를 작성하기 위해서라면 마크다운이나 위키도 사용할 수 있습니다.
하지만 OpenAPI를 사용하면 서버 코드에서 바로 요청(Request)과 응답(Response) 모델을 정의할 수 있고, 이를 Swagger UI가 자동으로 시각화해 줍니다.
이 방식은 중복 없는 문서 관리와 API 테스트 자동화를 가능하게 합니다.
결과적으로 QA, 프론트엔드 개발자, 모바일 개발자 모두가 동일한 API 스펙을 보고 확인할 수 있어 협업 효율성이 크게 높아집니다.
- 📖API 문서 자동화로 문서 작성 중복을 줄임
- 🧪Swagger UI에서 실시간 API 테스트 가능
- 🤝프론트엔드, 백엔드, QA 간 협업 효율 향상
💬 Flask에서 OpenAPI와 Swagger UI를 잘 활용하면, 단순히 코드 작성 도구를 넘어 전체 개발 문화와 협업 방식까지 개선할 수 있습니다.
🧰 Flask-Smorest로 OpenAPI 스펙과 문서화 설정
Flask-Smorest는 Flask와 Marshmallow를 기반으로 OpenAPI 스펙을 자동 생성해 주는 강력한 확장 라이브러리입니다.
요청과 응답을 스키마(Validation Schema)로 정의하면 API 문서가 즉시 업데이트되며, Swagger UI와 ReDoc UI도 자동 제공됩니다.
즉, 데이터 유효성 검증과 API 문서화를 동시에 해결할 수 있다는 장점이 있습니다.
📌 설치와 기본 설정
Flask-Smorest를 설치하려면 아래 명령어를 실행합니다.
pip install flask-smorest marshmallow
이후 Flask 앱에 Blueprint와 API 객체를 등록하면 됩니다.
from flask import Flask
from flask_smorest import Api, Blueprint
from marshmallow import Schema, fields
app = Flask(__name__)
app.config["API_TITLE"] = "My API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.2"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist/"
api = Api(app)
blp = Blueprint("users", __name__, url_prefix="/users", description="사용자 관련 API")
class UserSchema(Schema):
id = fields.Int(dump_only=True)
name = fields.Str(required=True)
@blp.route("/")
def list_users():
return [{"id": 1, "name": "Alice"}]
api.register_blueprint(blp)
📌 특징과 장점
- ⚡요청/응답을 Marshmallow 스키마로 간단히 정의 가능
- 🧩자동으로 Swagger UI와 ReDoc UI 제공
- 🛡️스펙 기반 검증으로 API 안정성 확보
💡 TIP: Swagger UI는 /swagger-ui 경로에서, OpenAPI JSON 문서는 /openapi.json 경로에서 확인할 수 있습니다.
🧩 Flask-RESTX로 Swagger UI 구성과 네임스페이스
Flask-RESTX는 Flask-RESTPlus에서 파생된 확장 라이브러리로, Swagger UI를 기본 내장하고 있습니다.
따라서 별도의 설정 없이도 API 문서를 시각화할 수 있으며, 네임스페이스를 통해 엔드포인트 그룹화를 지원해 프로젝트 구조를 정리하기 좋습니다.
빠르게 API 프로토타입을 만들고 테스트할 때 특히 유용합니다.
📌 설치와 기본 사용법
아래와 같이 Flask-RESTX를 설치합니다.
pip install flask-restx
Flask-RESTX는 네임스페이스와 모델을 통해 API를 선언적으로 작성할 수 있습니다.
from flask import Flask
from flask_restx import Api, Resource, fields
app = Flask(__name__)
api = Api(app, version="1.0", title="My API", description="Flask-RESTX Example API")
ns = api.namespace("users", description="사용자 관련 API")
user_model = api.model("User", {
"id": fields.Integer(readonly=True),
"name": fields.String(required=True, description="사용자 이름")
})
users = [{"id": 1, "name": "Alice"}]
@ns.route("/")
class UserList(Resource):
@ns.marshal_list_with(user_model)
def get(self):
return users
위 코드 실행 후 / 경로로 접속하면 Swagger UI가 자동으로 제공되며, /users/ 엔드포인트가 문서에 반영됩니다.
📌 특징과 장점
- 🚀Swagger UI 기본 내장으로 빠른 API 시각화 가능
- 📂네임스페이스 관리로 엔드포인트 그룹화 용이
- ⚡모델 선언을 통한 데이터 구조 명확화
⚠️ 주의: Flask-RESTX는 빠르게 개발하기 좋은 도구지만, Marshmallow 기반의 세밀한 데이터 검증은 제공하지 않으므로 검증 로직은 별도로 작성해야 합니다.
🔐 보안 스키마 Bearer JWT와 요청 검증
API 문서에 인증 정보를 명시하면, Swagger UI에서 바로 토큰을 입력해 보호된 엔드포인트를 시험할 수 있습니다.
일반적으로 Bearer JWT 방식을 사용하며, 요청 헤더의 Authorization: Bearer <토큰> 값을 검증합니다.
Flask-Smorest는 OpenAPI 컴포넌트에 보안 스키마를 선언해 @blp.doc로 엔드포인트에 적용할 수 있고, Flask-RESTX는 Api(..., authorizations=...)로 Swagger UI에 인증 입력창을 노출한 뒤 네임스페이스 또는 리소스 단위로 @api.doc(security=[...])를 붙여 사용합니다.
🛡️ Flask-Smorest에서 Bearer 보안 스키마 선언과 적용
앱 설정에 OpenAPI 컴포넌트와 보안 요구 사항을 추가하고, 블루프린트 또는 엔드포인트에 보안 메타데이터를 부여합니다.
아래 예시는 Swagger UI 상단 Authorize 버튼을 통해 JWT를 입력하고, 해당 토큰이 필요한 경로를 테스트하도록 구성합니다.
from flask import Flask, request
from flask_smorest import Api, Blueprint
from marshmallow import Schema, fields
app = Flask(__name__)
app.config.update(
API_TITLE="My API",
API_VERSION="v1",
OPENAPI_VERSION="3.0.2",
OPENAPI_URL_PREFIX="/",
OPENAPI_SWAGGER_UI_PATH="/swagger-ui",
OPENAPI_SWAGGER_UI_URL="https://cdn.jsdelivr.net/npm/swagger-ui-dist/",
API_SPEC_OPTIONS={
"components": {
"securitySchemes": {
"BearerAuth": {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"}
}
}
}
)
api = Api(app)
blp = Blueprint("secure", __name__, url_prefix="/secure", description="보호된 API")
class PingSchema(Schema):
ok = fields.Bool()
def require_jwt():
auth = request.headers.get("Authorization", "")
if not auth.startswith("Bearer "):
return False
token = auth.split(" ", 1)[1]
# 실제 구현에서는 JWT 서명과 만료를 검증하세요.
return bool(token)
@blp.route("/ping")
@blp.doc(security=[{"BearerAuth": []}], summary="보호된 핑", description="JWT가 필요합니다.")
@blp.response(200, PingSchema)
def ping():
if not require_jwt():
return {"message": "Unauthorized"}, 401
return {"ok": True}
api.register_blueprint(blp)
💡 TIP: 실제 서비스에서는 PyJWT 같은 라이브러리로 서명 키를 사용해 토큰 유효성, 만료, 스코프를 검증하세요.
또한 @blp.arguments와 Marshmallow 스키마로 요청 바디·쿼리 파라미터 검증을 병행하면 안전성이 크게 높아집니다.
🔑 Flask-RESTX에서 Swagger UI 인증창 노출과 보호 엔드포인트
RESTX는 Swagger(UI) 정의에 authorizations를 전달해 인증 입력창을 활성화합니다.
일반적으로 Swagger 2.0 표기에서는 apiKey 타입에 Authorization 헤더를 사용해 Bearer 스킴을 처리합니다.
네임스페이스 또는 개별 리소스에 @api.doc(security=[...])를 적용해 문서와 UI 모두에서 인증을 요구하도록 표시합니다.
from flask import Flask, request
from flask_restx import Api, Resource, Namespace
authorizations = {
"BearerAuth": {
"type": "apiKey",
"in": "header",
"name": "Authorization",
"description": "Add 'Bearer <JWT>'"
}
}
app = Flask(__name__)
api = Api(app, version="1.0", title="My API", authorizations=authorizations)
ns = Namespace("secure", description="보호된 API")
api.add_namespace(ns)
def require_jwt():
auth = request.headers.get("Authorization", "")
return auth.startswith("Bearer ") and len(auth.split(" ", 1)[1]) > 0
@ns.route("/ping")
class Ping(Resource):
@ns.doc(security=[{"BearerAuth": []}], summary="보호된 핑")
def get(self):
if not require_jwt():
return {"message": "Unauthorized"}, 401
return {"ok": True}
🧪 요청 유효성 검증과 에러 응답 표준화
인증 외에도 요청 데이터 검증이 중요합니다.
Flask-Smorest는 Marshmallow를 통해 스키마 기반의 바디·쿼리·경로 파라미터 검증을 간단히 붙일 수 있고, 실패 시 일관된 4xx 응답을 반환합니다.
RESTX는 model과 @expect를 활용해 입력 구조를 명세하고, 필요 시 직접 타입·범위 검사를 수행해 에러 메시지를 표준화하면 소비자 측에서 디버깅이 쉬워집니다.
- 🔒Swagger UI에 BearerAuth를 선언하고 Authorize로 토큰 입력
- 🧾요청 바디·쿼리 검증 스키마를 정의해 4xx 에러를 일관되게 반환
- 🧱실서비스에서는 서명 키/회전, 만료, 권한 스코프 검증 필수
⚠️ 주의: 개발 환경에서 허용한 테스트 비밀키를 운영에 그대로 사용하지 마세요.
HTTPS 미적용, 과도한 토큰 만료 시간, 리프레시 토큰 무제한 발급 등은 심각한 보안 리스크가 됩니다.
🧪 예제 코드 실행 방법과 흔한 오류 해결
Flask-Smorest와 Flask-RESTX 예제 코드를 실행하려면 먼저 프로젝트 환경을 준비해야 합니다.
보통 Python 3.9 이상을 권장하며, 가상환경을 구성한 뒤 필요한 패키지를 설치합니다.
이후 flask run 또는 python app.py 방식으로 서버를 실행할 수 있습니다.
Swagger UI는 기본적으로 /swagger-ui 또는 / 경로에서 확인 가능합니다.
📌 실행 절차
- 📦가상환경 생성 후 진입 (
python -m venv venv) - ⬇️
pip install flask flask-smorest flask-restx marshmallow실행 - ▶️
flask run또는python app.py로 서버 실행 - 🌐브라우저에서 Swagger UI 경로 접속
⚠️ 흔히 발생하는 오류와 해결 방법
| 문제 상황 | 해결 방법 |
|---|---|
| Swagger UI가 표시되지 않음 | Flask-Smorest 설정에서 OPENAPI_SWAGGER_UI_URL 경로 확인, RESTX는 기본 /에서 제공됨 |
| JWT 인증이 항상 실패 | Authorization 헤더에 Bearer <token> 정확히 입력, 토큰 서명·만료 검증 코드 확인 |
| 요청 스키마 검증 에러 | Flask-Smorest는 Marshmallow 스키마 필드 확인, RESTX는 @expect 모델 정의 확인 |
💡 디버깅 팁
실행 시 환경변수에 FLASK_ENV=development를 설정하면 더 상세한 오류 메시지를 확인할 수 있습니다.
또한 Swagger UI의 Authorize 버튼에 JWT를 넣은 뒤 엔드포인트를 테스트하면, 실제 요청에 Authorization 헤더가 어떻게 반영되는지 확인할 수 있습니다.
💎 핵심 포인트:
실행 환경과 Swagger UI 경로, 인증 입력 방법을 올바르게 이해하면 대부분의 오류는 쉽게 해결할 수 있습니다.
❓ 자주 묻는 질문 (FAQ)
Flask-Smorest와 Flask-RESTX 중 어떤 것을 선택해야 하나요?
Swagger UI 주소가 보이지 않을 때 어떻게 해야 하나요?
/swagger-ui에 경로가 있고, Flask-RESTX는 기본 루트(/)에서 문서를 노출합니다. 설정 값과 URL 프리픽스를 다시 확인하세요.
JWT 인증을 Swagger UI에서 바로 테스트할 수 있나요?
Bearer <토큰>을 입력하면 보호된 엔드포인트를 테스트할 수 있습니다.
ReDoc UI도 함께 사용할 수 있나요?
OpenAPI JSON 문서는 어디서 확인할 수 있나요?
/openapi.json 경로에서 확인 가능하며, RESTX는 기본적으로 /swagger.json에서 제공합니다.
운영 환경에서 Swagger UI를 그대로 노출해도 되나요?
Flask-Smorest에서 Marshmallow 스키마는 꼭 필요한가요?
Flask-RESTX에서 모델 검증은 어떻게 처리하나요?
@expect 데코레이터와 api.model을 활용해 요청 구조를 정의할 수 있습니다. 다만 Marshmallow처럼 정교한 검증은 직접 추가해야 합니다.
📝 Flask OpenAPI와 Swagger UI 활용 핵심 정리
Flask 환경에서 OpenAPI 문서와 Swagger UI를 노출하는 방법은 협업 효율성과 안정성을 크게 높여줍니다.
Flask-Smorest는 Marshmallow와 결합해 강력한 데이터 검증과 자동 문서화를 제공하며, Flask-RESTX는 Swagger UI를 기본 내장해 빠르게 프로토타입을 만들고 API를 공유하기에 적합합니다.
보안 측면에서는 Bearer JWT 스키마를 활용해 인증 흐름을 문서화하고 Swagger UI에서 직접 테스트할 수 있도록 구성하는 것이 실무적으로 큰 도움이 됩니다.
또한 실행 환경에서 자주 발생하는 오류를 대비해 Swagger 경로 확인, JWT 헤더 입력 방식 점검, 스키마 검증 로직 확인을 체크리스트로 관리하면 안정적인 운영이 가능합니다.
즉, 적절한 라이브러리 선택과 설정을 통해 Flask 기반 API 개발과 협업 환경을 한층 더 발전시킬 수 있습니다.
🏷️ 관련 태그 : Flask, OpenAPI, SwaggerUI, FlaskSmorest, FlaskRESTX, API문서화, JWT인증, 파이썬프로그래밍, 백엔드개발, RESTAPI