是否可以将传入的请求有效负载解组为瓶子或烧瓶中的方法/函数参数?如果是这样,怎么做?
我想发送以下内容作为 POST/PUT 请求的请求负载,
{ 'foo': [ 'bar1', 'bar2'], 'spam': 2 }
并将其用于伪代码中,
@route('/cheeseshop/<id>', method='PUT')
def cheeseShop(foo, spam):
pass
这可以通过查看这些框架中的任何一个中的内容类型来自动完成吗?
是否可以将传入的请求有效负载解组为瓶子或烧瓶中的方法/函数参数?如果是这样,怎么做?
我想发送以下内容作为 POST/PUT 请求的请求负载,
{ 'foo': [ 'bar1', 'bar2'], 'spam': 2 }
并将其用于伪代码中,
@route('/cheeseshop/<id>', method='PUT')
def cheeseShop(foo, spam):
pass
这可以通过查看这些框架中的任何一个中的内容类型来自动完成吗?
这样做有一些注意事项以提高代码的可读性,但可能的解决方案如下。
定义序列化方法。如果您需要与不同的客户合作,我建议JSON
。
创建一个装饰器并将其放在你function
和route
@route(...)
@expandargs
def foo(id, bar, baz):
...
在装饰器中使用request.json()
(如果是,则自动解码有效负载JSON
)来扩展 args,然后您将使用 originalargs
和 new 调用包装函数,例如**expandedargs
(注意双星号以展开关键字)。
混合位置和关键字参数时会出现问题。
这是因为只是勾勒出 Paolos 的答案,但为了帮助其他人寻找这个,这里有一个实现目标的解组装饰器的示例。
from functools import wraps
def unmarshal_payload(view):
@wraps(view)
def unmashalled_view(*args, **kwargs):
return view(*args, **request.get_json(), **kwargs)
return unmashalled_view
然后将其用作:
@app.route(f'/<int:id>/', methods=['PUT'])
@unmarshal_payload
def view(id, foo, bar):
print(id, foo, bar)
return 'Success'
然后根据你想如何处理包含{'id': 'something'}
你的有效负载之类的东西可以改变它。就像在这个幼稚的实现中一样,Flask 将返回一个内部服务器错误,因为 python 会抛出一个 TypeError,因为函数接收同一关键字的多个关键字参数。此外,如果您提供未在视图中命名的参数,您将收到带有 Unexpected 关键字的类型错误。
所以稍微宽松一点的定义是:
from functools import wraps
def unmarshal_payload(view):
@wraps(view)
def unmashalled_view(*args, **kwargs):
return view(*args, **kwargs, **{k:v for k,v in request.get_json().items() if k not in kwargs})
return unmashalled_view
@app.route(f'/<int:id>/', methods=['PUT'])
@unmarshal_payload
def view(id, foo, bar, **kwargs):
print(id, foo, bar)
return 'Success'