Flasgger AttributeError:' NoneType'对象没有属性' get'?

时间:2018-01-31 15:44:37

标签: python flask swagger flasgger

当我尝试访问http://localhost:8000/apidocs/index.html时,出现以下错误:

127.0.0.1 - - [31/Jan/2018 16:38:09] "GET /apidocs/index.html HTTP/1.1" 302 -
127.0.0.1 - - [31/Jan/2018 16:38:10] "GET /apidocs/ HTTP/1.1" 200 -
127.0.0.1 - - [31/Jan/2018 16:38:10] "GET /apispec_1.json HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python2.7/dist-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python2.7/dist-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python2.7/dist-packages/flask/views.py", line 84, in view
    return self.dispatch_request(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/flask/views.py", line 149, in dispatch_request
    return meth(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/flasgger/base.py", line 205, in get
    prefix_ids=prefix_ids)
  File "/usr/local/lib/python2.7/dist-packages/flasgger/utils.py", line 648, in extract_definitions
    properties.values(), level + 1, endpoint, verb, prefix_ids)
  File "/usr/local/lib/python2.7/dist-packages/flasgger/utils.py", line 617, in extract_definitions
    if not getattr(item, 'get'):
AttributeError: 'NoneType' object has no attribute 'get'

这是我的烧瓶应用程序:

def init_deserializer_restful_api():
    # Get port number for the web app.
    PORT = 8000

    # Initiate the Flask app
    app = Flask(__name__)
    Swagger(app)
    CORS(app)

    # Handler for deserializer
    @app.route("/deserialize", methods=['POST'])
    def handle_deserialization_request():
        # here swagger documentation and content of method


  """
    Deserialize a bag file to json
    ---
    tags:
      - deserializer
    consumes:
      - application/json
    produces:
      - application/json
    parameters:
      - name: body
        in: body
        description: request body
        required: true
        schema:
          type: object
          required:
            - name
            - es_addr
            - json
          properties:
            name:
              description: the file path to the log file / name of the file e.g log.tar.lz4
              type: string
            json:
              description: local json file name
              type: string
            es_addr:
            description: elastic search address
            type: string
    responses:
      200:
        description: returns the status of deserialization
        schema:
          type: object
          properties:
            status:
              description: success / error
              type: string
            response:
              description: message about the status
              type: object
              properties:
                data:
                  description: the data returned by API upon success
                  type: string
                error:
                  description: the error message returned by API upon failure
                  type: string
    """
    # Check if input is valid json
    if not request.json:
        return jsonify(status="error",
                       response={"error": "Input is not JSON",
                                 "data": ""})
    else:
        print("[INFO] Received log deserialization request")

        parameters = request.get_json()

        file_name = parameters.get("name")
        es_addr = parameters.get("es_addr")

        #es_index = parameters.get("es_index",file_name)
        #buffer_size = parameters.get("buffer", 5000)
        json_output = parameters.get("json")
        #es_type = parameters.get("es_type","rosmsg")

        # Run deserializer
        ru = RosbagUploader(file_name, json_output, es_addr)
        status = ru.start()
        print("status = {}".format(status))
        if status == ReturnCodes.SUCCESS:
            return jsonify(status="success",
                           response={"error": "",
                                     "data": ""})
        else:
            return jsonify(status="error",
                           response={"error": "Deserialization Failed",
                                     "data": ""})

我不明白错误,我尝试在我的代码上面的POST旁边添加GET并没有解决问题。我不确定错误是否来自我的代码? 有什么建议吗?

1 个答案:

答案 0 :(得分:1)

在将其作为docstring编写时,请确保您的API规范格式正确。您可以将规范编写到自己的文件中,并使用file快捷方式。

<强> specs/deserialize.yml

Deserialize a bag file to json
---
tags:
  - deserializer
consumes:
  - application/json
produces:
  - application/json
parameters:
  - name: body
    in: body
    description: request body
    required: true
    schema:
      type: object
      required:
        - name
        - es_addr
        - json
      properties:
        name:
          description: the file path to the log file / name of the file e.g log.tar.lz4
          type: string
        json:
          description: local json file name
          type: string
        es_addr:
          description: elastic search address
          type: string
responses:
  200:
    description: returns the status of deserialization
    schema:
      type: object
      properties:
        status:
          description: success / error
          type: string
        response:
          description: message about the status
          type: object
          properties:
            data:
              description: the data returned by API upon success
              type: string
            error:
              description: the error message returned by API upon failure
              type: string

<强> api.py

def create_api():
    # Get port number for the web app.
    PORT = 8000

    # Initiate the Flask app
    app = Flask(__name__)
    Swagger(app)
    ...

    # Handler for deserializer
    @app.route("/deserialize", methods=['POST'])
    def handle_deserialization_request():
        """
        file: specs/deserialize.yml
        """
        ...
        return jsonify(
            status="error",
            response={"error": "Input is not JSON", "data": ""}
        )

    return app


api = init_deserializer_restful_api()
api.run()