FLASK REST API在POST上返回400

在网上

我正在使用flask和SQLAlchemy作为我的ORM为一个简单的Todo应用程序构建REST API。我正在使用Postman测试我的API。我在Windows 10 64位计算机上。

GET请求有效并返回使用python输入到数据库中的数据。

获取请求

我想立即尝试添加任务。但是,当我发布请求时,我收到一个错误。

POST请求

我在烧瓶中的路线看起来像这样。

#add task
@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    if not request.json or not 'title' in request.json:
        raise InvalidUsage('Not a valid task!', status_code=400)
    task = {
        'title': request.json['title'],
        'description': request.json['description'],
        'done': False
    }
    Todo.add_todo(task)
    return jsonify({'task': task}), 201

它在Todo对象上调用的方法如下所示。

def add_todo(_title, _description):
    new_todo = Todo(title=_title, description=_description , completed = 0)
    db.session.add(new_todo)
    db.session.commit()

我尝试过的

我以为'邮递员Params中的可能引起了问题,因此我将其删除。但是我仍然遇到同样的错误。

Then I thought that maybe the way that Postman was sending the POST was incorrect so I checked to make sure that the Content-Type headers was correct. It is set to application/json

Finally, to confirm that the issue was that flask didn't like the request, I removed the check in the add task route to make sure the request had a title. So it looks like this.

if not request.json:

And I get the same error. So I think that the problem must be with how I'm actually sending the POST rather than some kind of formatting issue.

My entire code looks like this.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import json
from flask import jsonify
from flask import request

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

class Todo(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(300), unique=False, nullable=False)
    description = db.Column(db.String(), unique=False, nullable=False)
    completed = db.Column(db.Boolean, nullable=False)

    def json(self):
        return {'id': self.id,'title': self.title, 'description': self.description, 'completed': self.completed}

    def add_todo(_title, _description):
        new_todo = Todo(title=_title, description=_description , completed = 0)
        db.session.add(new_todo)
        db.session.commit()

    def get_all_tasks():
        return [Todo.json(todo) for todo in Todo.query.all()]

    def get_task(_id):
        task = Todo.query.filter_by(id=_id).first()
        if task is not None:
            return Todo.json(task)
        else:
            raise InvalidUsage('No task found', status_code=400)

    def __repr__(self):
        return f"Todo('{self.title}')"




class InvalidUsage(Exception):
    status_code = 400

    def __init__(self, message, status_code=None, payload=None):
        Exception.__init__(self)
        self.message = message
        if status_code is not None:
            self.status_code = status_code
        self.payload = payload

    def to_dict(self):
        rv = dict(self.payload or ())
        rv['message'] = self.message
        return rv

@app.route('/')
def hello_world():
    return 'Hello to the World of Flask!'

#get all tasks
@app.route('/todo/api/v1.0/tasks', methods=['GET'])
def get_tasks():
    return_value = Todo.get_all_tasks()
    return jsonify({'tasks': return_value})

#get specific task
@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):
    task = Todo.get_task(task_id)
    #if len(task) == 0:
        #raise InvalidUsage('No such task', status_code=404)
    return jsonify({'task': task})

#add task
@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    if not request.json or not 'title' in request.json:
        raise InvalidUsage('Not a valid task!', status_code=400)
    task = {
        'title': request.json['title'],
        'description': request.json['description'],
        'done': False
    }
    Todo.add_todo(task)
    return jsonify({'task': task}), 201

#update task
@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['PUT'])
def update_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if len(task) == 0:
        raise InvalidUsage('No provided updated', status_code=400)
    if not request.json:
        raise InvalidUsage('request not valid json', status_code=400)
    if 'title' in request.json and type(request.json['title']) != unicode:
        raise InvalidUsage('title not unicode', status_code=400)
    if 'description' in request.json and type(request.json['description']) != unicode:
        raise InvalidUsage('description not unicode', status_code=400)
    if 'done' in request.json and type(request.json['done']) is not bool:
        raise InvalidUsage('done not boolean', status_code=400)
    task[0]['title'] = request.json.get('title', task[0]['title'])
    task[0]['description'] = request.json.get('description', task[0]['description'])
    task[0]['done'] = request.json.get('done', task[0]['done'])
    return jsonify({'task': task[0]})

#delete task
@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['DELETE'])
def delete_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if len(task) == 0:
        raise InvalidUsage('No task to delete', status_code=400)
    tasks.remove(task[0])
    return jsonify({'result': True})


@app.errorhandler(InvalidUsage)
def handle_invalid_usage(error):
    response = jsonify(error.to_dict())
    response.status_code = error.status_code
    return response

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

EDIT:

Turns out I wasn't setting the request type in POSTMAN correctly. I've updated it to 'application/json' in the header. Now I'm receiving a different error.

Bad Request Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)

我已经像以前一样尝试了所有前面的步骤,但是仍然遇到此错误。

Badrequest

编辑2:

根据下面的响应,我尝试将这些值放入POST正文中。但是我仍然得到400条回应。

body

杜尚·玛ď(DušanMaďar)

从图像[第二个邮递员屏幕截图]中,您看起来像是在查询字符串中传递数据,create_task()希望它们在请求正文中

可以request.jsonrequest.argsin替换所有出现的in create_task()(以使其与查询参数一起使用),也可以使其保持不变并将数据发送到请求正文中。

curl -X POST http://localhost:5000/todo/api/v1.0/tasks \
-H "Content-Type: application/json" \
-d '{"title":"Learn more flask","description":"its supper fun"}'

另外,看看获取Flask请求中接收到的数据


已编辑

更新你add_todo的东西

@classmethod
def add_todo(cls, task):
    new_todo = cls(title=task["title"], description=task["description"], completed=0)
    db.session.add(new_todo)
    db.session.commit()

相关:使用dictionary广义插入sqlalchemy中

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

限制对Flask REST API的访问

Flask 的 Javascript REST API 错误

通过 Flask REST API 创建 JSON 文件

使用WebSocket扩展Flask REST API

Flask REST API用JSONArray响应

Flask 嵌套的 rest api 招摇不工作

Flask REST POST请求基于json的长度失败“ Bad Request”

即使uri正确,服务器也会在REST POST CALL上返回错误请求400

通过HTTP2提供Python(Flask)REST API

部署机器学习模型 Flask 和 REST API

NGINX不与flask rest API通信。码头工人

在Flask中使用REST APi推值,获取结果

用Flask REST API代码生成SQLite数据库

使用SQLAlchemy的Flask REST API中的整数范围

Flask REST API 记录发件人的 IP 地址

无法使用getJSON从Flask Rest API获取Json

Dockerized Python Flask REST API 显示“页面不工作

如何在Flask REST API服务中使用Keycloak

flutter和Flask REST API之间的数据解析

构建微服务事件总线和REST api(python / flask)

Windows 10 IIS URL错误-Python Flask Rest API

将 Flask Restless API 连接到 Admin-on-rest (React)

Flask REST API错误:视图函数未返回有效响应

根据请求返回的 Flask REST api 标头以及标头究竟是什么

Flask REST API 返回 json 数据,末尾带有额外的空大括号

从另一个Flask应用程序调用Flask应用程序的REST API

flask rest api应用程序可以单独在gunicorn上运行吗?

如何从 Internet 浏览 Windows Server 2012 r2 上的 IIS 部署的flask rest api

Jira POST&PUT Rest调用从Python返回错误400