flask using POST, PUT, DELETE - python

I keep getting an error on the url when I try to implement POST in my API. I keep getting the error in the URL saying METHOD not Allowed for this URL. Am I missing something? Does POST not work directly when u try to open the server?? I'm soooo lost.
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)
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('/todo/<int:UserID>', methods = ['GET'])
def get(UserID):
return (list[Todo.query.get(UserID)])
#app.route('/p/', methods = ['POST'])
def create_dev():
if not request.json or not 'name' in request.json:
abort(400)
dev = Todo(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()

You should add GET method to list of allowed methods. When You try to load page, You first need to get page itself using GET method. Then, after filling something on the page, You use POST method to pass some data to the app. In the app, You should check with which method function is called. Something like this:
#app.route('/p', methods=['GET', 'POST'])
def create_dev():
if request.method == 'GET':
return render_template('p_page.html')
# If You get to this line, it means it is POST method
do_something_here()

Related

Why i am getting UnboundLocalError in Flask?

this is my app.py code but i am receiving unbound local error after adding another path for delete and creating the function delete.
from crypt import methods
from email.policy import default
from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Todo(db.Model):
sno = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
desc = db.Column(db.String(200), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self) -> str:
return f"{self.sno} - {self.title}"
#app.route('/', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
title = request.form["title"]
desc = request.form["desc"]
todo = Todo(title=title, desc=desc)
db.session.add(todo)
db.session.commit()
mytodo = Todo.query.all()
return render_template('index.html', mytodo=mytodo)
#app.route('/delete/<int:sno>')
def delete(sno):
todo = Todo.query.filter_by(sno==sno).first()
db.session.delete(todo)
db.session.commit()
return redirect('/')
if __name__ == "__main__":
app.run(debug=True, port=8000)
Below i've added the screenshot of the errors i am getting even when i just visit the root url.
Problem
If the server receive a GET /, then you won't define te title variable, but would try to use it at Todo(title=title, desc=desc) so an error
Fix
All the creation code should be in the if POST branch
#app.route('/', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
title = request.form["title"]
desc = request.form["desc"]
todo = Todo(title=title, desc=desc)
db.session.add(todo)
db.session.commit()
mytodo = Todo.query.all()
return render_template('index.html', mytodo=mytodo)

How can i return a database that gets a JSON POST Request in Flask?

I know that my code is not good, i took parts of codes and try to work them together, but i get this error:
temp = data['temp']
TypeError: 'NoneType' object is not subscriptable
I want to send a POST Request and that to go in my database and then to return that database to show on the web. pls help
from flask import Flask, request, jsonify, json
from flask_sqlalchemy import SQLAlchemy
def theform():
return '''<form method="POST" action="/process">
<input type="text" name="temp"
</form>'''
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']=f'sqlite:///site.db'
db=SQLAlchemy(app)
db.init_app(app)
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))
def __repr__(self):
return f"User({'self.firstname'})"
#app.route('/', methods = ['GET','POST'])
def index():
data=request.get_json()
temp = data['temp']
firstname = temp
return jsonify([u.as_dict() for u in User.query.all()])
if __name__ == '__main__':
app.run()

ProgrammingError: (psycopg2.ProgrammingError) can't adapt type 'FileStorage'

I just want to write a filename from data to my model.
How to get filename from filestorage?
I'm using Flask for my web app. I create form that include FileField.
It is important for me to get the same filename.
Form:
class TableForm(FlaskForm):
file = FileField('Add file', validators=[FileAllowed(['xlsx', 'xls', 'csv'])])
submit = SubmitField('Add file')
Model:
class Table(db.Model):
__table_args__= {'schema': 'app'}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(240), nullable=False)
table_file = db.Column(db.String(80), nullable=False)
Routes:
#app.route("/projects/<int:project_id>", methods=['GET', 'POST'])
#login_required
def project_data_source(project_id):
tables = Table.query.filter_by(project_id=project_id)
if project.author != current_user:
abort(403)
form = TableForm()
if form.validate_on_submit():
table = Table(name=form.file.data, table_file=form.file.data)
db.session.add(table)
db.session.commit()
return redirect(url_for('project_data_source'))
There's a pretty good example on their docs. Here's how you get the file name:
from werkzeug.utils import secure_filename
f = form.file.data
filename = secure_filename(f.filename)
So your code would need to be:
from werkzeug.utils import secure_filename
#app.route("/projects/<int:project_id>", methods=['GET', 'POST'])
#login_required
def project_data_source(project_id):
tables = Table.query.filter_by(project_id=project_id)
if project.author != current_user:
abort(403)
form = TableForm()
if form.validate_on_submit():
filename = secure_filename(form.file.data.filename)
table = Table(name=filename, table_file=filename) # not sure why you save it twice here
db.session.add(table)
db.session.commit()
return redirect(url_for('project_data_source'))

HTTP/1.0 500 INTERNAL SERVER ERROR in flask

I have written a CRUD API in flask but whenever I try to make a GET request, I get this error saying "internal server error". POST requests are also not working for me. POST return a 400 error saying that it is a bad request. What am I doing wrong here?
Following is my run.py file
from flask import Flask, jsonify, abort, request
from flask_restless import APIManager
from flask_sqlalchemy import SQLAlchemy
from flask import make_response
app = Flask(__name__)
app.config.from_pyfile('config.py')
db = SQLAlchemy(app)
class User(db.Model):
username = db.Column(db.String(50), primary_key=True)
password = db.Column(db.String(50))
name = db.Column(db.String(20))
def __init__(self, name, uname, pword):
self.username = uname
self.name = name
self.password = pword
#app.route('/api/users/', methods = ['GET'])
def index():
return jsonify({'users': User.query.all()})
#app.route('/api/<string:username>/')
def get_user(username):
return jsonify({'users': User.query.get(username)})
#app.errorhandler(404)
def not_found(error):
return make_response(jsonify({'error': 'Not found'}), 404)
#app.route('/api/users/', methods = ['POST'])
def create_user():
if not request.json or not 'name' in request.json:
abort(400)
user = User(request.json.username, request.json.get('name', ''), request.json.get('password',''))
db.session.add(user)
db.session.commit()
return jsonify( { 'User': user } ), 201
#app.route('/api/users/<string:username>', methods = ['DELETE'])
def delete_user(username):
db.session.delete(Users.query.get(username))
db.session.commit()
return jsonify( { 'result': True } )
#app.route('/api/users/<string:username>', methods = ['PUT'])
def update_user(username):
user = User.query.get(username)
user.username = request.json.get('username', ser.username)
user.name = request.json.get('name',user.name)
user.focus = request.json.get('password', user.password)
db.session.commit()
return jsonify( { 'user': user } )
if __name__ == '__main__':
app.run()
Following is my config.py file
import os
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.sqlite')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
What am I doing wrong here? Any help would be highly appreciated.
You need to 'create' the User table after you define its class, otherwise it doesn't show up in memory. http://flask-sqlalchemy.pocoo.org/2.1/api/#flask.ext.sqlalchemy.SQLAlchemy.create_all
The way to do it is:
class User(db.Model):
username = db.Column(db.String(50), primary_key=True)
password = db.Column(db.String(50))
name = db.Column(db.String(20))
def __init__(self, name, uname, pword):
self.username = uname
self.name = name
self.password = pword
db.create_all()
...the rest of your code

flask can't connect sqlalchemy

I want to connect sql using sqlalchemy on flask
but it can't
there is a error
sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (1049, "Unknown database 'alchemy_new'")
I can't solve this problem.
# -*- coding:utf-8 -*-
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restful import reqparse, abort, Api, Resource
app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:12345#localhost/catchat'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
password = db.Column(db.String(120), unique=True)
def __init__(self, username, email, password):
self.username = username
self.email = email
self.password = password
def __repr__(self):
return '<User %r>' % self.username
user_inf = {'user1' : {'username':'jaeyeonkim','email':'jaeyeon93#naver.com', 'password':'12345'}}
def not_exist(user_id):
if user_id not in user_inf:
abort(404, message="{} does not exist".format(user_id))
parser = reqparse.RequestParser()
parser.add_argument('username')
parser.add_argument('email')
parser.add_argument('password')
class user(Resource):
def get(self, user_id):
not_exist(user_id)
return user_inf[user_id]
def delete(self,user_id):
not_exist(user_id)
del user_inf[user_id]
return '', 200
def put(self,user_id):
args = parser.parse_args()
not_exist(user_id)
a = {}
a['username'] = args['username']
a['email'] = args['email']
a['password'] = args['password']
user_inf[user_id] = a
return a, 200
class userlist(Resource):
def get(self):
return user_inf
def post(self):
args = parser.parse_args()
new_user = user_inf(args['username'], args['email'], args['password'])
new_user_id = db.session.add(new_user)
db.session.commit()
return new_user_id, 200
api.add_resource(userlist, '/users')
api.add_resource(user,'/api/v1/users/<user_id>')
if __name__ == '__main__':
app.run(debug=True)
First of all I have no idea why password shall be unique ;)
Secondly it looks like sqlalchemy doesn't recognize you connection string.
Try:
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql:////root:12345#localhost/catchat'
According to the following codeļ¼š
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:12345#localhost/catchat'
Your database is 'catchat'.Please create it.
mysql -u root -p12345
create database catchat;
And create table before use it.
db.create_all()
Finally, just a suggestion: don't use flask-restful to define api, please choose
#app.route("/user", methods=["GET"]), it is simple, easy and useful.
Trust me. Two weeks ago, I just rewrite my code from flask-restful to app.route.

Categories

Resources