tony tony - 10 days ago 5
reST (reStructuredText) Question

FLASK RESTful API using GET to get a specific id and returning 201 using Python

I'm trying to get a todo_ID using GET method. I'm still new at using sqlalchemy and most of the things i have tried are telling me that sqlalchemy doesn't use them. Also, can someone tell me how to use HEAD, i want my methods to return http statuses, i kinda tried using them and imported the render template but when i try to use them it says it has no idea what they are.

this is my attempt at looking at a tutorial and making changes

from flask import Flask, jsonify,json, request, render_template, 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, UserID, details):
self.UserID = UserID
self.details = details

@app.route('/todo', methods = ['GET']) # Uses GET method to return all information in the database.
def index():
return json.dumps([u.as_dict() for u in User.query.all()+Todo.query.all()]), 201

@app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
query = Todo.query.get()
return {'todo': [dict(zip(tuple(query.keys()), i)) for i in query.cursor if i[1] == todo_ID]}


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

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


My most recent attempt was:

@app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
query = Todo.query("select * from Todo")
return {'todo': [dict(zip(tuple(query.keys()), i)) for i in query.cursor if i[1] == todo_ID]}


And the error that I get is this.

query = Todo.query("select * from Todo")
TypeError: 'BaseQuery' object is not callable
127.0.0.1 - - [30/Nov/2016 21:15:28] "GET /todo/1 HTTP/1.1" 500 -

Answer

If you want to query Todo by primary key and only return one record you can use:

from flask import jsonify

@app.route('/todo/<int:todo_ID>', methods = ['GET'])
def get(todo_ID):
    response = {}
    todo = Todo.query.get(todo_ID)
    response['id'] = todo.id
    response['user_id'] = todo.UserID
    response['details'] = todo.details
    response['status_code'] = 201
    return jsonify(response)

Or you can use Marshmallow to have a serializer for each of your models so it can serialize them for you automatically.