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
|
|
|
|