|
1
|
|
|
from typing import Union |
|
2
|
|
|
|
|
3
|
|
|
from flask import Blueprint, Flask |
|
4
|
|
|
from flask_restful import Api, output_json |
|
5
|
|
|
from pydantic import BaseModel |
|
6
|
|
|
|
|
7
|
|
|
|
|
8
|
|
|
def _pydantic_safe_output_json(data: Union[BaseModel, dict, list], code, headers=None): |
|
9
|
|
|
if isinstance(data, BaseModel): |
|
10
|
|
|
data = data.dict() |
|
11
|
|
|
|
|
12
|
|
|
return output_json(data, code, headers) |
|
13
|
|
|
|
|
14
|
|
|
|
|
15
|
|
|
class _Api(Api): |
|
16
|
|
|
def __init__(self, *args, **kwargs): |
|
17
|
|
|
super(_Api, self).__init__(*args, **kwargs) |
|
18
|
|
|
|
|
19
|
|
|
self.representations = {'application/json': _pydantic_safe_output_json} |
|
20
|
|
|
|
|
21
|
|
|
|
|
22
|
|
|
def route(flask_app: Flask): |
|
23
|
|
|
from app.views.sample.api import SampleAPI |
|
24
|
|
|
|
|
25
|
|
|
handle_exception_func = flask_app.handle_exception |
|
26
|
|
|
handle_user_exception_func = flask_app.handle_user_exception |
|
27
|
|
|
# register_blueprint 시 defer되었던 함수들이 호출되며, flask-restful.Api._init_app()이 호출되는데 |
|
28
|
|
|
# 해당 메소드가 test_app 객체의 에러 핸들러를 오버라이딩해서, 별도로 적용한 handler의 HTTPException 관련 로직이 동작하지 않음 |
|
29
|
|
|
# 따라서 두 함수를 임시 저장해 두고, register_blueprint 이후 함수를 재할당하도록 함 |
|
30
|
|
|
|
|
31
|
|
|
# - blueprint, api object initialize |
|
32
|
|
|
api_blueprint = Blueprint("api", __name__) |
|
33
|
|
|
api = _Api(api_blueprint) |
|
34
|
|
|
|
|
35
|
|
|
# - route |
|
36
|
|
|
api.add_resource(SampleAPI, "/sample") |
|
37
|
|
|
|
|
38
|
|
|
# - register blueprint |
|
39
|
|
|
flask_app.register_blueprint(api_blueprint) |
|
40
|
|
|
|
|
41
|
|
|
flask_app.handle_exception = handle_exception_func |
|
42
|
|
|
flask_app.handle_user_exception = handle_user_exception_func |
|
43
|
|
|
|