简体   繁体   English

Flask-restx 请求解析器返回 400 Bad Request

[英]Flask-restx request parser returns 400 Bad Request

I'm using flask-restx in my flask application but each time I use the swagger ui to make a request it returns this 400:我在我的烧瓶应用程序中使用flask-restx但每次我使用 swagger ui 发出请求时,它都会返回 400:

http://127.0.0.1:5000/api/user/register/?password=test&email=test&username=test
{
  "message": "Did not attempt to load JSON data because the request Content-Type was not 'application/json'."
}

My file structure:我的文件结构:

flask-project/
├─ run.py
├─ app/
│  ├─ main/
│  │  ├─ __init__.py
│  │  ├─ api/
│  │  │  ├─ __init__.py
│  │  │  ├─ user.py
│  ├─ __init__.py

app/_init_.py

import os
from dotenv import load_dotenv

from flask import Flask

# Extensions
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_socketio import SocketIO

db = SQLAlchemy()
ma = Marshmallow()
socketio = SocketIO()

load_dotenv()


def create_app(debug=False):
    from app.main.api import api_blueprint

    app = Flask(__name__)
    app.debug = debug
    app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
    app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///database.sqlite3"
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "true"  # !! Only in development environment.

    db.init_app(app)  # Flask-SQLAlchemy must be initialized before Flask-Marshmallow.
    ma.init_app(app)
    socketio.init_app(app)

    app.register_blueprint(api_blueprint, url_prefix='/api')

    with app.app_context():
        db.create_all()

    @app.before_first_request
    def create_tables():
        """ Pre-populate specific tables """
        pass

    return app

user.py

from flask_restx import Namespace, Resource, reqparse

api = Namespace('user')

@api.route('/register')
@api.param('username', 'Username')
@api.param('email', 'Email')
@api.param('password', 'Password')
class CreateUser(Resource):
    def put(self):
        parser = reqparse.RequestParser()
        parser.add_argument('username', location='json', type=str)
        parser.add_argument('email', location='json', type=str)
        parser.add_argument('password', location='json', type=str)
        args = parser.parse_args()
        
        return args

When I placed print statements in the put method, I found that the method is called and anything before I define args will print.当我在put方法中放置 print 语句时,我发现该方法被调用,并且在我定义 args 之前的任何内容都会打印出来。 After the line where I define args nothing prints.在我定义 args 的那一行之后没有打印。 What am I doing wrong?我究竟做错了什么?

我发现通过从 Werkzeug 2.1.2 降级到 2.0.2 解决了这个问题。

I just went through this on a project this weekend.这个周末我刚刚在一个项目上经历了这个。

api.param is for parameters that are in the path, like /users/<user_id> . api.param用于路径中的参数,例如/users/<user_id> The parameters you are using are query parameters, not path parameters.您使用的参数是查询参数,而不是路径参数。 So remove the 3 @api.param decorators.所以删除 3 个@api.param装饰器。

As I understand it, location='json' is for extracting data from the body of a request sent in JSON.据我了解, location='json'用于从以 JSON 格式发送的请求正文中提取数据。 Your parameters are query parameters.您的参数是查询参数。 Change your parser.add_argument calls to use location='args' .Then after calling parse_args() as you have in your posted code, you should be able to do args['username'] to get the value of the username query arg, which will give None if username arg was not given.更改您的parser.add_argument调用以使用location='args' 。然后在您发布的代码中调用parse_args()之后,您应该能够执行args['username']来获取username查询 arg 的值,如果没有给出username arg,它将给出 None 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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