Flask server not working properly with CodernityDB - python

I'm trying to complete the Flask tutorial between this and this to have something very simple using CodernityDB instead of sqllite, and I need to execute the app to be able to study all the CodernityDB methods I need. But the server is not working properly, the localhost tell me there is an Internal error, but I can't figure out the way to debug it.
Here is my code (flaskr.py), the templates are here:
from __future__ import with_statement
from flask import Flask, request, session, g, redirect, url_for, \
abort, render_template, flash
from CodernityDB.database_thread_safe import ThreadSafeDatabase
from CodernityDB.database import RecordNotFound
# configuration
DATABASE = '/tmp/flaskr.db'
DEBUG = True
SECRET_KEY = 'development key'
# pending
USER = 'admin'
PASSWORD = 'default'
app = Flask(__name__)
##app.config.from_object(__name__)
cdb = ThreadSafeDatabase(DATABASE)
if cdb.exists():
cdb.open()
cdb.reindex()
else:
from database_indexes import WithXIndex
cdb.create()
cdb.add_index(WithXIndex(cdb.path, 'x'))
#app.before_request
def before_request():
g.db = cdb
#app.route('/')
def show_entries():
## return "Hello World! This is powered by Python Backend."
cur = db.get('x',10,with_doc=True)
entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
return render_template('show_entries.html', entries=entries)
#app.route('/add', methods=['POST'])
def add_entry():
## return "Add new entry"
if not session.get('logged_in'):
abort(401)
g.db.insert(dict(x=request.form['title'], name=request.form['text']))
flash('New entrey was succesfully posted')
return redirect(url_for('show_entries'))
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']:
error = 'Invalid password'
else:
session['logged_in'] = True
flash('You were logged in')
return redirect(url_for('show_entries'))
return render_template('login.html', error=error)
#app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
if __name__ == '__main__':
app.run()
## app.run(host='0.0.0.0')
## app.run(debug= True)
## app.run(host='127.0.0.1', port=5000)
database_indexes.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from CodernityDB.hash_index import HashIndex
from CodernityDB.tree_index import TreeBasedIndex
from hashlib import md5
class WithXIndex(HashIndex):
def __init__(self, *args, **kwargs):
kwargs['key_format'] = 'I'
super(WithXIndex, self).__init__(*args, **kwargs)
def make_key_value(self, data):
a_val = data.get("x")
if a_val is not None:
return a_val, None
return None
def make_key(self, key):
return key
I didn't create the environment variable because I want to use another approach for the configuration, maybe a file, and the config.from_object is commented because when I executed it with it shows Restarting with stat.

Related

Authentication in Flask application using dictionary database structure

I am creating a basic application to demonstrate the register and login activities in Flask using sessions. For the below code, each user available in the dictionary should be able to login. However, the application only accepts the login for the first user named 'Mary'. I don't understand where did it went wrong.
from flask import Flask, app, session, render_template, request,redirect, url_for, jsonify
app = Flask(__name__)
app.config['SECRET_KEY'] = "Zd9TUg1aE03bHc28"
#app.route('/')
def load():
return render_template("authusers.html")
class Mydatabase:
appdb=[{'username':'Mary','password':'Password#123'},
{'username':'John','password':'Password#456'},
{'username':'Tara','password':'Password#789'}]
mydbusers=Mydatabase()
#app.route('/login',methods = ['GET','POST'])
def success():
if request.method == "POST":
username_val = request.form['user_id']
userpassword_val = request.form['user_password']
for authuser in Mydatabase.appdb:
for authpassword in authuser.values():
if authuser['username'] == username_val and authpassword['password'] == userpassword_val:
session['reg_user'] = username_val
return f'{session.get("reg_user")} have successfully logged into the application';
else:
return redirect(url_for('register'))
#app.route('/logout', methods=['GET','POST'])
def logout():
if 'reg_user' in session:
session.pop('reg_user',None)
return render_template("authusers.html")
#app.route('/register', methods=['GET','POST'])
def register():
return render_template('register.html')
#app.route('/reg_success',methods=['GET','POST'])
def reg_success():
newusercred={'username':request.form['user_id'], 'password':request.form['user_password']}
mydbusers.appdb.append(newusercred)
# return jsonify(Mydatabase.appdb)
return render_template("authusers.html")
if __name__=="__main__":
app.run(debug=True)
I see some logical issue in your code
Try like this ->
class Mydatabase:
appdb=[{'username':'Mary','password':'Password#123'},
{'username':'John','password':'Password#456'},
{'username':'Tara','password':'Password#789'}]
username_val = 'Tara'
userpassword_val = 'Password#789'
d = [a for a in Mydatabase.appdb if a["username"] == username_val and a["password"]==userpassword_val]
if d:
print(f'have successfully logged into the application')
else:
print(f'Wrong credentials')
There are some unwanted loops in your code, and you do return even in the else of part.

How to integrate login required decorator to flask routes with a static user ID and password?

I am new to flask and python, i am trying to add login required and all routes other than home page. I read about flask-login module, haven't had any success. Looking for suggestions !
I tried using flask-login and prevent access of "/data" route. It did not work. My login requirement is very simple, allow login if user pass is admin/admin. And make sure the user is logged in for all subsequent routes.
Here is my flask code
from flask import Flask, render_template, redirect, url_for, request
import subprocess
import os
import datetime
import time
app = Flask(__name__)
#app.route("/")
def home():
now = datetime.datetime.now()
timeString = now.strftime("%Y-%m-%d %H:%M")
templateData = {
'title' : 'HELLO!',
'time': timeString
}
return render_template('main.html', **templateData)
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = 'Invalid Credentials. Please try again.'
else:
return redirect(url_for('data'))
return render_template('login.html', error=error)
#app.route("/data")
def data():
now = datetime.datetime.now()
timeString = now.strftime("%Y-%m-%d %H:%M")
templateData = {
'title' : 'HELLO!',
'time': timeString
}
return render_template('api.html', **templateData)
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
I dont want /data route to be accessed without login as admin/admin
flask_login should do the trick.
import and use the '#login_required' decorator on any route that you want to make unavailable to users who aren't currently logged in.
from flask_login import login_required
#app.route("/data")
#login_required
def data():
...
...
leave the decorator off of any routes that don't require login.
since you only have need for generic authentication you might look into session login.
for this, you'll need a secret key...
import secrets
app = Flask(__name__)
app.config['SECRET_KEY'] = secrets.token_hex(16)
and an example usage of flask session management.
from flask import session
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = 'Invalid Credentials. Please try again.'
else:
session['logged_in'] = True
return redirect(url_for('data'))
return render_template('login.html', error=error)

Flask server doesn't render bokeh charts in remote

I have the following code to run a Flask server:
import os
from flask import Flask, url_for, request, render_template, redirect, flash, session
from bokeh.embed import autoload_server
from bokeh.client import pull_session
app = Flask(__name__)
#app.route('/login', methods = ['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if valid_login(request.form['username'], request.form['password']):
flash("Succesfully logged in")
session['username'] = request.form.get('username')
return redirect(url_for('welcome'))
else:
error = 'Incorrect username and password'
return render_template('login.html', error = error)
#app.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('login'))
def valid_login(username, password):
if username == password:
return True
else:
return False
#app.route('/')
def welcome():
if 'username' in session:
return render_template('welcome.html', username = session['username'])
else:
return redirect(url_for('login'))
#app.route('/Gapminder')
def gapminder():
if 'username' in session:
sessione = pull_session(app_path = "/main")
bokeh_script = autoload_server(None, app_path = "/main", session_id=sessione.id)
return render_template("gapminder.html", bokeh_script = bokeh_script)
else:
return redirect(url_for('login'))
if __name__ == '__main__':
host = os.getenv('IP', 'locahost')
port = int(os.getenv('PORT', 5000))
app.debug = True
app.secret_key = '\xc9ixnRb\xe40\xd4\xa5\x7f\x03\xd0y6\x01\x1f\x96\xeao+\x8a\x9f\xe4'
app.run(host = host, port = port)
I run the bokeh server chart with
bokeh serve main.py --allow-websocket-origin=localhost:5000 --host *
and the flask server with
python run_flask.py
Well, I can see the bokeh reder in my local enviroment at the address
localhost:5006/main
and also the flask web page with the bokeh chart, also rendered and working ok at
localhost:5000
The problem is when I try to access fro another machine in the same local network. I can see the bokeh render chart at
ip:5006/main.
The flask web page
ip:5000
is also ok except the bokeh renderer, I can't see it.
can you help me please? Thanks a lot.

TypeError: __call__() got an unexpected keyword argument 'mimetype' [duplicate]

I have built a website using flask (www.csppdb.com). Sometimes when I log in as one user, log out, then login as another user I still see pages from the first user I logged in as. This problem is immediately fixed when the page is refreshed. I think this is called "caching" if I am not mistaken. Is there any way I could disable this on a site wide level so that every page that is visited needs a new refresh?
It would be like sharing your computer with a friend. He logs into Facebook, then logs out. Now you log in on his computer and you see his profile... (awkward). After you refresh the page the problem is fixed.
Here is some of my code. I was using flask-login but I then tried to "roll my own"
from flask.ext.mysql import MySQL
import os
from flask import Flask, request, jsonify, session, url_for, redirect, \
render_template, g, flash
from data import *
from werkzeug import check_password_hash, generate_password_hash
import config
app = Flask(__name__)
mysql = MySQL()
app.config['MYSQL_DATABASE_HOST'] = os.environ['MYSQL_DATABASE_HOST'] if 'MYSQL_DATABASE_HOST' in os.environ else config.MYSQL_DATABASE_HOST
app.config['MYSQL_DATABASE_PORT'] = os.environ['MYSQL_DATABASE_PORT'] if 'MYSQL_DATABASE_PORT' in os.environ else config.MYSQL_DATABASE_PORT
app.config['MYSQL_DATABASE_USER'] = os.environ['MYSQL_DATABASE_USER'] if 'MYSQL_DATABASE_USER' in os.environ else config.MYSQL_DATABASE_USER
app.config['MYSQL_DATABASE_PASSWORD'] = os.environ['MYSQL_DATABASE_PASSWORD'] if 'MYSQL_DATABASE_PASSWORD' in os.environ else config.MYSQL_DATABASE_PASSWORD
app.config['MYSQL_DATABASE_DB'] = os.environ['MYSQL_DATABASE_DB'] if 'MYSQL_DATABASE_DB' in os.environ else config.MYSQL_DATABASE_DB
mysql.init_app(app)
if 'SECRET_KEY' in os.environ: app.config['SECRET_KEY'] = os.environ['SECRET_KEY']
else: app.config['SECRET_KEY'] = os.urandom(24)
def connect_db(): return mysql.connect()
def check_auth():
g.user = None
if 'username' in session:
g.user = get_user(session['username'])
return
return redirect(url_for('login'))
#app.route('/')
def home():
if 'username' in session: return redirect(url_for('main'))
return render_template('home.html')
def connect_db(): return mysql.connect()
#app.teardown_request
def teardown_request(exception):
if exception: print exception
g.db.close()
#app.before_request
def before_request():
print session.keys(), session.values()
print("before request")
print ('username' in session, "in session?")
g.db = connect_db()
g.user = None
if "username" in session:
g.user = get_user(session['username'])
#app.route('/login/', methods=['GET', 'POST'])
def login():
"""Logs the user in."""
if 'username' in session:
return redirect(url_for('main'))
error = None
if request.method == 'POST':
print("login hit")
user = get_user(request.form['username'])
if user is None:
error = 'Invalid username'
print error
elif not check_password_hash(user.password, request.form['password']):
error = 'Invalid password'
print error
else:
flash('You were logged in')
print "logged in"
session['username'] = request.form['username']
g.user = request.form['username']
print error, "error"
return redirect(url_for('main'))
return render_template('login.html', error=error)
Setting the cache to be max-age=0 fixed it.
#app.after_request
def add_header(response):
"""
Add headers to both force latest IE rendering engine or Chrome Frame,
and also to cache the rendered page for 10 minutes.
"""
response.headers['X-UA-Compatible'] = 'IE=Edge,chrome=1'
response.headers['Cache-Control'] = 'public, max-age=0'
return response
To stop browser caching on these sort of pages you need to set some HTTP response headers.
Cache-Control: no-cache, no-store
Pragma: no-cache
Once you do this then the browser wont cache those pages. I dont know how to do this with "flask" so I will leave that as an exercise for you :)
This question shows how to add a response header Flask/Werkzeug how to attach HTTP content-length header to file download

Can't find where sqlite3 database is

I'm folowing Flaskr Tutorial (http://flask.pocoo.org/docs/tutorial/setup/) and missunderstand one thing:
Both aplication that I did and the original Flaskr from github (https://github.com/mitsuhiko/flask/tree/master/examples/flaskr/) work properly, but I dont see any database files created, even though I manually created '/tm/flaskr.db', this file is still empty.
Please, could you explain me, in what a magic place sqlite3 keeps data?
here is py file that I execute:
# coding: utf-8
import sqlite3
import inspect
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
from contextlib import closing
app = Flask(__name__)
app.config.from_object('config')
def connect_db():
return sqlite3.connect(app.config['DATABASE'])
def init_db():
with closing(connect_db()) as db:
with app.open_resource('schema.sql') as f:
db.cursor().executescript(f.read())
db.commit()
#app.before_request
def before_request():
g.db = connect_db()
#app.teardown_request
def teardown_request(exception):
g.db.close()
#app.route('/')
def show_entries():
cur = g.db.execute('select title, text from entries order by id desc')
entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
return render_template('show_entries.html', entries=entries)
#app.route('/add', methods=['POST'])
def add_entry():
if not session.get('logged_in'):
abort(401)
g.db.execute('insert into entries (title, text) values (?, ?)',
[request.form['title'], request.form['text']])
g.db.commit()
flash('New entry was successfully posted')
return redirect(url_for('show_entries'))
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != app.config['USERNAME']:
error = 'Invalid username'
elif request.form['password'] != app.config['PASSWORD']:
error = 'Invalid password'
else:
session['logged_in'] = True
flash('You were logged in')
return redirect(url_for('show_entries'))
return render_template('login.html', error=error)
#app.route('/logout')
def logout():
session.pop('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
if __name__ == '__main__':
app.run()
here is config file:
# coding: utf-8
DATABASE = '/tmp/site.db'
DEBUG = True
SECRET_KEY = 'dev_key'
USERNAME = 'admin'
PASSWORD = 'pass'
schema.sql
drop table if exists entries;
create table entries (
id integer primary key autoincrement,
title string not null,
text string not null
);
Thanks so much for your answers, I've noticed, that db is created in the '/tmp/'folder in the root of file system. I expected, that it would be created in my project folder like in django with sqlite.
The database will be stored in "/tmp/site.db".
try doing sqlite3 /tmp/site.db
If you want to keep this file in the projects directory just change it to site.db
You need the init_db() to be run seperately just once.
From Python command line import flaskr and run flaskr.init_db()
I would suggest looking at Flaskr and trying to understand it first. The default Flaskr will re-initiated the db every time it is executed.
Joe

Categories

Resources