sanic-api 0.2.5__tar.gz → 0.2.7__tar.gz
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.
- {sanic-api-0.2.5 → sanic-api-0.2.7}/PKG-INFO +1 -1
- {sanic-api-0.2.5 → sanic-api-0.2.7}/README.MD +79 -79
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/__main__.py +19 -19
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/api/__init__.py +1 -1
- sanic-api-0.2.7/example/api/t1/__init__.py +2 -0
- sanic-api-0.2.5/example/api/t1/t1.py → sanic-api-0.2.7/example/api/t1/t1_1.py +22 -22
- sanic-api-0.2.7/example/api/t1/t1_2.py +9 -0
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/api/t2/__init__.py +1 -1
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/api/t2/t2.py +9 -9
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/api/t2/t3/__init__.py +1 -1
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/api/t2/t3/t3.py +9 -9
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/api/user.py +89 -89
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/api/validator.py +97 -97
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/app.py +62 -62
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/settings.py +10 -10
- {sanic-api-0.2.5 → sanic-api-0.2.7}/pyproject.toml +4 -3
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/__init__.py +21 -21
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/api/__init__.py +2 -2
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/api/api.py +177 -177
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/api/exception.py +46 -46
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/api/extend.py +25 -25
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/api/handle_exception.py +61 -61
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/api/model.py +45 -45
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/api/validators.py +76 -76
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/config/__init__.py +2 -2
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/config/base.py +110 -110
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/config/sanic.py +19 -21
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/config/sanic_api.py +11 -13
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/config/setting.py +30 -30
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/enum.py +88 -88
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/logger/__init__.py +1 -1
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/logger/config.py +77 -77
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/logger/extend.py +71 -71
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/logger/sanic_http.py +68 -68
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/openapi/__init__.py +7 -7
- {sanic-api-0.2.5 → sanic-api-0.2.7}/sanic_api/openapi/openapi.py +102 -102
- sanic-api-0.2.7/sanic_api/utils.py +112 -0
- sanic-api-0.2.5/example/api/t1/__init__.py +0 -1
- sanic-api-0.2.5/sanic_api/utils.py +0 -97
- {sanic-api-0.2.5 → sanic-api-0.2.7}/LICENSE.txt +0 -0
- {sanic-api-0.2.5 → sanic-api-0.2.7}/example/__init__.py +0 -0
@@ -1,79 +1,79 @@
|
|
1
|
-

|
2
|
-
|
3
|
-
[](https://choosealicense.com/licenses/mit/)
|
4
|
-
[]()
|
5
|
-
[](http://www.gnu.org/licenses/agpl-3.0)
|
6
|
-
[](https://github.com/psf/black)
|
7
|
-
|
8
|
-
# Sanic-API
|
9
|
-
|
10
|
-
让您的sanic服务程序更好的支持API文档、参数校验、日志打印、响应规范等
|
11
|
-
|
12
|
-
## 特性
|
13
|
-
|
14
|
-
- 无需任何多余改动,全自动生成openapi文档,使用更加方便
|
15
|
-
|
16
|
-
- 基于`pydantic`的参数校验器,让接口的请求及响应更符合你的预期
|
17
|
-
|
18
|
-
- 使用`loguru`库代替官方`logging`日志库,并对访问日志进行扩展,支持打印接口耗时、接口参数
|
19
|
-
|
20
|
-
- 使用`{code: 0, data: null, msg: ""}`样式的接口返回
|
21
|
-
|
22
|
-
- 对接口中的异常进行拦截,及自定义错误码
|
23
|
-
|
24
|
-
- 接口返回样式可自定义配置
|
25
|
-
|
26
|
-
## 截图
|
27
|
-
|
28
|
-
## 路线图
|
29
|
-
|
30
|
-
- 增加一键生成预设项目cli命令
|
31
|
-
|
32
|
-
- 编写详细文档
|
33
|
-
|
34
|
-
- API接口增加请求头、URL路径参数收集和校验:
|
35
|
-
|
36
|
-
## 安装
|
37
|
-
|
38
|
-
使用 pip 安装 sanic-api
|
39
|
-
|
40
|
-
```bash
|
41
|
-
pip install sanic-api
|
42
|
-
```
|
43
|
-
|
44
|
-
## 使用方法/示例
|
45
|
-
|
46
|
-
```python
|
47
|
-
from sanic import Sanic, text
|
48
|
-
from sanic_api import init_api
|
49
|
-
|
50
|
-
app = Sanic("Sanic-API")
|
51
|
-
|
52
|
-
|
53
|
-
@app.get('/')
|
54
|
-
async def index(request):
|
55
|
-
return text("Sanic-API Example")
|
56
|
-
|
57
|
-
|
58
|
-
def main():
|
59
|
-
init_api(app)
|
60
|
-
app.run(access_log=True)
|
61
|
-
|
62
|
-
|
63
|
-
if __name__ == '__main__':
|
64
|
-
main()
|
65
|
-
|
66
|
-
```
|
67
|
-
|
68
|
-
## 开发
|
69
|
-
|
70
|
-
要部署这个项目,请运行
|
71
|
-
|
72
|
-
```bash
|
73
|
-
pip install pdm
|
74
|
-
pdm sync
|
75
|
-
```
|
76
|
-
|
77
|
-
## 文档
|
78
|
-
|
79
|
-
[文档](https://linktodocumentation)
|
1
|
+

|
2
|
+
|
3
|
+
[](https://choosealicense.com/licenses/mit/)
|
4
|
+
[]()
|
5
|
+
[](http://www.gnu.org/licenses/agpl-3.0)
|
6
|
+
[](https://github.com/psf/black)
|
7
|
+
|
8
|
+
# Sanic-API
|
9
|
+
|
10
|
+
让您的sanic服务程序更好的支持API文档、参数校验、日志打印、响应规范等
|
11
|
+
|
12
|
+
## 特性
|
13
|
+
|
14
|
+
- 无需任何多余改动,全自动生成openapi文档,使用更加方便
|
15
|
+
|
16
|
+
- 基于`pydantic`的参数校验器,让接口的请求及响应更符合你的预期
|
17
|
+
|
18
|
+
- 使用`loguru`库代替官方`logging`日志库,并对访问日志进行扩展,支持打印接口耗时、接口参数
|
19
|
+
|
20
|
+
- 使用`{code: 0, data: null, msg: ""}`样式的接口返回
|
21
|
+
|
22
|
+
- 对接口中的异常进行拦截,及自定义错误码
|
23
|
+
|
24
|
+
- 接口返回样式可自定义配置
|
25
|
+
|
26
|
+
## 截图
|
27
|
+
|
28
|
+
## 路线图
|
29
|
+
|
30
|
+
- 增加一键生成预设项目cli命令
|
31
|
+
|
32
|
+
- 编写详细文档
|
33
|
+
|
34
|
+
- API接口增加请求头、URL路径参数收集和校验:
|
35
|
+
|
36
|
+
## 安装
|
37
|
+
|
38
|
+
使用 pip 安装 sanic-api
|
39
|
+
|
40
|
+
```bash
|
41
|
+
pip install sanic-api
|
42
|
+
```
|
43
|
+
|
44
|
+
## 使用方法/示例
|
45
|
+
|
46
|
+
```python
|
47
|
+
from sanic import Sanic, text
|
48
|
+
from sanic_api import init_api
|
49
|
+
|
50
|
+
app = Sanic("Sanic-API")
|
51
|
+
|
52
|
+
|
53
|
+
@app.get('/')
|
54
|
+
async def index(request):
|
55
|
+
return text("Sanic-API Example")
|
56
|
+
|
57
|
+
|
58
|
+
def main():
|
59
|
+
init_api(app)
|
60
|
+
app.run(access_log=True)
|
61
|
+
|
62
|
+
|
63
|
+
if __name__ == '__main__':
|
64
|
+
main()
|
65
|
+
|
66
|
+
```
|
67
|
+
|
68
|
+
## 开发
|
69
|
+
|
70
|
+
要部署这个项目,请运行
|
71
|
+
|
72
|
+
```bash
|
73
|
+
pip install pdm
|
74
|
+
pdm sync
|
75
|
+
```
|
76
|
+
|
77
|
+
## 文档
|
78
|
+
|
79
|
+
[文档](https://linktodocumentation)
|
@@ -1,19 +1,19 @@
|
|
1
|
-
from sanic import Sanic
|
2
|
-
from sanic.worker.loader import AppLoader
|
3
|
-
|
4
|
-
from example.app import app_factory
|
5
|
-
from example.settings import settings
|
6
|
-
from sanic_api.enum import RunModeEnum
|
7
|
-
|
8
|
-
if __name__ == "__main__":
|
9
|
-
loader = AppLoader(factory=app_factory)
|
10
|
-
app = loader.load()
|
11
|
-
app.prepare(
|
12
|
-
host=settings.host,
|
13
|
-
port=settings.port,
|
14
|
-
debug=settings.mode == RunModeEnum.DEBUG,
|
15
|
-
dev=settings.mode == RunModeEnum.DEV,
|
16
|
-
workers=settings.workers,
|
17
|
-
fast=settings.mode == RunModeEnum.PRODUCTION and settings.workers == 1,
|
18
|
-
)
|
19
|
-
Sanic.serve(app, app_loader=loader)
|
1
|
+
from sanic import Sanic
|
2
|
+
from sanic.worker.loader import AppLoader
|
3
|
+
|
4
|
+
from example.app import app_factory
|
5
|
+
from example.settings import settings
|
6
|
+
from sanic_api.enum import RunModeEnum
|
7
|
+
|
8
|
+
if __name__ == "__main__":
|
9
|
+
loader = AppLoader(factory=app_factory)
|
10
|
+
app = loader.load()
|
11
|
+
app.prepare(
|
12
|
+
host=settings.host,
|
13
|
+
port=settings.port,
|
14
|
+
debug=settings.mode == RunModeEnum.DEBUG,
|
15
|
+
dev=settings.mode == RunModeEnum.DEV,
|
16
|
+
workers=settings.workers,
|
17
|
+
fast=settings.mode == RunModeEnum.PRODUCTION and settings.workers == 1,
|
18
|
+
)
|
19
|
+
Sanic.serve(app, app_loader=loader)
|
@@ -1 +1 @@
|
|
1
|
-
from .user import users_blueprint
|
1
|
+
from .user import users_blueprint
|
@@ -1,22 +1,22 @@
|
|
1
|
-
from sanic import Blueprint, Request, text
|
2
|
-
|
3
|
-
from sanic_api.api.exception import ServerException
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@
|
10
|
-
async def hello(request):
|
11
|
-
return text("Hello world!")
|
12
|
-
|
13
|
-
|
14
|
-
@
|
15
|
-
async def error(request):
|
16
|
-
raise ServerException(message="Error")
|
17
|
-
|
18
|
-
|
19
|
-
@
|
20
|
-
async def restart(request: Request):
|
21
|
-
request.app.m.restart(all_workers=True, zero_downtime=True)
|
22
|
-
return text("ok")
|
1
|
+
from sanic import Blueprint, Request, text
|
2
|
+
|
3
|
+
from sanic_api.api.exception import ServerException
|
4
|
+
|
5
|
+
t1_1_blueprint = Blueprint("t1_1_blueprint", url_prefix="/t1_1")
|
6
|
+
t1_1_blueprint.ctx.desc = "测试蓝图1_1"
|
7
|
+
|
8
|
+
|
9
|
+
@t1_1_blueprint.route("/test", methods=["GET", "POST"])
|
10
|
+
async def hello(request):
|
11
|
+
return text("Hello world!")
|
12
|
+
|
13
|
+
|
14
|
+
@t1_1_blueprint.route("/error", methods=["GET", "POST"])
|
15
|
+
async def error(request):
|
16
|
+
raise ServerException(message="Error")
|
17
|
+
|
18
|
+
|
19
|
+
@t1_1_blueprint.route("/restart", methods=["GET", "POST"])
|
20
|
+
async def restart(request: Request):
|
21
|
+
request.app.m.restart(all_workers=True, zero_downtime=True)
|
22
|
+
return text("ok")
|
@@ -1 +1 @@
|
|
1
|
-
from .t2 import t2_blueprint
|
1
|
+
from .t2 import t2_blueprint
|
@@ -1,9 +1,9 @@
|
|
1
|
-
from sanic import Blueprint, text
|
2
|
-
|
3
|
-
t2_blueprint = Blueprint("t2_blueprint", url_prefix="/t2")
|
4
|
-
t2_blueprint.ctx.desc = "测试蓝图2"
|
5
|
-
|
6
|
-
|
7
|
-
@t2_blueprint.route("/test", methods=["GET", "POST"])
|
8
|
-
async def hello(request):
|
9
|
-
return text("Hello world!")
|
1
|
+
from sanic import Blueprint, text
|
2
|
+
|
3
|
+
t2_blueprint = Blueprint("t2_blueprint", url_prefix="/t2")
|
4
|
+
t2_blueprint.ctx.desc = "测试蓝图2"
|
5
|
+
|
6
|
+
|
7
|
+
@t2_blueprint.route("/test", methods=["GET", "POST"])
|
8
|
+
async def hello(request):
|
9
|
+
return text("Hello world!")
|
@@ -1 +1 @@
|
|
1
|
-
from .t3 import t3_blueprint
|
1
|
+
from .t3 import t3_blueprint
|
@@ -1,9 +1,9 @@
|
|
1
|
-
from sanic import Blueprint, text
|
2
|
-
|
3
|
-
t3_blueprint = Blueprint("t3_blueprint", url_prefix="/t3")
|
4
|
-
t3_blueprint.ctx.desc = "测试蓝图3"
|
5
|
-
|
6
|
-
|
7
|
-
@t3_blueprint.route("/test", methods=["GET", "POST"])
|
8
|
-
async def hello(request):
|
9
|
-
return text("Hello world!")
|
1
|
+
from sanic import Blueprint, text
|
2
|
+
|
3
|
+
t3_blueprint = Blueprint("t3_blueprint", url_prefix="/t3")
|
4
|
+
t3_blueprint.ctx.desc = "测试蓝图3"
|
5
|
+
|
6
|
+
|
7
|
+
@t3_blueprint.route("/test", methods=["GET", "POST"])
|
8
|
+
async def hello(request):
|
9
|
+
return text("Hello world!")
|
@@ -1,89 +1,89 @@
|
|
1
|
-
from typing import Any, Dict, List
|
2
|
-
from uuid import uuid4
|
3
|
-
|
4
|
-
from sanic import Blueprint, text
|
5
|
-
from sanic.request import Request
|
6
|
-
|
7
|
-
from .validator import (
|
8
|
-
UserAddApi,
|
9
|
-
UserDelApi,
|
10
|
-
UserFindOneApi,
|
11
|
-
UserListApi,
|
12
|
-
UserUpdateApi,
|
13
|
-
)
|
14
|
-
|
15
|
-
users_blueprint = Blueprint("users_blueprint", url_prefix="/users")
|
16
|
-
users_blueprint.ctx.desc = "用户"
|
17
|
-
|
18
|
-
|
19
|
-
@users_blueprint.route("/test", methods=["GET"])
|
20
|
-
async def hello(request):
|
21
|
-
return text("Hello world!")
|
22
|
-
|
23
|
-
|
24
|
-
@users_blueprint.route("/", methods=["POST"])
|
25
|
-
async def user_add(request: Request, api: UserAddApi):
|
26
|
-
"""
|
27
|
-
添加用户
|
28
|
-
"""
|
29
|
-
api.resp.uid = 1
|
30
|
-
return api.json_resp()
|
31
|
-
|
32
|
-
|
33
|
-
@users_blueprint.route("/<uid>", methods=["DELETE"])
|
34
|
-
async def user_del(request: Request, uid: int, api: UserDelApi):
|
35
|
-
"""
|
36
|
-
刪除一个用户
|
37
|
-
"""
|
38
|
-
|
39
|
-
api.resp.uid = uid
|
40
|
-
|
41
|
-
return api.json_resp()
|
42
|
-
|
43
|
-
|
44
|
-
@users_blueprint.route("/<uid>", methods=["PUT"])
|
45
|
-
async def user_update(request: Request, uid: int, api: UserUpdateApi):
|
46
|
-
"""
|
47
|
-
更新一个用户
|
48
|
-
"""
|
49
|
-
|
50
|
-
api.resp.uid = uid
|
51
|
-
|
52
|
-
return api.json_resp()
|
53
|
-
|
54
|
-
|
55
|
-
@users_blueprint.route("/<uid>", methods=["GET"])
|
56
|
-
async def user_one(request: Request, uid: int, api: UserFindOneApi):
|
57
|
-
"""
|
58
|
-
获取一个用户
|
59
|
-
"""
|
60
|
-
|
61
|
-
api.resp.uid = 1
|
62
|
-
api.resp.username = "username"
|
63
|
-
api.resp.password = uuid4().hex
|
64
|
-
|
65
|
-
return api.json_resp()
|
66
|
-
|
67
|
-
|
68
|
-
@users_blueprint.route("/", methods=["GET"])
|
69
|
-
async def user_list(request: Request, api: UserListApi):
|
70
|
-
"""
|
71
|
-
获取一些用户
|
72
|
-
"""
|
73
|
-
|
74
|
-
users: List[Dict[str, Any]] = [
|
75
|
-
{
|
76
|
-
"uid": 1,
|
77
|
-
"username": "user1",
|
78
|
-
},
|
79
|
-
{
|
80
|
-
"uid": 2,
|
81
|
-
"username": "user2",
|
82
|
-
},
|
83
|
-
]
|
84
|
-
for user in users:
|
85
|
-
api.resp.username = user["username"]
|
86
|
-
api.resp.uid = user["uid"]
|
87
|
-
api.resp.add_data()
|
88
|
-
|
89
|
-
return api.json_resp()
|
1
|
+
from typing import Any, Dict, List
|
2
|
+
from uuid import uuid4
|
3
|
+
|
4
|
+
from sanic import Blueprint, text
|
5
|
+
from sanic.request import Request
|
6
|
+
|
7
|
+
from .validator import (
|
8
|
+
UserAddApi,
|
9
|
+
UserDelApi,
|
10
|
+
UserFindOneApi,
|
11
|
+
UserListApi,
|
12
|
+
UserUpdateApi,
|
13
|
+
)
|
14
|
+
|
15
|
+
users_blueprint = Blueprint("users_blueprint", url_prefix="/users")
|
16
|
+
users_blueprint.ctx.desc = "用户"
|
17
|
+
|
18
|
+
|
19
|
+
@users_blueprint.route("/test", methods=["GET"])
|
20
|
+
async def hello(request):
|
21
|
+
return text("Hello world!")
|
22
|
+
|
23
|
+
|
24
|
+
@users_blueprint.route("/", methods=["POST"])
|
25
|
+
async def user_add(request: Request, api: UserAddApi):
|
26
|
+
"""
|
27
|
+
添加用户
|
28
|
+
"""
|
29
|
+
api.resp.uid = 1
|
30
|
+
return api.json_resp()
|
31
|
+
|
32
|
+
|
33
|
+
@users_blueprint.route("/<uid>", methods=["DELETE"])
|
34
|
+
async def user_del(request: Request, uid: int, api: UserDelApi):
|
35
|
+
"""
|
36
|
+
刪除一个用户
|
37
|
+
"""
|
38
|
+
|
39
|
+
api.resp.uid = uid
|
40
|
+
|
41
|
+
return api.json_resp()
|
42
|
+
|
43
|
+
|
44
|
+
@users_blueprint.route("/<uid>", methods=["PUT"])
|
45
|
+
async def user_update(request: Request, uid: int, api: UserUpdateApi):
|
46
|
+
"""
|
47
|
+
更新一个用户
|
48
|
+
"""
|
49
|
+
|
50
|
+
api.resp.uid = uid
|
51
|
+
|
52
|
+
return api.json_resp()
|
53
|
+
|
54
|
+
|
55
|
+
@users_blueprint.route("/<uid>", methods=["GET"])
|
56
|
+
async def user_one(request: Request, uid: int, api: UserFindOneApi):
|
57
|
+
"""
|
58
|
+
获取一个用户
|
59
|
+
"""
|
60
|
+
|
61
|
+
api.resp.uid = 1
|
62
|
+
api.resp.username = "username"
|
63
|
+
api.resp.password = uuid4().hex
|
64
|
+
|
65
|
+
return api.json_resp()
|
66
|
+
|
67
|
+
|
68
|
+
@users_blueprint.route("/", methods=["GET"])
|
69
|
+
async def user_list(request: Request, api: UserListApi):
|
70
|
+
"""
|
71
|
+
获取一些用户
|
72
|
+
"""
|
73
|
+
|
74
|
+
users: List[Dict[str, Any]] = [
|
75
|
+
{
|
76
|
+
"uid": 1,
|
77
|
+
"username": "user1",
|
78
|
+
},
|
79
|
+
{
|
80
|
+
"uid": 2,
|
81
|
+
"username": "user2",
|
82
|
+
},
|
83
|
+
]
|
84
|
+
for user in users:
|
85
|
+
api.resp.username = user["username"]
|
86
|
+
api.resp.uid = user["uid"]
|
87
|
+
api.resp.add_data()
|
88
|
+
|
89
|
+
return api.json_resp()
|