sanic-api 0.2.5__py3-none-any.whl → 0.2.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- example/__main__.py +19 -19
- example/api/__init__.py +1 -1
- example/api/t1/__init__.py +2 -1
- example/api/t1/{t1.py → t1_1.py} +22 -22
- example/api/t1/t1_2.py +9 -0
- example/api/t2/__init__.py +1 -1
- example/api/t2/t2.py +9 -9
- example/api/t2/t3/__init__.py +1 -1
- example/api/t2/t3/t3.py +9 -9
- example/api/user.py +89 -89
- example/api/validator.py +97 -97
- example/app.py +62 -62
- example/settings.py +10 -10
- sanic_api/__init__.py +21 -21
- sanic_api/api/__init__.py +2 -2
- sanic_api/api/api.py +177 -177
- sanic_api/api/exception.py +46 -46
- sanic_api/api/extend.py +25 -25
- sanic_api/api/handle_exception.py +61 -61
- sanic_api/api/model.py +45 -45
- sanic_api/api/validators.py +76 -76
- sanic_api/config/__init__.py +2 -2
- sanic_api/config/base.py +110 -110
- sanic_api/config/sanic.py +19 -21
- sanic_api/config/sanic_api.py +11 -13
- sanic_api/config/setting.py +30 -30
- sanic_api/enum.py +88 -88
- sanic_api/logger/__init__.py +1 -1
- sanic_api/logger/config.py +77 -77
- sanic_api/logger/extend.py +71 -71
- sanic_api/logger/sanic_http.py +68 -68
- sanic_api/openapi/__init__.py +7 -7
- sanic_api/openapi/openapi.py +102 -102
- sanic_api/utils.py +112 -97
- {sanic_api-0.2.5.dist-info → sanic_api-0.2.7.dist-info}/METADATA +4 -3
- sanic_api-0.2.7.dist-info/RECORD +39 -0
- sanic_api-0.2.7.dist-info/WHEEL +4 -0
- sanic_api-0.2.5.dist-info/RECORD +0 -38
- sanic_api-0.2.5.dist-info/WHEEL +0 -4
- {sanic_api-0.2.5.dist-info → sanic_api-0.2.7.dist-info}/licenses/LICENSE.txt +0 -0
sanic_api/__init__.py
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
from sanic import Sanic
|
2
|
-
from sanic_ext import Extend
|
3
|
-
|
4
|
-
from sanic_api import api, openapi
|
5
|
-
|
6
|
-
from .api import ApiExtend
|
7
|
-
from .logger import LoggerExtend
|
8
|
-
|
9
|
-
|
10
|
-
def init_api(app: Sanic):
|
11
|
-
"""
|
12
|
-
初始化API
|
13
|
-
Args:
|
14
|
-
app: Sanic的APP
|
15
|
-
|
16
|
-
Returns:
|
17
|
-
|
18
|
-
"""
|
19
|
-
Extend.register(LoggerExtend)
|
20
|
-
Extend.register(ApiExtend)
|
21
|
-
openapi.init(app)
|
1
|
+
from sanic import Sanic
|
2
|
+
from sanic_ext import Extend
|
3
|
+
|
4
|
+
from sanic_api import api, openapi
|
5
|
+
|
6
|
+
from .api import ApiExtend
|
7
|
+
from .logger import LoggerExtend
|
8
|
+
|
9
|
+
|
10
|
+
def init_api(app: Sanic):
|
11
|
+
"""
|
12
|
+
初始化API
|
13
|
+
Args:
|
14
|
+
app: Sanic的APP
|
15
|
+
|
16
|
+
Returns:
|
17
|
+
|
18
|
+
"""
|
19
|
+
Extend.register(LoggerExtend)
|
20
|
+
Extend.register(ApiExtend)
|
21
|
+
openapi.init(app)
|
sanic_api/api/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
from .api import API
|
2
|
-
from .extend import ApiExtend
|
1
|
+
from .api import API
|
2
|
+
from .extend import ApiExtend
|
sanic_api/api/api.py
CHANGED
@@ -1,177 +1,177 @@
|
|
1
|
-
import functools
|
2
|
-
from abc import ABCMeta
|
3
|
-
from typing import Any, Callable, Dict, Optional
|
4
|
-
|
5
|
-
from pydantic import BaseModel, Field
|
6
|
-
from pydantic import ValidationError as PyDanticValidationError
|
7
|
-
from sanic import HTTPResponse, Sanic
|
8
|
-
from sanic.response import json
|
9
|
-
|
10
|
-
from sanic_api.api.exception import ValidationError
|
11
|
-
from sanic_api.api.model import ListRespModel, ResponseModel
|
12
|
-
from sanic_api.enum import EnumBase, ParamEnum, RespCodeEnum
|
13
|
-
from sanic_api.utils import json_dumps
|
14
|
-
|
15
|
-
|
16
|
-
def get_resp_tmp(key: str, default):
|
17
|
-
"""
|
18
|
-
获取响应字段模板
|
19
|
-
"""
|
20
|
-
app = Sanic.get_app()
|
21
|
-
sanic_api: dict = app.config.get("sanic_api", {})
|
22
|
-
return sanic_api.get(key, default)
|
23
|
-
|
24
|
-
|
25
|
-
class Response:
|
26
|
-
def __init__(
|
27
|
-
self,
|
28
|
-
http_code: int = 200,
|
29
|
-
headers: Optional[Dict[str, str]] = None,
|
30
|
-
server_code: EnumBase = RespCodeEnum.SUCCESS,
|
31
|
-
message: str = "Success",
|
32
|
-
data: Any = None,
|
33
|
-
response_type: Optional[type] = None,
|
34
|
-
):
|
35
|
-
"""
|
36
|
-
初始化函数
|
37
|
-
Args:
|
38
|
-
http_code: http响应码 默认是200
|
39
|
-
headers: 自定义的响应头
|
40
|
-
server_code: 自定义的服务码
|
41
|
-
message: 返回的消息
|
42
|
-
data: 返回的数据
|
43
|
-
"""
|
44
|
-
|
45
|
-
self.http_code = http_code
|
46
|
-
self.headers = headers
|
47
|
-
self.message = message
|
48
|
-
response_type = response_type or Response.get_response_type(type(data))
|
49
|
-
|
50
|
-
if isinstance(data, ListRespModel):
|
51
|
-
data = data.to_list()
|
52
|
-
elif isinstance(data, BaseModel):
|
53
|
-
data = data.dict()
|
54
|
-
|
55
|
-
resp: ResponseModel = response_type()
|
56
|
-
code_tmp = get_resp_tmp("code_tmp", "code")
|
57
|
-
msg_tmp = get_resp_tmp("msg_tmp", "msg")
|
58
|
-
data_tmp = get_resp_tmp("data_tmp", "data")
|
59
|
-
|
60
|
-
setattr(resp, code_tmp, server_code)
|
61
|
-
setattr(resp, msg_tmp, message)
|
62
|
-
setattr(resp, data_tmp, data)
|
63
|
-
|
64
|
-
data = resp.dict()
|
65
|
-
|
66
|
-
self.data = data
|
67
|
-
|
68
|
-
def json_resp(self, default: Optional[Callable[[Any], Any]] = None) -> HTTPResponse:
|
69
|
-
"""
|
70
|
-
返回json格式的响应
|
71
|
-
Args:
|
72
|
-
|
73
|
-
"""
|
74
|
-
return json(
|
75
|
-
body=self.data,
|
76
|
-
status=self.http_code,
|
77
|
-
headers=self.headers,
|
78
|
-
dumps=functools.partial(json_dumps, default=default),
|
79
|
-
)
|
80
|
-
|
81
|
-
@classmethod
|
82
|
-
def get_response_type(cls, data_type: type):
|
83
|
-
"""
|
84
|
-
获取响应的类型
|
85
|
-
Args:
|
86
|
-
data_type: 响应中data的类型
|
87
|
-
|
88
|
-
Returns:
|
89
|
-
|
90
|
-
"""
|
91
|
-
code_tmp = get_resp_tmp("code_tmp", "code")
|
92
|
-
msg_tmp = get_resp_tmp("msg_tmp", "msg")
|
93
|
-
data_tmp = get_resp_tmp("data_tmp", "data")
|
94
|
-
|
95
|
-
attr_dict = {
|
96
|
-
code_tmp: Field(title="业务响应码"),
|
97
|
-
msg_tmp: Field(title="响应消息"),
|
98
|
-
data_tmp: Field(title="响应数据"),
|
99
|
-
"__annotations__": {code_tmp: int, msg_tmp: str, data_tmp: data_type},
|
100
|
-
}
|
101
|
-
resp_name = data_type.__name__ if data_type.__name__ != "NoneType" else "Response"
|
102
|
-
response_type = type(resp_name, (ResponseModel,), attr_dict)
|
103
|
-
return response_type
|
104
|
-
|
105
|
-
@staticmethod
|
106
|
-
def _get_tmp(key: str, default):
|
107
|
-
"""
|
108
|
-
获取字段模板
|
109
|
-
"""
|
110
|
-
app = Sanic.get_app()
|
111
|
-
sanic_api: dict = app.config.get("sanic_api", {})
|
112
|
-
return sanic_api.get(key, default)
|
113
|
-
|
114
|
-
|
115
|
-
class API(metaclass=ABCMeta):
|
116
|
-
json_req: Optional[BaseModel] = None
|
117
|
-
form_req: Optional[BaseModel] = None
|
118
|
-
query_req: Optional[BaseModel] = None
|
119
|
-
resp: Optional[Any] = None
|
120
|
-
tags: list = []
|
121
|
-
description: str = ""
|
122
|
-
|
123
|
-
def __init__(self):
|
124
|
-
response_type = self.__class__.__annotations__.get("resp")
|
125
|
-
self.json_req_type = self.__class__.__annotations__.get("json_req")
|
126
|
-
self.form_req_type = self.__class__.__annotations__.get("form_req")
|
127
|
-
self.query_req_type = self.__class__.__annotations__.get("query_req")
|
128
|
-
self.response_type = Response.get_response_type(response_type)
|
129
|
-
self.resp = response_type()
|
130
|
-
|
131
|
-
def validate_params(self, req_data: dict, param_enum: ParamEnum):
|
132
|
-
"""
|
133
|
-
验证参数,参数有问题抛出异常
|
134
|
-
Args:
|
135
|
-
req_data: 数据
|
136
|
-
param_enum: 参数类型
|
137
|
-
|
138
|
-
Returns:
|
139
|
-
|
140
|
-
"""
|
141
|
-
try:
|
142
|
-
if param_enum == ParamEnum.JSON:
|
143
|
-
self.json_req = self.json_req_type(**req_data)
|
144
|
-
elif param_enum == ParamEnum.QUERY:
|
145
|
-
self.query_req = self.query_req_type(**req_data)
|
146
|
-
elif param_enum == ParamEnum.FORM:
|
147
|
-
self.form_req = self.form_req_type(**req_data)
|
148
|
-
except PyDanticValidationError as e:
|
149
|
-
raise ValidationError(e.errors()) from e
|
150
|
-
|
151
|
-
def json_resp(
|
152
|
-
self,
|
153
|
-
http_code: int = 200,
|
154
|
-
headers: Optional[Dict[str, str]] = None,
|
155
|
-
server_code: RespCodeEnum = RespCodeEnum.SUCCESS,
|
156
|
-
message: str = "Success",
|
157
|
-
):
|
158
|
-
"""
|
159
|
-
根据响应数据返回json格式的响应
|
160
|
-
Args:
|
161
|
-
http_code: http协议响应码
|
162
|
-
headers: 响应头
|
163
|
-
server_code: 应用协议响应码
|
164
|
-
message: 响应消息
|
165
|
-
|
166
|
-
Returns:
|
167
|
-
返回一个sanic的HTTPResponse
|
168
|
-
"""
|
169
|
-
|
170
|
-
return Response(
|
171
|
-
data=self.resp,
|
172
|
-
http_code=http_code,
|
173
|
-
headers=headers,
|
174
|
-
server_code=server_code,
|
175
|
-
message=message,
|
176
|
-
response_type=self.response_type,
|
177
|
-
).json_resp()
|
1
|
+
import functools
|
2
|
+
from abc import ABCMeta
|
3
|
+
from typing import Any, Callable, Dict, Optional
|
4
|
+
|
5
|
+
from pydantic import BaseModel, Field
|
6
|
+
from pydantic import ValidationError as PyDanticValidationError
|
7
|
+
from sanic import HTTPResponse, Sanic
|
8
|
+
from sanic.response import json
|
9
|
+
|
10
|
+
from sanic_api.api.exception import ValidationError
|
11
|
+
from sanic_api.api.model import ListRespModel, ResponseModel
|
12
|
+
from sanic_api.enum import EnumBase, ParamEnum, RespCodeEnum
|
13
|
+
from sanic_api.utils import json_dumps
|
14
|
+
|
15
|
+
|
16
|
+
def get_resp_tmp(key: str, default):
|
17
|
+
"""
|
18
|
+
获取响应字段模板
|
19
|
+
"""
|
20
|
+
app = Sanic.get_app()
|
21
|
+
sanic_api: dict = app.config.get("sanic_api", {})
|
22
|
+
return sanic_api.get(key, default)
|
23
|
+
|
24
|
+
|
25
|
+
class Response:
|
26
|
+
def __init__(
|
27
|
+
self,
|
28
|
+
http_code: int = 200,
|
29
|
+
headers: Optional[Dict[str, str]] = None,
|
30
|
+
server_code: EnumBase = RespCodeEnum.SUCCESS,
|
31
|
+
message: str = "Success",
|
32
|
+
data: Any = None,
|
33
|
+
response_type: Optional[type] = None,
|
34
|
+
):
|
35
|
+
"""
|
36
|
+
初始化函数
|
37
|
+
Args:
|
38
|
+
http_code: http响应码 默认是200
|
39
|
+
headers: 自定义的响应头
|
40
|
+
server_code: 自定义的服务码
|
41
|
+
message: 返回的消息
|
42
|
+
data: 返回的数据
|
43
|
+
"""
|
44
|
+
|
45
|
+
self.http_code = http_code
|
46
|
+
self.headers = headers
|
47
|
+
self.message = message
|
48
|
+
response_type = response_type or Response.get_response_type(type(data))
|
49
|
+
|
50
|
+
if isinstance(data, ListRespModel):
|
51
|
+
data = data.to_list()
|
52
|
+
elif isinstance(data, BaseModel):
|
53
|
+
data = data.dict()
|
54
|
+
|
55
|
+
resp: ResponseModel = response_type()
|
56
|
+
code_tmp = get_resp_tmp("code_tmp", "code")
|
57
|
+
msg_tmp = get_resp_tmp("msg_tmp", "msg")
|
58
|
+
data_tmp = get_resp_tmp("data_tmp", "data")
|
59
|
+
|
60
|
+
setattr(resp, code_tmp, server_code)
|
61
|
+
setattr(resp, msg_tmp, message)
|
62
|
+
setattr(resp, data_tmp, data)
|
63
|
+
|
64
|
+
data = resp.dict()
|
65
|
+
|
66
|
+
self.data = data
|
67
|
+
|
68
|
+
def json_resp(self, default: Optional[Callable[[Any], Any]] = None) -> HTTPResponse:
|
69
|
+
"""
|
70
|
+
返回json格式的响应
|
71
|
+
Args:
|
72
|
+
|
73
|
+
"""
|
74
|
+
return json(
|
75
|
+
body=self.data,
|
76
|
+
status=self.http_code,
|
77
|
+
headers=self.headers,
|
78
|
+
dumps=functools.partial(json_dumps, default=default),
|
79
|
+
)
|
80
|
+
|
81
|
+
@classmethod
|
82
|
+
def get_response_type(cls, data_type: type):
|
83
|
+
"""
|
84
|
+
获取响应的类型
|
85
|
+
Args:
|
86
|
+
data_type: 响应中data的类型
|
87
|
+
|
88
|
+
Returns:
|
89
|
+
|
90
|
+
"""
|
91
|
+
code_tmp = get_resp_tmp("code_tmp", "code")
|
92
|
+
msg_tmp = get_resp_tmp("msg_tmp", "msg")
|
93
|
+
data_tmp = get_resp_tmp("data_tmp", "data")
|
94
|
+
|
95
|
+
attr_dict = {
|
96
|
+
code_tmp: Field(title="业务响应码"),
|
97
|
+
msg_tmp: Field(title="响应消息"),
|
98
|
+
data_tmp: Field(title="响应数据"),
|
99
|
+
"__annotations__": {code_tmp: int, msg_tmp: str, data_tmp: data_type},
|
100
|
+
}
|
101
|
+
resp_name = data_type.__name__ if data_type.__name__ != "NoneType" else "Response"
|
102
|
+
response_type = type(resp_name, (ResponseModel,), attr_dict)
|
103
|
+
return response_type
|
104
|
+
|
105
|
+
@staticmethod
|
106
|
+
def _get_tmp(key: str, default):
|
107
|
+
"""
|
108
|
+
获取字段模板
|
109
|
+
"""
|
110
|
+
app = Sanic.get_app()
|
111
|
+
sanic_api: dict = app.config.get("sanic_api", {})
|
112
|
+
return sanic_api.get(key, default)
|
113
|
+
|
114
|
+
|
115
|
+
class API(metaclass=ABCMeta):
|
116
|
+
json_req: Optional[BaseModel] = None
|
117
|
+
form_req: Optional[BaseModel] = None
|
118
|
+
query_req: Optional[BaseModel] = None
|
119
|
+
resp: Optional[Any] = None
|
120
|
+
tags: list = []
|
121
|
+
description: str = ""
|
122
|
+
|
123
|
+
def __init__(self):
|
124
|
+
response_type = self.__class__.__annotations__.get("resp")
|
125
|
+
self.json_req_type = self.__class__.__annotations__.get("json_req")
|
126
|
+
self.form_req_type = self.__class__.__annotations__.get("form_req")
|
127
|
+
self.query_req_type = self.__class__.__annotations__.get("query_req")
|
128
|
+
self.response_type = Response.get_response_type(response_type)
|
129
|
+
self.resp = response_type()
|
130
|
+
|
131
|
+
def validate_params(self, req_data: dict, param_enum: ParamEnum):
|
132
|
+
"""
|
133
|
+
验证参数,参数有问题抛出异常
|
134
|
+
Args:
|
135
|
+
req_data: 数据
|
136
|
+
param_enum: 参数类型
|
137
|
+
|
138
|
+
Returns:
|
139
|
+
|
140
|
+
"""
|
141
|
+
try:
|
142
|
+
if param_enum == ParamEnum.JSON:
|
143
|
+
self.json_req = self.json_req_type(**req_data)
|
144
|
+
elif param_enum == ParamEnum.QUERY:
|
145
|
+
self.query_req = self.query_req_type(**req_data)
|
146
|
+
elif param_enum == ParamEnum.FORM:
|
147
|
+
self.form_req = self.form_req_type(**req_data)
|
148
|
+
except PyDanticValidationError as e:
|
149
|
+
raise ValidationError(e.errors()) from e
|
150
|
+
|
151
|
+
def json_resp(
|
152
|
+
self,
|
153
|
+
http_code: int = 200,
|
154
|
+
headers: Optional[Dict[str, str]] = None,
|
155
|
+
server_code: RespCodeEnum = RespCodeEnum.SUCCESS,
|
156
|
+
message: str = "Success",
|
157
|
+
):
|
158
|
+
"""
|
159
|
+
根据响应数据返回json格式的响应
|
160
|
+
Args:
|
161
|
+
http_code: http协议响应码
|
162
|
+
headers: 响应头
|
163
|
+
server_code: 应用协议响应码
|
164
|
+
message: 响应消息
|
165
|
+
|
166
|
+
Returns:
|
167
|
+
返回一个sanic的HTTPResponse
|
168
|
+
"""
|
169
|
+
|
170
|
+
return Response(
|
171
|
+
data=self.resp,
|
172
|
+
http_code=http_code,
|
173
|
+
headers=headers,
|
174
|
+
server_code=server_code,
|
175
|
+
message=message,
|
176
|
+
response_type=self.response_type,
|
177
|
+
).json_resp()
|
sanic_api/api/exception.py
CHANGED
@@ -1,46 +1,46 @@
|
|
1
|
-
from typing import Any, Optional
|
2
|
-
|
3
|
-
from sanic.exceptions import SanicException
|
4
|
-
|
5
|
-
from sanic_api.enum import EnumBase, RespCodeEnum
|
6
|
-
from sanic_api.utils import get_current_request
|
7
|
-
|
8
|
-
|
9
|
-
class ServerException(SanicException):
|
10
|
-
def __init__(
|
11
|
-
self,
|
12
|
-
message: Optional[str] = None,
|
13
|
-
status_code: Optional[int] = None,
|
14
|
-
server_code: Optional[EnumBase] = None,
|
15
|
-
quiet: Optional[bool] = None,
|
16
|
-
context: Any = None,
|
17
|
-
extra=None,
|
18
|
-
):
|
19
|
-
super().__init__(
|
20
|
-
message=message,
|
21
|
-
status_code=status_code,
|
22
|
-
quiet=quiet,
|
23
|
-
context=context,
|
24
|
-
extra=extra,
|
25
|
-
)
|
26
|
-
self.server_code = server_code or RespCodeEnum.FAILED
|
27
|
-
self.message = message or self.server_code.desc
|
28
|
-
self.status_code = status_code or 200
|
29
|
-
req = get_current_request()
|
30
|
-
if req:
|
31
|
-
req.ctx.exception = self
|
32
|
-
|
33
|
-
|
34
|
-
class ValidationInitError(ServerException):
|
35
|
-
"""
|
36
|
-
验证器初始化失败
|
37
|
-
"""
|
38
|
-
|
39
|
-
|
40
|
-
class ValidationError(ServerException):
|
41
|
-
"""
|
42
|
-
参数验证失败
|
43
|
-
"""
|
44
|
-
|
45
|
-
def __init__(self, errors: list, *args, **kwargs):
|
46
|
-
super().__init__(server_code=RespCodeEnum.PARAM_FAILED, context=errors)
|
1
|
+
from typing import Any, Optional
|
2
|
+
|
3
|
+
from sanic.exceptions import SanicException
|
4
|
+
|
5
|
+
from sanic_api.enum import EnumBase, RespCodeEnum
|
6
|
+
from sanic_api.utils import get_current_request
|
7
|
+
|
8
|
+
|
9
|
+
class ServerException(SanicException):
|
10
|
+
def __init__(
|
11
|
+
self,
|
12
|
+
message: Optional[str] = None,
|
13
|
+
status_code: Optional[int] = None,
|
14
|
+
server_code: Optional[EnumBase] = None,
|
15
|
+
quiet: Optional[bool] = None,
|
16
|
+
context: Any = None,
|
17
|
+
extra=None,
|
18
|
+
):
|
19
|
+
super().__init__(
|
20
|
+
message=message,
|
21
|
+
status_code=status_code,
|
22
|
+
quiet=quiet,
|
23
|
+
context=context,
|
24
|
+
extra=extra,
|
25
|
+
)
|
26
|
+
self.server_code = server_code or RespCodeEnum.FAILED
|
27
|
+
self.message = message or self.server_code.desc
|
28
|
+
self.status_code = status_code or 200
|
29
|
+
req = get_current_request()
|
30
|
+
if req:
|
31
|
+
req.ctx.exception = self
|
32
|
+
|
33
|
+
|
34
|
+
class ValidationInitError(ServerException):
|
35
|
+
"""
|
36
|
+
验证器初始化失败
|
37
|
+
"""
|
38
|
+
|
39
|
+
|
40
|
+
class ValidationError(ServerException):
|
41
|
+
"""
|
42
|
+
参数验证失败
|
43
|
+
"""
|
44
|
+
|
45
|
+
def __init__(self, errors: list, *args, **kwargs):
|
46
|
+
super().__init__(server_code=RespCodeEnum.PARAM_FAILED, context=errors)
|
sanic_api/api/extend.py
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
from sanic.exceptions import NotFound
|
2
|
-
from sanic_ext import Extension
|
3
|
-
|
4
|
-
from sanic_api.api.exception import ServerException
|
5
|
-
|
6
|
-
from .handle_exception import not_found, other_exception, server_exception
|
7
|
-
from .validators import validators
|
8
|
-
|
9
|
-
|
10
|
-
class ApiExtend(Extension):
|
11
|
-
"""
|
12
|
-
接口处理扩展
|
13
|
-
参数校验、异常拦截等功能
|
14
|
-
"""
|
15
|
-
|
16
|
-
name = "ApiExtend"
|
17
|
-
|
18
|
-
def startup(self, bootstrap) -> None:
|
19
|
-
if not self.included():
|
20
|
-
return
|
21
|
-
|
22
|
-
self.app.error_handler.add(ServerException, server_exception)
|
23
|
-
self.app.error_handler.add(Exception, other_exception)
|
24
|
-
self.app.error_handler.add(NotFound, not_found)
|
25
|
-
self.app.on_request(validators, priority=998)
|
1
|
+
from sanic.exceptions import NotFound
|
2
|
+
from sanic_ext import Extension
|
3
|
+
|
4
|
+
from sanic_api.api.exception import ServerException
|
5
|
+
|
6
|
+
from .handle_exception import not_found, other_exception, server_exception
|
7
|
+
from .validators import validators
|
8
|
+
|
9
|
+
|
10
|
+
class ApiExtend(Extension):
|
11
|
+
"""
|
12
|
+
接口处理扩展
|
13
|
+
参数校验、异常拦截等功能
|
14
|
+
"""
|
15
|
+
|
16
|
+
name = "ApiExtend"
|
17
|
+
|
18
|
+
def startup(self, bootstrap) -> None:
|
19
|
+
if not self.included():
|
20
|
+
return
|
21
|
+
|
22
|
+
self.app.error_handler.add(ServerException, server_exception)
|
23
|
+
self.app.error_handler.add(Exception, other_exception)
|
24
|
+
self.app.error_handler.add(NotFound, not_found)
|
25
|
+
self.app.on_request(validators, priority=998)
|
@@ -1,61 +1,61 @@
|
|
1
|
-
from sanic import Request
|
2
|
-
from sanic.log import logger
|
3
|
-
|
4
|
-
from sanic_api.api.api import Response
|
5
|
-
from sanic_api.api.exception import ServerException
|
6
|
-
from sanic_api.enum import RespCodeEnum
|
7
|
-
|
8
|
-
|
9
|
-
def server_exception(request: Request, e: ServerException):
|
10
|
-
"""
|
11
|
-
处理业务异常
|
12
|
-
Args:
|
13
|
-
request: 请求
|
14
|
-
e: 异常信息
|
15
|
-
|
16
|
-
Returns:
|
17
|
-
返回处理异常后的响应
|
18
|
-
"""
|
19
|
-
|
20
|
-
return Response(
|
21
|
-
http_code=e.status_code,
|
22
|
-
server_code=e.server_code,
|
23
|
-
message=e.message,
|
24
|
-
data=e.context,
|
25
|
-
).json_resp()
|
26
|
-
|
27
|
-
|
28
|
-
def not_found(request: Request, e):
|
29
|
-
"""
|
30
|
-
处理 NotFound 异常
|
31
|
-
Args:
|
32
|
-
request: 请求信息
|
33
|
-
e: 异常信息
|
34
|
-
|
35
|
-
Returns:
|
36
|
-
|
37
|
-
"""
|
38
|
-
if "/favicon.ico" == request.path:
|
39
|
-
return
|
40
|
-
|
41
|
-
logger.warning(f"找不到路由:{request.path}")
|
42
|
-
|
43
|
-
|
44
|
-
def other_exception(request: Request, e):
|
45
|
-
"""
|
46
|
-
处理其他异常
|
47
|
-
Args:
|
48
|
-
request:
|
49
|
-
e:
|
50
|
-
|
51
|
-
Returns:
|
52
|
-
|
53
|
-
"""
|
54
|
-
logger.exception(e)
|
55
|
-
|
56
|
-
error_name = e.__class__.__name__
|
57
|
-
return Response(
|
58
|
-
http_code=500,
|
59
|
-
server_code=RespCodeEnum.FAILED,
|
60
|
-
message=f"服务端业务发生未知异常:[{error_name}] {e}",
|
61
|
-
).json_resp()
|
1
|
+
from sanic import Request
|
2
|
+
from sanic.log import logger
|
3
|
+
|
4
|
+
from sanic_api.api.api import Response
|
5
|
+
from sanic_api.api.exception import ServerException
|
6
|
+
from sanic_api.enum import RespCodeEnum
|
7
|
+
|
8
|
+
|
9
|
+
def server_exception(request: Request, e: ServerException):
|
10
|
+
"""
|
11
|
+
处理业务异常
|
12
|
+
Args:
|
13
|
+
request: 请求
|
14
|
+
e: 异常信息
|
15
|
+
|
16
|
+
Returns:
|
17
|
+
返回处理异常后的响应
|
18
|
+
"""
|
19
|
+
|
20
|
+
return Response(
|
21
|
+
http_code=e.status_code,
|
22
|
+
server_code=e.server_code,
|
23
|
+
message=e.message,
|
24
|
+
data=e.context,
|
25
|
+
).json_resp()
|
26
|
+
|
27
|
+
|
28
|
+
def not_found(request: Request, e):
|
29
|
+
"""
|
30
|
+
处理 NotFound 异常
|
31
|
+
Args:
|
32
|
+
request: 请求信息
|
33
|
+
e: 异常信息
|
34
|
+
|
35
|
+
Returns:
|
36
|
+
|
37
|
+
"""
|
38
|
+
if "/favicon.ico" == request.path:
|
39
|
+
return
|
40
|
+
|
41
|
+
logger.warning(f"找不到路由:{request.path}")
|
42
|
+
|
43
|
+
|
44
|
+
def other_exception(request: Request, e):
|
45
|
+
"""
|
46
|
+
处理其他异常
|
47
|
+
Args:
|
48
|
+
request:
|
49
|
+
e:
|
50
|
+
|
51
|
+
Returns:
|
52
|
+
|
53
|
+
"""
|
54
|
+
logger.exception(e)
|
55
|
+
|
56
|
+
error_name = e.__class__.__name__
|
57
|
+
return Response(
|
58
|
+
http_code=500,
|
59
|
+
server_code=RespCodeEnum.FAILED,
|
60
|
+
message=f"服务端业务发生未知异常:[{error_name}] {e}",
|
61
|
+
).json_resp()
|