Flask Celery Python import - python

I'm having problems integrating Celery in my Flask application.
This is the repo https://github.com/theobouwman/community-python.
I start my app by running app.py which imports my app (where blueprints and config are added) and Celery.
In /tasks/add.py I have a sample task and where I import the Celery object again for the #celery.task decorator.
Till that point everything works fine. I can run my Flask application and run the Celery worker.
But when I try to trigger a task from within a controller in a Blueprint like here https://github.com/theobouwman/community-python/blob/master/auth/controllers/RegistrationController.py#L38 it says that it cannot import it, which it a logic reaction.
Traceback (most recent call last):
File "app.py", line 2, in <module>
from flask_app import app
File "/development/projects/python/Community/flask_app.py", line 4, in <module>
from auth.routes import auth
File "/development/projects/python/Community/auth/routes.py", line 3, in <module>
from .controllers import RegistrationController, AuthenticationController, LogoutController
File "/development/projects/python/Community/auth/controllers/RegistrationController.py", line 10, in <module>
from tasks.add import add
File "/development/projects/python/Community/tasks/add.py", line 1, in <module>
from app import celery
File "/development/projects/python/Community/app.py", line 2, in <module>
from flask_app import app
ImportError: cannot import name 'app'
I don't know how to fix this import cycle and that's the reason for this question. I googled for like 3 hours but couldn't find a solution.
I hope someone here could help me.
And is there a Flask Slack or Gitter in the air?
Thanks in advance.

Change your import in RegistrationController.py to a local one to solve the circular import:
from ..blueprint import auth
from models import User
from flask import redirect, url_for, request, render_template, flash
import bcrypt
from ..forms.register import SimpleRegistrationForm
"""
Error in python3.6 app.py
Says cyclus import error
"""
# Comment out the line below
# from tasks.add import add
#auth.route('/register', methods=['GET', 'POST'])
def register():
form = SimpleRegistrationForm(request.form)
if request.method == 'POST' and form.validate():
fname = request.form['fname']
sname = request.form['sname']
email = request.form['email']
password = request.form['password']
hashed = bcrypt.hashpw(password.encode('utf-8 '), bcrypt.gensalt())
user = User.select().where(User.email == email)
if user.exists():
flash('Er bestaat al een account met dit email adres')
return redirect(url_for('auth.register'))
user = User(fname=fname, sname=sname, email=email, password=hashed)
user.save()
flash('Uw account is aangemaakt. Kijk in uw mailbox voor de activatie link')
return redirect(url_for('auth.register'))
return render_template('pages/register.html', form=form)
#auth.route('/register/test')
def register_test():
# local import avoids the cycle
from tasks.add import add
add.delay()
# hashed = bcrypt.hashpw('test'.encode('utf-8 '), bcrypt.gensalt())
# user = User(
# fname='Theo',
# sname='Bouwman',
# email='theobouwman98#gmail.com',
# password=hashed
# )
# user.save()
return redirect(url_for('auth.login'))

Related

flask_login.current_user.is_authenticated returns False if not in Blueprint route

With Flask-SocketIO, I want to send data from the current user to the Message event on the client-side. The problem is, the current_user object returns an Anonymous user unless I access it inside a route handler.
Here is __init__.py (to show imports):
from flask import Blueprint
chat = Blueprint('chat', __name__)
from . import routes, events
Here is routes.py:
from flask import render_template, redirect, url_for, request
from flask_login import login_required, current_user
from . import chat
#chat.route('/chatroom', methods=['GET', 'POST'])
#login_required
def chatroom():
print(f"\ninside route: {current_user.is_authenticated}\n") # returns true
if request.method == 'POST':
return redirect(url_for('chat.chatroom'))
return render_template('chatroom.html')
Here is events.py:
from flask_login import current_user
from flask_socketio import emit
from ..extensions import socketio
#socketio.on('message', namespace='/chatroom')
def handle_message(in_data):
print(f"\ninside event: {current_user.is_authenticated}\n") # returns false
sender_name = 'Seth'
sender_pic_id = ''
out_data = {
'msg': f"{sender_name}: {in_data['msg']}",
'pic_id': sender_pic_id
}
emit('message', out_data)
It's not 'blueprint vs. not' that's significant here, it's 'socket i/o or not'. Sessions don't automatically migrate from one to the other.
See https://blog.miguelgrinberg.com/post/flask-socketio-and-the-user-session for a lengthier discussion.

How do I fix an IndentationError

I started learning flask a few days ago from the e-book flask framework cookbook.
I am confused about the following error.
File "run.py", line 1, in <module>
from my_app import app
File "/home/kenosis/flask_app/my_app/__init__.py", line 2, in <module>
from my_app.product.views import product_blueprint
File "/home/kenosis/flask_app/my_app/product/views.py", line 10
def home():
^
IndentationError: unexpected indent
This is my views.py
from werkzeug import abort
from flask import render_template
from flask import Blueprint
from my_app.product.models import PRODUCTS
product_blueprint = Blueprint('product', __name__)
#product_blueprint.route('/')
#product_blueprint.route('/home')
def home():
return render_template('home.html', products=PRODUCTS)
#product_blueprint.route('/product/<key>')
def product(key):
product = PRODUCTS.get(key)
if not product:
abort(404)
return render_template('product.html', product=PRODUCTS)
and then this is my init
from flask import Flask
from my_app.product.views import product_blueprint
app = Flask(__name__)
app.register_blueprint(product_blueprint)
product_blueprint = Blueprint('main', __name__, template_folder='templates')
What am I doing wrong?
Indentation is very important in Python. Do not indent after the decorator
from flask import render_template, abort
from flask import Blueprint
from my_app.product.models import PRODUCTS
product_blueprint = Blueprint('product', __name__)
#product_blueprint.route('/')
#product_blueprint.route('/home')
def home():
return render_template('home.html', products=PRODUCTS)
#product_blueprint.route('/product/<key>')
def product(key):
product = PRODUCTS.get(key)
if not product:
abort(404)
return render_template('product.html', product=PRODUCTS)

Circular import issue when working with sending mail upon user registration on Flask

I am currently working with a flask application and am trying to send out emails once the user has registered with the site. I am having difficulties with circular imports between the main.py where the app is instantiated and the data_inserts.py where the data is committed to the db and a password is emailed back to the user. For the email functionality, I use Flask-mail extension. The error I get is given below:
ImportError: Cannot import name from 'DataInserts' from relevant_folder.data_inserts
Given below are the details:
main.py:
from relevant_folder.data_inserts import DataInserts
from flask import Flask
from flask_mail import Mail
from conf.mail_settings.py import mail_settings
app = Flask(__name__)
app.config.update[mail_settings]
mail = Mail(app)
#app.route("/register")
def register():
params = request.json
DataInserts.add_user(params)
relevant_folder.data_inserts.py:
from main import app
from main.app import mail
from flask_mail import message
class DataInserts():
def add_user(self, new_user_json):
''' add user name and email to db logic goes here'''
msg = Message(subject="Subject",
sender=app.config.get("MAIL_USERNAME"),
recipients=[new_user_json["email"]],
body="Hello " + new_user_json["name"] + ", your password is password")
mail.send(msg)
I feel I have not structured my application properly. Any help greatly appreciated
It should be enough to move the DataInserts import...
from flask import Flask
from flask_mail import Mail
from conf.mail_settings.py import mail_settings
app = Flask(__name__)
app.config.update[mail_settings]
mail = Mail(app)
from relevant_folder.data_inserts import DataInserts
#app.route("/register")
def register():
params = request.json
DataInserts.add_user(params)
Alternatively you could pass app and mail instances to the DataInsert class, instead of importing the globals...
Update: Another approach would be using "flask.current_app".
from relevant_folder.data_inserts import DataInserts
from flask import Flask
from flask_mail import Mail
from conf.mail_settings.py import mail_settings
app = Flask(__name__)
app.config.update[mail_settings]
mail = Mail(app)
app.mail = mail
#app.route("/register")
def register():
params = request.json
DataInserts.add_user(params)
Notice that I stored the mail instance in app.mail for easy access later.
relevant_folder.data_inserts.py:
from flask import current_app
from flask_mail import message
class DataInserts():
def add_user(self, new_user_json):
''' add user name and email to db logic goes here'''
msg = Message(subject="Subject",
sender=current_app.config.get("MAIL_USERNAME"),
recipients=[new_user_json["email"]],
body="Hello " + new_user_json["name"] + ", your password is password")
current_app.mail.send(msg)
But keep in mind that current_app needs an active application context.
when working on a request, the context should alway be there, otherwise you can manually create the context e.g. using with app.app_context():
For more on that topic, see the flask documentation:
http://flask.pocoo.org/docs/1.0/appcontext/

Python:ValueError: Attempted relative import in non-package

I have the following package structure
This is my code in home.py
import os
from flask import Blueprint, render_template, request, flash, url_for
from .. import db
from ..models.home import Summary
from ..forms.home import SummarizerForm
from ..processing.summarizer import Summarizer
from ..helpers import flash_errors
from ..processing.newsbot import NewsBot
home = Blueprint('home', __name__)
#home.route('/', methods=['GET', 'POST'])
def index():
summary = None
url = ''
form = SummarizerForm(request.form)
if request.method == "POST" and form.validate():
summary = Summarizer(form.text.data, form.algorithm.data, form.length.data)
if summary.error:
flash(summary.error)
else:
source_url = form.text.data if form.text.data.startswith(('http://', 'https://')) else ''
summary_db_entry = Summary(
summary.bullets,
summary.highlighted_text,
source_url=source_url)
db.session.add(summary_db_entry)
db.session.commit()
url_hash = summary_db_entry.url
url = os.path.join(request.url, url_for('home.summary_entry', url_hash=url_hash)[1:])
flash_errors(form)
return render_template(
'home/index.html',
form=form,
summary=summary,
url=url
)
#home.route('/s/<url_hash>')
def summary_entry(url_hash):
summary = Summary.query.filter_by(url=url_hash).first_or_404()
source_url = summary.source_url
return render_template(
'home/summary.html',
summary=summary,
source_url=source_url
)
#home.route('/about')
#home.route('/about/')
def about():
return render_template('home/about.html')
And the init.py out of the package
from .views.home import home
I get the following error on init.py which is out of the package.
Traceback (most recent call last):
File "/Users/johnsriskandarajah/Documents/summarizer-flask-app-master/tldrapp/__init__.py", line 35, in <module>
from .views.home import home
ValueError: Attempted relative import in non-package
How can this error be fixed? I tried out most of the solutions online but couldn't find any luck.
Full project structure

Running Pyad in flask

I am attempting to run pyad in a flask app.
from flask import Flask, render_template, flash, request
from wtforms import Form, TextField, TextAreaField, validators, StringField, SubmitField
from pyad import *
import folder_module
# App config.
DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
app.config['SECRET_KEY'] = 'SECRETKEY'
class ReusableForm(Form):
uid1 = TextField('UID1:', validators=[validators.required()])
uid2 = TextField('UID2:', validators=[validators.required()])
folder = TextField('Folder Name:', validators=[validators.required()])
#app.route("/", methods=['GET', 'POST'])
def fold():
form = ReusableForm(request.form)
print(form.errors)
if request.method == 'POST':
uid1 = request.form['uid1']
uid2 = request.form['uid2']
foldername = request.form['folder']
if form.validate():
ou = pyad.adcontainer.ADContainer.from_dn("ou=Groups, dc=ad, dc=test, dc=com")
flash(ou)
else:
flash('All the form fields are required. ')
return render_template('folder.html', form=form)
if __name__ == "__main__":
app.run()
I am hoping that I can call into pyad to create a security group. But even running a query on the ad container (ou via dn in this case) gives me a win32 error. The main fail error is resulted from that line and gives the following win32types error.
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147221020), None)
I have tried running this in 32bit and 64 bit python, as well as with AD.setdefault auth.
Is there anything else I can do?
pywintypes.com error when running pyad.adgroup on flask
It looks like someone else has a similar question
I solve this error using pythoncom library inside any route.
from flask import Flask, render_template, request
import pythoncom
import pyad
#app.route('/')
def index():
pythoncom.CoInitialize()

Categories