new programmmmmer new programmmmmer - 1 month ago 14
reST (reStructuredText) Question

using curl to use POST using Python RESTful API

I can't figure out how to get curl working when I try to POST some information into the database. I was getting an error before saying it couldn't read txt file but then I put the full path, now it says "sent a request the server could not understand" Tbh I'm not sure how to use curl properly and don't know what to put in the url if I'm not using a txt file too.

my curl looks like this

C:\Windows>curl -X POST -d "C:/Users/Muba/PycharmProjects/API practise/todo.txt"
http://127.0.0.1:5000/ --header "Content-Type:application/json"


My todo.txt file contains

todo_ID, 12
User_ID, 8
details, "Get rid of all the flies in the house."


And this is my code.

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

import requests


app = Flask(__name__)
app.config.from_pyfile('Config.py')
db = SQLAlchemy(app)
db.create_all()
class JsonModel(object):
def as_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}

class User(db.Model, JsonModel):
User_ID = db.Column(db.Integer, primary_key = True)
FirstName = db.Column(db.String(20))
LastName = db.Column(db.String(20))

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

class Todo(db.Model, JsonModel):
todo_ID = db.Column(db.Integer, primary_key = True)
UserID = db.Column(db.Integer, db.ForeignKey('User_ID'))
details = db.Column(db.String(30))

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

@app.route('/', methods = ['GET'])
def index():
return json.dumps([u.as_dict() for u in User.query.all()+Todo.query.all()])


@app.route('/', methods = ['POST'])
def create_dev():
if not request.json or not 'name' in request.json:
abort(400)
dev = Todo(request.json.todo_ID, request.json.get('todo_ID',''), request.json.UserID, request.json.get('UserID',''),
request.json.details,request.json.get('details',''))
db.session.add(dev)
db.session.commit()
return json.dumps([{'dev': dev}]), 201

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

Answer

Firstly, I would not recommend cURL to starters, use Postman, for example, or find some other HTTP testing tool of your choice.

Secondly, your data needs to actually be JSON

todo.json

{
    "todo_ID": 12,
    "User_ID": 8,
    "details": "Get rid of all the flies in the house."
}

Take this very simple Flask app as an example.

from flask import Flask, request
app = Flask(__name__)

@app.route('/', methods = ['POST'])
def sample():
    if request.method == 'POST':
        print("POST'd", request.json)
    return "handled"

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

And cURL it (replace with your filepath)

curl -XPOST -d \
  @/path/to/todo.json \
  -H "Content-Type:application/json" \
  http://path.to.flask:port/

I see the output of the request is handled, and in the server logs I see

POST'd {'User_ID': 8, 'todo_ID': 12, 'details': 'Get rid of all the flies in the house.'}

Now, if you are dealing with JSON documents, mostly, probably best not to use a column-oriented relational database like anything SQL (because it's annoying to "translate" JSON to columns, especially for nested objects and lists). Instead look into Couchbase or MongoDB, for example.