개발/Flask
Flask-RESTX로 Rest API 서버 구성 & Swagger 문서 작성 - 2
8시20분
2021. 10. 22. 08:20
지난 포스트에서 데이터베이스와 Flask를 연동한 것에 이어서 API 설계와 구현을 하려고 한다.
Flask-RESTX로 Rest API 서버 구성 & Swagger 문서 작성 - 1
깃헙 레포: https://github.com/Comparelt/comparelt-api GitHub - Comparelt/comparelt-api: The backend server with Flask & PostgreSQL The backend server with Flask & PostgreSQL. Contribute to Comparelt..
eight20.tistory.com
필요한 API의 기능적인 구분은 다음과 같다
- 로그인/회원가입 API
- 크롤링 API
- 제품 검색 API
로그인/ 회원 가입 API는 flask-restx와 JWT를 사용하여 회원가입과 로그인 유저를 관리하는 것으로 하였다.
Flask 서버의 메인인 app.py에 아래와 같은 내용을 추가하여 API 서버 프레임을 만드는 동시에 Swagger 설명을 작성한다.
# app.py
--------- 생략 ---------
# API 서버 프레임을 구성하고, title과 version을 통해 swagger에 작성합니다.
api = Api(app, version='0.1', title="Comparelt's API Server")
api.add_namespace(Auth, '/auth') # Auth API를 API 서버에 추가합니다.
위와 같이 넣고 Flask 서버를 시작하고, 터미널에 출력되어 있는 ip로 접속해보면 다음과 같이 Swagger로 API 문서가 정리되어 있는 것을 볼 수 있다.
Auth API를 다음과 같이 작성하였다.
#api/auth/__init__.py
Auth = Namespace(name="Auth", description="Auth API")
users = {} # 데이터베이스에서 유저 정보를 가져오는 로직 추가후 변경
user_fields = Auth.model('Email', {
'email': fields.String(description='A User Email', required=True, example="dku@example.com")
}) # Swaager에 설명, 예시 및 require을 입력한다.
user_fields_auth = Auth.inherit('User Auth', user_fields, {
'password': fields.String(description='Password', required=True, example="password"),
'username': fields.String(description='Username', required=True, example='dku')
})
@Auth.route('/signup')
class AuthRegister(Resource):
@Auth.expect(user_fields_auth)
@Auth.doc(responses={200: 'Success'})
@Auth.doc(responses={409: 'Duplicated user'})
def post(self):
email = request.json['email']
password = request.json['password']
if email in users:
return {
"message": "Duplicated user"
}, 409
else:
users[email] = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()) # save password
return {
'Authorization': jwt.encode({'email': email}, "secret", algorithm="HS256").decode("UTF-8")
}, 200
@Auth.route('/login')
class AuthLogin(Resource):
@Auth.expect(user_fields_auth)
@Auth.doc(responses={200: 'Success'})
@Auth.doc(responses={401: 'UnAuthorized'})
@Auth.doc(responses={404: 'User Not Found'})
def post(self):
email = request.json['email']
password = request.json['password']
if email not in users:
return {
"message": "User Not Found"
}, 404
elif not bcrypt.checkpw(password.encode('utf-8'), users[email]): # If password is correct
return {
"message": "Auth Failed"
}, 401
else:
return {
'Authorization': jwt.encode({'email': email}, "secret", algorithm="HS256").decode("UTF-8")
# return as String
}, 200
@Auth.route('/get')
class AuthGet(Resource):
@Auth.header(name='JWT',
description='Authorization which you must included in header', example="eyJ0eo02e5tg")
@Auth.doc(responses={200: 'Success'})
@Auth.doc(responses={401: 'Login Failed'})
def get(self):
header = request.headers.get('Authorization') # Authorization into request header
if header is None:
return {"message": "Please Login"}, 401
data = jwt.decode(header, "secret", algorithm="HS256")
return data, 200
위와 같이 구성하고 Flask를 재시작하고, Swaager를 보면 아래와 같이 API가 추가되고, 해당 설명, 예시, 필수 사항이 입력되어있다.
이번 포스트는 로그인 / 회원가입 API를 추가하고, API 관련 설명을 Swagger로 정리하였다.