最近在使用apiflask框架,总体来说这个框架十分的赞!
在使用的过程中遇到了一下的一些问题或者说是疑问,有的问题已经自行解决但不知道是否有更好的方法。
因此发个贴看看有没有更好的、更优雅的解决方法。
(表达能力不太好,见谅 and 由于写作的时间跨度比较大,因此个别方法已在官方文档中贴出,但下文并未提及,有的也可能是我眼瞎没看到)
自定义通用响应体
个人感觉这个问题是比较重要的,目前的解决方法过于丑陋。
当前的解决办法(Flask通用),是先定义一个格式化响应体的函数,然后将内容格式化成字典然后返回,但这样就不知道应该如何与@output
装饰器配合使用了,感觉这个问题应该是有成熟的解决方案才对。
其中这个自定义的响应体应该是全局通用的,包括错误处理之类(框架自动处理 or 开发者手动处理的错误)
def make_res(code:int=200, message:str="ok", data: Any=None) -> dict:
return {
"code": code,
"message": message,
"data": data,
"timestamp": get_timestamp()
}
@app.get('/')
def index():
...
return make_res( ... )
Abort函数
-
abort
函数应该如何搭配上面的自定义响应体一起使用? - 有的时候错误会有状态码需要返回出去,但
abort
好像只可以输入http协议范围内的错误状态码(好像是因为会和http的status code绑定在一起)
@docs装饰器的使用
-
apiflask
直接生成api文档这个功能十分的cool~,但随之而来的问题是我应该如何指定文档中参数的类型,比如form
表单中文件上传。 - api文档中的
Example Value
应该如何修改
Example Value
目前的解决方法是在Schema
模型中指定missing
和default
字段
@input装饰器的使用
官网中给出了input可以location到files
、‘form’、‘cookies’、‘headers’和’query’
其中files
不太清楚如何获取.
关于用户认证
用户认证是极其重要的一块,一般前后端交互中使用token
实现。查看apiflask
官网发现到目前位置仍然没有找到相关部分的栗子。所幸apiflask使用了flask-httpauth
模块蹭使用过,一下是我的解决方案,同样的个人对这个实现方法不太满意,感觉比较丑陋。代码如下:
问题:
- 当使用类的方法(MethodView)来组织时,如何添加认证
- 如何为整个类添加认证 ->
未知
- 如何为类中的个别方法添加 ->
为这个类的方法添加装饰器@auth_required
- 如何为整个类添加认证 ->
- 当使用普通视图函数时应该如何添加 -> 直接添加
@auth_required
extend.py
from apiflask import HTTPTokenAuth
@auth.verify_token
def verify_token(token):
"""验证token
验证函数,验证token是否有效
Args:
token (str): 前端传来的token
Returns:
Bool: True表示token验证有效 否则False
"""
g.user = None
try:
data = Serializer(current_app.config['SECRET_KEY']).loads(token)
except Exception as e:
return False
if "username" in data:
g.user = data["username"]
return True
return False
utils.py
def generate_auth_token(payload:dict, expiration=3600 * 24 * 7):
"""生成token
Args:
payload (dict): token载体
expiration (int, optional): token有效时间. Defaults to 3600*24*7.
Returns:
str: token令牌
"""
s = Serializer(current_app.config["SECRET_KEY"], expires_in=expiration)
return s.dumps(payload).decode()
views.py
from apiflask.decorators import auth_required
...
@bp.get("/")
@auth_required(auth)
def index():
user = {"msg": "not found"}
for item in users:
if item["username"] == g.user:
user = item
return user
ps: 上面的代码均已分类push到GitHub,新手上路 小心高血压!