【问题标题】:attribute error raised when tried to document flask restplus request bodywith?尝试记录烧瓶 restplus 请求正文时引发的属性错误?
【发布时间】:2020-08-04 10:01:46
【问题描述】:

我正在尝试使用 Flask-restplus'api.model 记录我的请求正文,并且我必须以特定结构提供数据。这是请求正文的样子:

请求正文

{
  "version": 0,
  "subject": "SUBJECT10",
  "organization": "company",
  "time": "2010-02-10T09:30:00Z",
  "features": {
    "age": 18,
    "gender": "M",
    "hear_rate": {
      "value": 120,
      "time": "2010-02-10T09:30:00Z"
    },
    "blood pressure": {
      "value": 72,
      "time": "2012-02-10T09:30:00Z"
    },
    "wbc": {
      "value": 10,
      "time": "2010-02-10T09:30:00Z"
    }
  }
}

我的尝试

为了将我的请求主体建模为 Flask-Restplus'api.model,我想出了以下引发属性错误的解决方案。

from flask_restplus import fields
from flask import Flask, jsonify
from flask_restplus import Api, Resource, fields, reqparse, inputs

app = Flask(__name__)
api = Api(app)
ns = api.namespace('test api')

features_attr = api.model('features', {
    # 'name': fields.String(required=True),
    'value': fields.Integer(required=True),
    'time': fields.Date(required=True)
})

class feats_objs(fields.Nested):
    __schema_type__ = ['string', 'object']

    def output(self, key, obj):
        if key =='value':
            return obj
        else:
            return 'default value'
        return super().output(key, obj)

    def schema(self):
        schema_dict = super().schema()
        schema_dict.pop('type')
        nested_ref = schema_dict.pop('$ref')
        schema_dict['oneof'] = [
        {'type': 'string'},
        {'$ref': nested_ref}
        ]
        return schema_dict

feat_root_objs = api.model('feats_root_objs', {
    'age': fields.String(required=True),
    'gender': fields.String(required=True),
    'time': fields.Date(required=True),
    'features': fields.List(fields.biom_feats_objs(features_attr))
    })

@ns.route('/my_features')
class my_features(Resource):
    @ns.expect(feat_root_objs)
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('age', type=str, required=True),
        parser.add_argument('gender', type=str, required=True),
        parser.add_argument('features', type=str, required=True),
        parser.add_argument('time', type=inputs.datetime_from_iso8601, required=True)

        try:
            args = parser.parse_args()
            return jsonify(args)
        except:
            return None, 400

    if __name__ == '__main__':
        app.run(debug=True)

错误信息

这是我从上面的代码中得到的错误信息。

Traceback (most recent call last):
  File ".\my_features.py", line 41, in <module>
    'features': fields.List(fields.feats_objs(features_attr))
AttributeError: module 'flask_restplus.fields' has no attribute 'feats_objs'

但是上面的代码给了我属性错误,我不知道为什么上面的代码不能编译。我怎样才能使这项工作?我怎样才能为上述请求正文和响应正文正确api.model?有什么想法可以做到这一点吗?谢谢

【问题讨论】:

  • 你能发布你得到的错误和堆栈跟踪吗?
  • @khuynh 感谢您的提醒。我粘贴了错误。非常感谢您的帮助。
  • @khuynh 你能帮我如何让它按我的预期工作吗?
  • 您错误地使用了fields。如果您尝试对feature_attr 的列表进行建模,则可以使用fields.Nested。您应该修改这一行:'features': fields.List(fields.Nested(features_attr)) 以消除您的错误。
  • @khuynh 你的意思是修改为fields.Nested(features_attr) ?我仍然有同样的错误。你能发布一个可行的解决方案吗?我将如何处理响应正文?

标签: python flask flask-restful flask-restplus


【解决方案1】:

您的代码中缺少一些内容:

1) 从flask_restfulplus 导入Namespace 对象

2) 使用Namespace 对象创建命名空间

3) 向 API 注册命名空间

查看修改后的代码sn -p:

from flask_restplus import fields
from flask import Flask, jsonify
from flask_restplus import Api, Namespace, Resource, fields, reqparse, inputs
# 1) import `Namespace` above


app = Flask(__name__)
api = Api(app)
ns = Namespace('test api')       # 2) create the namespace 'test api'

features_attr = api.model('biomarker features', {
    # 'name': fields.String(required=True),
    'value': fields.Integer(required=True),
    'time': fields.Date(required=True)
})

class biom_feats_objs(fields.Nested):
    __schema_type__ = ['string', 'object']

    def output(self, key, obj):
        if key =='value':
            return obj
        else:
            return 'default value'
        return super().output(key, obj)

    def schema(self):
        schema_dict = super().schema()
        schema_dict.pop('type')
        nested_ref = schema_dict.pop('$ref')
        schema_dict['oneof'] = [
        {'type': 'string'},
        {'$ref': nested_ref}
        ]
        return schema_dict

feat_root_objs = api.model('biom_feats_root_objs', {
    'age': fields.String(required=True),
    'gender': fields.String(required=True),
    'time': fields.Date(required=True),
    'features': fields.List(fields.Nested(features_attr))
    })

@ns.route('/immunomatch_Ed_features')
class immunomatch_Ed_features(Resource):
    @ns.expect(feat_root_objs)
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('age', type=str, required=True),
        parser.add_argument('gender', type=str, required=True),
        parser.add_argument('features', type=str, required=True),
        parser.add_argument('time', type=inputs.datetime_from_iso8601, required=True)

        try:
            args = parser.parse_args()
            return jsonify(args)
        except:
            return None, 400

if __name__ == '__main__':
    api.add_namespace(ns)      # 3) register your namespace with your api
    app.run(debug=True)

请参阅docs,了解如何使用多个命名空间以及如何创建和注册它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-18
    • 2014-07-23
    • 2017-06-02
    • 2015-03-10
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多