Search code examples
pythoncurlpostflaskput

Using curl to POST and update multiple data


I've seen this question asked a lot but the questions have to do with using txt files or data from forms. I can use curl to POST data when using a json file but I want to know how I can do it by manually adding data into the curl statement. I also tried using PUT in curl statement but couldn't get it to work as well. I looked at a lot of questions but most only use like the ID or something and I'm trying to POST and PUT in 3 things. Also I tried making some small changes to the data in the statement but they kept giving me different errors like bracket misplacement. Plz help this beginner U_U

My curl statement for posting in the database is.

curl -X POST -d '{"todo_ID":18,"UserID":6,"details":"Stop putting in the same things"}' -H "Content-Type:application/
json" http://127.0.0.1:5000/

It says this error and I tried to make changes but still get the same error.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>The browser (or proxy) sent a request that this server could not understand.<
/p>

When using PUT my curl statement is

curl -X PUT -H "Content-Type:applicat
ion/json" -d {"todo_ID":1,"UserID": 3,"details":"hi let it go"} http://127.0.0.1
:5000/update/1

I basically get the same error that I get for POST.

My code is.

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

app = Flask(__name__)
app.config.from_pyfile('Config.py')
db = SQLAlchemy(app)

class JsonModel(object): #Class for making objects JSON serializable
    def as_dict(self):
        return {c.name: getattr(self, c.name) for c in self.__table__.columns}

class User(db.Model, JsonModel): #Class which is a model for the User table in the database
    User_ID = db.Column(db.Integer, primary_key = True)
    FirstName = db.Column(db.String(20))
    LastName = db.Column(db.String(20))

    def __init__(self,User_ID,FirstName, LastName):
        self.User_ID = User_ID
        self.FirstName = FirstName
        self.LastName = LastName

class Todo(db.Model, JsonModel):    #Class which is a model for the Todo table in the database
    todo_ID = db.Column(db.Integer, primary_key = True)
    UserID = db.Column(db.Integer, db.ForeignKey("user.User_ID"))
    details = db.Column(db.String(30))

    def __init__(self,todo_ID, UserID,details):
        self.todo_ID = todo_ID
        self.UserID = UserID
        self.details = details

@app.route('/', methods = ['POST'])  #Uses POST method with same URL as GET method to add new information to Todo table.
def create_dev():
    dev = Todo(request.json["todo_ID"], request.json["UserID"], request.json["details"])
    db.session.add(dev)
    db.session.commit()
    return json.dumps([{'dev': dev}]), 201

@app.route('/update/<int:todo_ID>', methods = ['PUT'])
def update_todo(todo_ID):
    dev = Todo.query.get(todo_ID)
    dev.UserID = Todo(request.json["UserID"])
    dev.details = Todo(request.json["details"])
    db.session.update(dev)
    db.session.commit()
    return jsonify( { 'dev': dev})

@app.before_first_request #Creates everything before the first request.
def startup():
    db.create_all()

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

Solution

  • 400 Bad Requests are usually seen when you're trying to access some data from the request that isn't there.

    In your case it's probably failing when you first try to read request.json["todo_ID"] from your request because Flask has been unable to decode your json correctly.

    Now, curl can be a bit of a pain to get working with json (check other SO questions on the subject). The easiest way to test is to create an example.json text file with the contents:

    {
        "todo_ID":18,
        "UserID":6,
        "details":"Stop putting in the same things"
    }
    

    Then adjust your curl command to use that file instead of handling the string itself, by running curl -H "Content-Type: application/json" -X POST -d @example.json http://127.0.0.1:5000/

    Your problem should disappear.