简体   繁体   中英

Flask-restplus how to post without a body

I'd like to use the POST verb to perform actions on a VM with flask-restplus, but it always results in a 400 when there is no body.

VM_ACTION_FIELDS = {
      'vmActionId': fields.Integer(required=True, description='The vmActionId of the VmAction'),
      'vmId': fields.Integer(required=True, description='The vmId of the VmAction'),
      'status': fields.String(required=True, description='The status of the VmAction',
                              enum=['NEW', 'REQUESTED', 'IN_PROGRESS', 'ERROR', 'COMPLETED']),
      'actionType': fields.String(required=True, description='The actionType of the VmAction',
                                  enum=['STOP', 'RESTART']),
      'createdAt': fields.DateTime(required=True,
                                   description='The createdAt datetime of the VmAction'),
      'completedAt': fields.DateTime(required=True,
                                     description='The completedAt datetime of the VmAction'),
  }
  VM_ACTION_MODEL = api.model('VmAction', VM_ACTION_FIELDS)

  [snip]

      @vms_ns.route('/<int:vmId>/stop', endpoint='vmStop')
      class VmStopView(Resource):
          """
          Stop a VM
          """
          @api.marshal_with(VM_ACTION_MODEL, code=202)
          @api.doc(id='stopVm', description='Stop a Vm')
          def post(self, vmId):
              # do stuff 
              return vmAction, 202

The result is 400 { "message": "The browser (or proxy) sent a request that this server could not understand." }

If I simply change from post to get, it works fine. BUT, I really want to use the POST verb for this, because thats the standard verb I need to follow for custom non-CRUD actions. Have I painted myself into a corner with flask-restplus?

Note: for operations that require a body, it works fine. Its only bodyless flask-restplus post operations that 400 error on empty body.

If you're setting the content-type to application/json I think you're body should be at least {} . If you want to submit an empty payload, just remove the content-type header.

I think this is exactly this issue (which I'm trying to figure out): https://github.com/noirbizarre/flask-restplus/issues/84

Here is a workaround that is working for me to hold me over until another solution is found:

@app.before_request
  def before_request():
      """This is a workaround to the bug described at
      https://github.com/noirbizarre/flask-restplus/issues/84"""
      ctlen = int(request.headers.environ.get('CONTENT_LENGTH', 0))
      if ctlen == 0:
          request.headers.environ['CONTENT_TYPE'] = None

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM