This is my code for my main.py file which is designed to be a simple contact form built in flask.
from flask import Flask, render_template, request
from flask_mail import Mail, Message
from forms import ContactForm
app = Flask(__name__)
app.secret_key = 'YourSuperSecreteKey'
# add mail server config
app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'YourUser#NameHere'
app.config['MAIL_PASSWORD'] = 'yourMailPassword'
mail = Mail(app)
#app.route('/')
def hello():
"""Return a friendly HTTP greeting."""
return 'Hello World!'
#app.errorhandler(404)
def page_not_found(e):
"""Return a custom 404 error."""
return 'Sorry, Nothing at this URL.', 404
#app.errorhandler(500)
def application_error(e):
"""Return a custom 500 error."""
return 'Sorry, unexpected error: {}'.format(e), 500
#app.route('/contact', methods=('GET', 'POST'))
def contact():
form = ContactForm()
if request.method == 'POST':
if form.validate() == False:
return 'Please fill in all fields <p>Try Again!!!</p>'
else:
msg = Message("Message from your visitor" + form.name.data,
sender='YourUser#NameHere',
recipients=['yourRecieve#mail.com', 'someOther#mail.com'])
msg.body = """
From: %s <%s>,
%s
""" % (form.name.data, form.email.data, form.message.data)
mail.send(msg)
return "Successfully sent message!"
elif request.method == 'GET':
return render_template('contact.html', form=form)
if __name__ == '__main__':
app.run()
I get the error: Sorry, unexpected error: 'module' object has no attribute 'SMTP_SSL'
I've called my file "main.py". Everything works fine until I try and send the actual email. Is this just because I haven't populated the settings or is something else a miss?
Sorry just figured out how to see traceback on GAE:
Exception on /contact [POST]
Traceback (most recent call last):
File "/base/data/home/apps/s~smart-cove-95709/1.384663697853252774/lib/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/base/data/home/apps/s~smart-cove-95709/1.384663697853252774/lib/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/base/data/home/apps/s~smart-cove-95709/1.384663697853252774/lib/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/base/data/home/apps/s~smart-cove-95709/1.384663697853252774/lib/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/base/data/home/apps/s~smart-cove-95709/1.384663697853252774/lib/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/base/data/home/apps/s~smart-cove-95709/1.384663697853252774/main.py", line 50, in contact
mail.send(msg)
File "/base/data/home/apps/s~smart-cove-95709/1.384663697853252774/lib/flask_mail.py", line 491, in send
with self.connect() as connection:
File "/base/data/home/apps/s~smart-cove-95709/1.384663697853252774/lib/flask_mail.py", line 144, in __enter__
self.host = self.configure_host()
File "/base/data/home/apps/s~smart-cove-95709/1.384663697853252774/lib/flask_mail.py", line 156, in configure_host
host = smtplib.SMTP_SSL(self.mail.server, self.mail.port)
AttributeError: 'module' object has no attribute 'SMTP_SSL'
You have set the MAIL_USE_SSL option to True:
app.config['MAIL_USE_SSL'] = True
which means that the Flask-Mail extension will want to use the smtplib.SMTP_SSL class, but that class isn't usually available on Google App Engine.
That class is only available if the Python ssl module is available, which is only the case if your Python was built with SSL support available. This isn't normally the case in the GAE environment.
The module is not available on Google App Engine unless you specifically enable it. Enable it in your app.yaml:
libraries:
- name: ssl
version: latest
Do note that the socket support on GAE is experimental.
For sending email on GAE you are better off using the mail.send_mail() function however, so you can make use of the GAE infrastructure instead.
Related
I have a Flask server that looks like this:
import flask, os, werkzeug.utils
UPLOAD_FOLDER = "files/"
ALLOWED_EXTENSIONS = {"txt"}
def isFileAllowed(file):
return str("." in file and file.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS)
app = flask.Flask(__name__)
app.config["UPLOAD_DIR"] = UPLOAD_FOLDER
#app.route("/log_receiver", methods = ["POST", "GET"])
def log_receiver():
if flask.request.method == "POST":
file = flask.request.files["file"]
if file and isFileAllowed(file):
filename = werkzeug.utils.secure_filename(file)
file.save(os.path.join(app.config["UPLOAD_DIR"], filename))
return "Sucessfully uploaded"
return "File couldn't be uploaded"
return "404, not found"
if __name__ == '__main__':
app.run()
I've made a test uploader, also in Python, that looks like this:
import requests
def log_uploader():
with open("log.txt", "rb") as log:
r = requests.post("http://localhost:5000/log_receiver", files={"log.txt": log})
print(r.text)
if __name__ == '__main__':
log_uploader()
The issue is, whenever I run it, I get a 404 error.
I've tried removing the ["file"] in flask.request.files, which removes the 400 error but brings in a 500 error with the following log:
[2022-11-29 16:05:46,547] ERROR in app: Exception on /log_receiver [POST]
Traceback (most recent call last):
File "/home/day/.local/lib/python3.9/site-packages/flask/app.py", line 2525, in wsgi_app
response = self.full_dispatch_request()
File "/home/day/.local/lib/python3.9/site-packages/flask/app.py", line 1822, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/day/.local/lib/python3.9/site-packages/flask/app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "/home/day/.local/lib/python3.9/site-packages/flask/app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/home/day/Desktop/Coding/Quickraft/Server-side/APIs/main.py", line 17, in log_receiver
filename = werkzeug.utils.secure_filename(file)
File "/home/day/.local/lib/python3.9/site-packages/werkzeug/utils.py", line 221, in secure_filename
filename = unicodedata.normalize("NFKD", filename)
TypeError: normalize() argument 2 must be str, not ImmutableMultiDict
127.0.0.1 - - [29/Nov/2022 16:05:46] "POST /log_receiver HTTP/1.1" 500 -
How could I fix this? Thanks in advance,
Daymons.
See again the flask documentation for request.files
Each value in files is a Werkzeug FileStorage object
It is not just the filename but much more than that. The error message is telling you something: That secure_filename() expects a string, but you are passing it something that isn't a string.
Have a look again at the flask documentation for file uploads: https://flask.palletsprojects.com/en/2.2.x/patterns/fileuploads/
I'm trying to build a simple contact form with Flask and hosting it on GAE but I can't seem to get it right.
I'd truly appreciate your help because I've spent several days trying to figure this out without any success.
Here's the error I get when I click submit:
Internal Server Error
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
And here are the logs:
2022-02-14 23:03:33 default[20220215t000150] Traceback (most recent call last):
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app response = self.full_dispatch_request()
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request rv = self.handle_user_exception(e)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request rv = self.dispatch_request()
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/srv/main.py", line 34, in contact message.send() File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/mail.py", line 1209, in send make_sync_call('mail', self._API_CALL, message, response)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/apiproxy_stub_map.py", line 96, in MakeSyncCall return stubmap.MakeSyncCall(service, call, request, response)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/apiproxy_stub_map.py", line 355, in MakeSyncCall rpc.CheckSuccess()
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/apiproxy_rpc.py", line 149, in CheckSuccess raise self.exception
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/runtime/default_api_stub.py", line 267, in _CaptureTrace f(**kwargs)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/runtime/default_api_stub.py", line 260, in _SendRequest raise self._TranslateToError(parsed_response) File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/runtime/default_api_stub.py", line 134, in _TranslateToError raise self._ErrorException(exception_type, msg) google.appengine.runtime.apiproxy_errors.FeatureNotEnabledError: The API call mail.Send() is currently not enabled. -- Additional details from server: App Engine APIs are not enabled, please add app_engine_apis: true to your app.yaml to enable.
Here's my main.py:
from flask import Flask, redirect, render_template, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
from flask_talisman import Talisman
from google.appengine.api import mail, wrap_wsgi_app
app = Flask(__name__)
app.config['SECRET_KEY'] = 'my-very-very-secret-key'
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
Talisman(app)
EMAIL_ADDR = 'my_email#example.com'
class ContactForm(FlaskForm):
name = StringField(label='Name', validators=[DataRequired()])
submit = SubmitField(label='Submit')
#app.route('/')
def homepage():
return render_template('index.html')
#app.route('/contact', methods=['GET', 'POST'])
def contact():
form = ContactForm()
if form.validate_on_submit():
name = form.name.data
message = mail.EmailMessage(sender=EMAIL_ADDR,
subject='form test')
message.body = f'this is a test message from {name}'
message.to = EMAIL_ADDR
message.send()
return redirect(url_for('homepage'))
return render_template('contact.html', form=form)
if __name__ == '__main__':
app.run()
My app.yaml
runtime: python39
app_engine_apis: true
inbound_services:
- mail
- mail_bounce
My requirements.txt
Flask==2.0.2
flask-talisman==0.8.1
wtforms==3.0.0
Flask-WTF==1.0.0
appengine-python-standard>=0.3.1
I've stumbled upon the solution! If anyone else runs into this issue: 'gcloud beta app deploy' solves it. I used to deploy the app with 'gcloud app deploy' before.
I am trying to make a chat app which is linked with a database which stores the users username and password but i would like to call the username in multiple functions. I currently have a global variable which is called NAME_KEY and i would like to replace it with the username of which ever user is logged in.
Here is my code as it currently stands!
from flask import render_template, redirect, session, request, url_for, jsonify, flash, Blueprint
from .database import DataBase
from flask_mysqldb import MySQL
from flask_socketio import SocketIO
import bcrypt
import MySQLdb
from config import *
view = Blueprint("views", __name__)
# GLOBAL CONSTANTS
NAME_KEY = 'username'
MSG_LIMIT = 20
socketio = SocketIO(app) # used for user communication
db = MySQL(app)
password = b"1234"
hashed = bcrypt.hashpw(password, bcrypt.gensalt())
# VIEWS
#view.route("/login", methods=["POST", "GET"])
def login():
"""
displays main login page and handles saving name in session
:exception POST
:return: None
"""
if request.method == 'POST':
if 'username' in request.form and 'password' in request.form:
username = request.form.get('username')
password = request.form.get('password').encode("utf-8")
cursor = db.connection.cursor(MySQLdb.cursors.DictCursor)
cursor.execute("SELECT * FROM logininfo WHERE email=%s AND password=%s", (username, password))
info = cursor.fetchone()
if info is not None:
if bcrypt.checkpw(password, hashed):
session['loginsuccess'] = True
flash(f'You were successfully logged in as {username}.')
return redirect(url_for('views.home'))
else:
flash("Profile doesn't exist please try again!")
return render_template("login.html", **{"session": session})
#view.route('/new/', methods=['GET', 'POST'])
def new_user():
if request.method == "POST":
if "one" in request.form and "two" in request.form and "three" in request.form:
username = request.form['one']
email = request.form['two']
password = request.form['three']
cur = db.connection.cursor(MySQLdb.cursors.DictCursor)
cur.execute("INSERT INTO login.logininfo(name, password, email)VALUES(%s, %s, %s)",
(username, password, email))
db.connection.commit()
return redirect(url_for('login'))
return render_template("register.html")
#view.route("/logout")
def logout():
"""
logs the user out by popping username from session
:return: None
"""
session.pop(NAME_KEY, None)
flash("0You were logged out.")
return redirect(url_for("views.login"))
#view.route("/")
#view.route("/home")
def home():
"""
displays home page if logged in
:return: None
"""
if NAME_KEY not in session:
return redirect(url_for("views.login"))
return render_template("index.html", **{"session": session})
#view.route("/history")
def history():
if NAME_KEY not in session:
flash("0Please login before viewing message history")
return redirect(url_for("views.login"))
json_messages = get_history(session[NAME_KEY])
print(json_messages)
return render_template("history.html", **{"history": json_messages})
#view.route("/get_name")
def get_name():
"""
:return: a json object storing name of logged in user
"""
data = {"name": ""}
if NAME_KEY in session:
data = {"name": session[NAME_KEY]}
return jsonify(data)
#view.route("/get_messages")
def get_messages():
"""
:return: all messages stored in database
"""
db = DataBase()
msgs = db.get_all_messages(MSG_LIMIT)
messages = remove_seconds_from_messages(msgs)
return jsonify(messages)
#view.route("/get_history")
def get_history(name):
"""
:param name: str
:return: all messages by name of user
"""
db = DataBase()
msgs = db.get_messages_by_name(name)
messages = remove_seconds_from_messages(msgs)
return messages
Currently this line of code is throwing an error
'cursor = db.connection.cursor(MySQLdb.cursors.DictCursor)'
The error is as follows
"KeyError: 'MYSQL_HOST'"
I also have no idea how to go about replacing the global variable NAME_KEY with one that takes which ever user is signed up and stored in my database.
I also have a config file which is as follows
from dotenv import load_dotenv
from pathlib import Path # python3 only
import os
from flask import Flask
# set path to env file
env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)
app = Flask(__name__)
class Config:
"""Set Flask configuration vars from .env file."""
# Load in environment variables
TESTING = os.getenv('TESTING')
FLASK_DEBUG = os.getenv('FLASK_DEBUG')
SECRET_KEY = os.getenv('SECRET_KEY')
SERVER = os.getenv('SERVER')
app.config["MYSQL_HOST"] = "login#localhost"
app.config["MYSQL_USER"] = "root"
app.config["MYSQL_PASSWORD"] = "pleasehelp"
app.config["MYSQL_DB"] = "login"
Any help or suggestions would be greatly appreciated.
Here are my errors
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask_socketio\__init__.py", line 46, in __call__
start_response)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\engineio\middleware.py", line 71, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\User\PycharmProjects\testApp\testApp\application\views.py", line 40, in login
cursor = db.connection.cursor(MySQLdb.cursors.DictCursor)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask_mysqldb\__init__.py", line 94, in connection
ctx.mysql_db = self.connect
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\flask_mysqldb\__init__.py", line 43, in connect
if current_app.config['MYSQL_HOST']:
KeyError: 'MYSQL_HOST'
I'm using flask-security to handle user registration, login, etc. I'm facing a problem when registering a new user using the default flask-security views.
EDIT
I managed to advance a little on solving the problem. The initial problem was that I wasn't providing a load_user callback. Now I'm doing it:
#login_manager.user_loader
def load_user(user_id):
return User.objects.get(id=user_id)
Problem is that the confirmation url/view seems to use an AnonymousUser and so, the query filter does not match the correct user. Any clues guys?
Original
I'm able to provide user mail and password in the registration view, I successfully receive a confirmation e-mail (the default template provided by flask-security) but when I try to confirm the account clicking on the mail confirmation link I get the following attribute error:
AttributeError: 'AnonymousUserMixin' object has no attribute 'roles'
Here is the full traceback:
Traceback (most recent call last):
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site- packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask_security/views.py", line 226, in confirm_email
logout_user()
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask_security/utils.py", line 92, in logout_user
identity=AnonymousIdentity())
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/blinker/base.py", line 267, in send
for receiver in self.receivers_for(sender)]
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask_principal.py", line 469, in _on_identity_changed
self.set_identity(identity)
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask_principal.py", line 418, in set_identity
self._set_thread_identity(identity)
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask_principal.py", line 463, in _set_thread_identity
identity=identity)
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/blinker/base.py", line 267, in send
for receiver in self.receivers_for(sender)]
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/flask_security/core.py", line 217, in _on_identity_loaded
for role in current_user.roles:
File "/home/infante/PycharmProjects/venvs/wp/lib/python2.7/site-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
AttributeError: 'AnonymousUserMixin' object has no attribute 'roles'
Here is my app configuration:
from flask import Flask
from flask.ext.security import MongoEngineUserDatastore, Security
from flask_login import LoginManager
from flask_mail import Mail
from wpapp.models import db, User, Role
from wpapp.views import frontend
from wpapp.configs import CONFS
login_manager = LoginManager()
app = Flask(__name__)
app.config["MONGODB_SETTINGS"] = CONFS['MONGODB_SETTINGS']
app.config["SECRET_KEY"] = CONFS['SECRET_KEY']
app.config['SECURITY_PASSWORD_HASH'] = CONFS['SECURITY_PASSWORD_HASH']
app.config['SECURITY_PASSWORD_SALT'] = CONFS['SECURITY_PASSWORD_SALT']
app.config['SECURITY_REGISTERABLE'] = CONFS['SECURITY_REGISTERABLE']
app.config['SECURITY_CONFIRMABLE'] = CONFS['SECURITY_CONFIRMABLE']
app.config['SECURITY_RECOVERABLE'] = CONFS['SECURITY_RECOVERABLE']
app.config['SECURITY_REGISTER_URL'] = CONFS['SECURITY_REGISTER_URL']
app.config['MAIL_SERVER'] = CONFS['MAIL_SERVER']
app.config['MAIL_PORT'] = CONFS['MAIL_PORT']
app.config['MAIL_USE_SSL'] = CONFS['MAIL_USE_SSL']
app.config['MAIL_USERNAME'] = CONFS['MAIL_USERNAME']
app.config['MAIL_PASSWORD'] = CONFS['MAIL_PASSWORD']
mail = Mail(app)
app.register_blueprint(frontend)
db.init_app(app)
user_datastore = MongoEngineUserDatastore(db, User, Role)
security = Security(app, user_datastore)
login_manager.init_app(app)
if __name__ == '__main__':
app.run()
And here are my models definitions (I'm using mongodb):
from flask.ext.mongoengine import MongoEngine
from flask.ext.security import UserMixin, RoleMixin
db = MongoEngine()
class Role(db.Document, RoleMixin):
name = db.StringField(verbose_name=u"Nome",
help_text=u"Inserir um nome para identificação do Papel.",
max_length=50,
required=True,
unique=True)
description = db.StringField(verbose_name=u"Descrição",
help_text=u"Inserir descrição sucinta sobre o Papel.",
max_length=255)
class User(db.Document, UserMixin):
email = db.StringField(verbose_name=u"E-mail",
help_text=u"Cadastrar um e-mail válido.",
max_length=255,
required=True,
unique=True)
password = db.StringField(verbose_name=u"Senha",
help_text=u"Cadastrar sua senha para acesso.",
required=True,
max_length=255)
active = db.BooleanField(verbose_name=u"Ativo",
help_text=u"Indica se o usuário está ativo no sistema.",
default=True)
confirmed_at = db.DateTimeField(verbose_name=u"Confirmação",
help_text=u"Horário de confirmação do usuário")
roles = db.ListField(db.ReferenceField(Role),
verbose_name=u"Papéis",
help_text=u"Atribuir papéis ao usuário.",
default=[])
Does anyone have a clue on what may the problem be?
Thanks in advance!
Thanks deadbeef404, pretty much nailed it. I would have commented on your answer, but I don't have any rep.
Actually flask login uses it's own AnonymousUserMixin class. The following snippet shows how to override it with flask security's AnonymousUser class.
login_manager = LoginManager()
from flask.ext.security import AnonymousUser
login_manager.anonymous_user = AnonymousUser
I'm not sure what your exact problem is but it seems that flask principal is trying to use the AnonymousUser (the identity in memory when no one is logged in) like an authenticated user. An AnonymousUser doesn't have a roles attribute so when it tries to access it, it throws an Exception.
I was not able to implement a working minimal example with the Python Micro-Webframework Flask using a neo4j graphdatabase via the embedded python bindings (neo4j / python-embedded, version 1.6). What I have (on the basis of this Stack-Overflow-thread) is:
import os
import jpype
from neo4j import GraphDatabase
from flask import Flask, g
# configuration
DATABASE = 'graphdatabase'
DEBUG = True
SECRET_KEY = 'blubber'
USERNAME = 'tobias'
PASSWORD = 'bla'
ADMIN = 'admin'
app = Flask(__name__)
app.config.from_object(__name__)
def connectDB():
return GraphDatabase(app.config['DATABASE'])
def initDB():
db = connectDB()
with db.transaction:
users = db.node()
userIndex = db.node.indexes.create('users')
user = db.node(name=app.config['ADMIN'])
userIndex['name'][app.config['ADMIN']] = user
db.shutdown()
print "Database initialized."
#app.before_request
def before_request():
jpype.attachThreadToJVM()
g.db = connectDB()
#app.teardown_request
def teardown_request(exception):
jpype.attachThreadToJVM()
g.db.shutdown()
#app.route('/')
def index():
with g.db.transaction:
userIndex = g.db.node.indexes.get('users')
user = userIndex['name'][app.config['ADMIN']].single
username = user['name']
return render_template('index.html', name=username)
if os.path.exists(app.config['DATABASE']) == False:
initDB()
if __name__ == '__main__':
app.run()
Unfortunately, it throws:
File "/home/tobias/Esk/Dev/adhocracyLight/venv/lib/python2.7/site-packages/flask/app.py", line 1518, in __call__
return self.wsgi_app(environ, start_response)
File "/home/tobias/Esk/Dev/adhocracyLight/venv/lib/python2.7/site-packages/flask/app.py", line 1506, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/tobias/Esk/Dev/adhocracyLight/venv/lib/python2.7/site-packages/flask/app.py", line 1504, in wsgi_app
response = self.full_dispatch_request()
File "/home/tobias/Esk/Dev/adhocracyLight/venv/lib/python2.7/site-packages/flask/app.py", line 1264, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/tobias/Esk/Dev/adhocracyLight/venv/lib/python2.7/site-packages/flask/app.py", line 1262, in full_dispatch_request
rv = self.dispatch_request()
File "/home/tobias/Esk/Dev/adhocracyLight/venv/lib/python2.7/site-packages/flask/app.py", line 1248, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/tobias/Esk/Dev/adhocracyLight/adhocracyLight.py", line 73, in index
userIndex = g.db.node.indexes.get('users')
File "/home/tobias/Esk/Dev/adhocracyLight/venv/lib/python2.7/site-packages/neo4j/index.py", line 36, in get
return self._index.forNodes(name)
java.lang.RuntimeExceptionPyRaisable: java.lang.IllegalArgumentException: No index provider 'lucene' found. Maybe the intended provider (or one more of its dependencies) aren't on the classpath or it failed to load.
I guess the problem is due to the threading (g is thread-local and contains a pointer to the neo4j-Database, maybe that's a bad idea?).
Neo4j Embedded is not intended to be used in a Web server environment -- you should use Neo4j Server and a Neo4j Server client.
Bulbs (http://bulbflow.com) is a Neo4j Server client that was designed with Flask in mind, in fact bulbflow.com is running on Flask on Heroku, using the Neo4j Heroku Add On (which is currently free).
You use Gremlin or Cypher for queries and transactional requests.
For an example of how to structure your app, see the Lightbulb (https://github.com/espeed/lightbulb) blog example, esp:
https://github.com/espeed/lightbulb/blob/master/lightbulb/model.py
https://github.com/espeed/lightbulb/blob/master/lightbulb/bulbsconf.py
Notice this line in bulbsconf.py:
bulbs_config.set_neo4j_heroku()
Lightbulb is designed to run on Heroku with the Neo4j Heroku Add On -- leave that line out if you are not running on Heroku.
Then in your Flask views or your app.py, do:
from bulbsconf import graph