flask can't connect sqlalchemy - python

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.

Related

Python Flask LDAP connect user with sAMAccountname

I am developing a web app and trying to connect our company users through our AD using there sAMAccountname as they are used to. So far, I can connect users with their DistinguishedName but I can't find the way to do it with the sAMAccountname, any clue ?
in my init.py I have :
app.config['SQLALCHEMY_DATABASE_URI'] = 'connection_to_db'
app.config['SECRET_KEY'] = 'secret_key'
# The Attribute you want users to authenticate to LDAP with.
app.config['LDAP_USER_LOGIN_ATTR'] = 'sAMAccountName'
app.config['LDAP_PROVIDER_URL'] = 'connection_to_ldap'
app.config['LDAP_PROTOCOL_VERSION'] = 3
db = SQLAlchemy(app)
and in my models.py I have :
def get_ldap_connection():
conn = ldap.initialize(app.config['LDAP_PROVIDER_URL'])
return conn
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100))
def __init__(self, username, password):
self.username = username
#staticmethod
def try_login(username, password):
conn = get_ldap_connection()
res = conn.simple_bind_s(
'CN=%s,DC=example,DC=com' % username,
password
)
# conn.unbind()
print(res)
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return str(self.id)
Thanks in advance

Receiving 'TypeError' when attempting to import and create a db using SQLAlchemy

I have started work on a project and have decided before I get too deep to get my ORM sorted out (this means going back over and re writing my classes). I believe my code is correct but I am getting a 'TypeError' whenever I try to create the database schema using Python. I load up the Python console whilst in my project directory, and type 'from app import db' which works fine. After the command 'db.create_all()' (which worked using a basic example) I am thrown the error:
'File
"C:\Users\owner\AppData\Local\Programs\Python\Python38-32\lib\site-packages\sqlalchemy\dialects\mysql\base.py",
line 2016, in visit_VARCHAR
return self._extend_string(type_, {}, "VARCHAR(%d)" % type_.length) TypeError: %d format: a number is required, not type'
I am given no clue as to where in my actual code the cause could be, and am at a total loss.
Any help would be great - a lot of code is commented out and some other code left in for now as I'm in the process of adding my ORM but it was implemented without SQLAlchemy initially. Below is my code for 'init.py':
from flask import Flask, render_template, url_for, flash, redirect, g, request, session, send_from_directory, send_file
from heychef.config import Config
from flask_sqlalchemy import SQLAlchemy
import os
import bcrypt
import uuid
import json
import ssl
from datetime import datetime
from datetime import timedelta
from heychef.models.Agency import Agency
from heychef.models.User import User
from heychef.models.Shift import Shift
from flaskext.mysql import MySQL
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
from heychef.models.Agent import Agent
#app.before_request
def before_request():
g.agent = None
g.agency = None
if 'agent' in session:
g.agent = session['agent']
if 'agency' in session:
g.agency = session['agency']
##########################################################
############# Agent Routes ################
##########################################################
#app.route("/")
def home():
return render_template('agent-views/signup.html'), 200
#app.route("/agent-signup", methods = ['POST', 'GET'])
def agentSignup():
if request.method == 'POST':
email = request.form['inputEmail']
firstName = request.form['inputFirstName']
secondName = request.form['inputSecondName']
password = request.form['inputPassword']
rPassword = request.form['inputConfirmPassword']
if(password != rPassword):
flash('Passwords do not match.', 'danger')
return render_template('agent-views/signup.html')
else:
hashedPwd = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
agent = Agent(firstName, secondName, email, hashedPwd)
agent.addAgent(self)
flash('Account created, you can log in now.', 'success')
return render_template('agent-views/signup.html')
#app.route("/agent-login", methods = ['POST','GET'])
def agentLogin():
if request.method == 'POST':
session.pop('agent', None)
email = request.form['inputEmail']
pwd = request.form['inputPassword']
connection = mysql.get_db()
cursor = connection.cursor()
result, msg = Agent.agentLogin(connection, cursor, email, pwd)
if(result):
session['agent'] = email
flash(msg, 'success')
return redirect(url_for('agentDashboard'))
else:
flash(msg, 'danger')
return render_template('agent-views/login.html')
else:
return render_template('agent-views/login.html')
#app.route("/agent-dashboard", methods = ['GET'])
def agentDashboard():
if g.agent:
return render_template('agent-views/dashboard.html'), 200
else:
msg = "Please log in"
flash(msg, 'warning')
return redirect(url_for('agentLogin'))
if __name__ == "__main__":
app.run()
and here is my Agent Class:
from heychef.models.User import User
#from heychef.models.data.AgentDb import AgentDb
from heychef import db
class Agent(db.Model):
agentId = db.Column(db.Integer, unique=True, nullable=False, primary_key=True)
firstName = db.Column(db.String(80), unique=False, nullable=False, primary_key=False)
secondName = db.Column(db.String(80), unique=False, nullable=False, primary_key=False)
email = db.Column(db.String(80), unique=False, nullable=False, primary_key=False)
level = db.Column(db.String(80), unique=False, nullable=True, primary_key=False)
agencyId = db.Column(db.Integer, unique=False, nullable=True, primary_key=False)
addressLine1 = db.Column(db.String(80), unique=False, nullable=True, primary_key=False)
addressLine2 = db.Column(db.String(80), unique=False, nullable=True, primary_key=False)
addressLine3 = db.Column(db.String(80), unique=False, nullable=True, primary_key=False)
postcode = db.Column(db.String(20), unique=False, nullable=True, primary_key=False)
passwordHash = db.Column(db.String(256), unique=False, nullable=False, primary_key=False)
def __repr__(self):
return "<Agent(firstName='%s', lastName='%s')>" % (self.firstName, self.lastName)
def __init__(self, firstName, secondName, email, hashedPwd):
self.agentId = 1001
self.firstName = firstName
self.secondName = secondName
self.email = email
self.passwordHash = hashedPwd
#staticmethod
def agentEmailExists(cursor, email):
exists = AgentDb.agentEmailExistsDb(cursor, email)
return exists
#staticmethod
def addAgent(agent):
db.session.add(self)
db.session.commit()
#staticmethod
def agentLogin(connection, cursor, email, pwd):
failMsg = 'Email or Password does not match.'
successMsg = 'Successfully logged in.'
result = AgentDb.agentLoginDb(connection, cursor, email, pwd)
if(result):
msg = successMsg
else:
msg = failMsg
return result, msg
#staticmethod
def getWork(cursor):
work = AgentDb.getWorkDb(cursor)
return work
any help would be ace as I'm really struggling!
Many thanks
The error seems to be related to a VARCHAR (String)db column and points out that it has received a Non-Integer value ,so there might be a db.string() model field with a Non-Integer or empty parenthesis in the other model Classes in your project.

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

Getting Logged in User Info in Flask using LDAP

I am trying to find a way to retrieve information such as 'mail', 'displayName', 'telephoneNumber' from an LDAP authenticated/logged in user in Flask.
My user can successfully authenticate and log in using LDAP. However how would I be able to get additional information about the user?
I am using standard python-ldap and flask-login modules and I'm trying to create a string variable for these attributes so I can call on them later in the session. When trying to run the query I am getting ldap.FILTER_ERROR: {'desc': u'Bad search filter'} . Any ideas on how to get this working?
class UserInfo():
def whoami(username, password):
conn = get_ldap_connection()
conn.simple_bind_s(username,password)
basedn = 'OU=...,OU=...,DC=...,DC=...'
userfilter = "(|(SamAccountName=\*" + username + "\*)"
userattribute = ['displayName']
userresults = conn.search_s(basedn,ldap.SCOPE_SUBTREE,userfilter, userattribute)
userinfos = UserInfo()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100))
def __init__(self, username, password):
self.username = username
#staticmethod
def try_login(username, password):
conn = get_ldap_connection()
conn.simple_bind_s(domain+username, password)
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return unicode(self.id)
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
#app.before_request
def get_current_user():
g.user = current_user
I needed to use ldap.filter.filter_format for proper character escaping.
import ldap.filter
criteria= ldap.filter.filter_format('(&(objectClass=user)(sAMAccountName=%s))', [username])

Why is check_password_hash always returning False in this login view?

I have a user model with functions to set and check a password using Werkzeug's set_password_hash and check_password_hash functions.
models.py
class User(db.Model):
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(15), unique = True)
password = db.Column(db.String(15))
tasks = db.relationship('Task', backref='author', lazy='dynamic')
def __init__(self, username, password):
self.username = username
self.set_password(password)
def set_password(self, password):
self.password = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password, password)
login.py
def post(self):
username = flask.request.form['username']
passwd = flask.request.form['passwd']
user = User.query.filter_by(username = username).first()
flask.flash(user.check_password(user.password))
if user and user.check_password(user.password):
flask.session['username'] = username
else:
flask.flash("User doesn't exist or password is inccorect.")
return flask.render_template('login.html')
return flask.render_template('index.html')
The flashed result of check_password is always "False". What am I doing wrong?
You've defined User.password to have a length of 15, but the password hash is longer than 15 characters. So when you go to compare it later, it will not be the same value, it will be truncated.
The solution is to either define a longer length to accommodate the length of the hash, or use a database that doesn't care about length (PostgreSQL, SQLite) and don't set a length for the column at all (this is preferable).
password = db.Column(db.String) # no length
# or
password = db.Column(db.String(255)) # some longer length
There's also a second problem: you're calling check_password with the stored hash, not with the user input.
# wrong
user.check_password(user.password)
# should be
user.check_password(passwd)
The following is a small example that demonstrates the password working correctly.
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session
from werkzeug.security import generate_password_hash, check_password_hash
engine = sa.create_engine('sqlite://', echo=True)
session = Session(engine)
Base = declarative_base(engine)
class User(Base):
__tablename__ = 'user'
id = sa.Column(sa.Integer, primary_key=True)
username = sa.Column(sa.String, nullable=False, unique=True)
password = sa.Column('password', sa.String)
def set_password(self, secret):
self.password = generate_password_hash(secret)
def check_password(self, secret):
return check_password_hash(self.password, secret)
Base.metadata.create_all()
u = User(username='davidism')
u.set_password('cabbage')
session.add(u)
session.commit()
u = session.query(User).filter_by(username='davidism').one()
print(u.password)
# pbkdf2:sha1:1000$w9jx4Egp$b420d784ac6ad0575e4a9a908bb4679826e56f5f
print(u.check_password('cabbage'))
# True

Categories

Resources