Flask context and python-rq - flask

I have a Flask application with blueprints that is structured like this:
application.py
project/
form_emailer.py
blueprints/
example_form.py
wtforms-models/
example_form_model.py
templates/
example_form_template.html
I'm trying to use RQ to send emails in the background (using Flask-Mail) because our SMTP uses the Gmail servers, which can take a few seconds to complete. My function in form_emailer.py looks like this:
from flask import Flask
from flask.ext.mail import Mail, Message
from application import app, q
mail = Mail(app)
def _queue_message(message):
mail.send(message)
def sendemail(recipients, subject, body):
"""
This function gets called in a Flask blueprint.
"""
message = Message(recipients=recipients, subject=subject, body=body)
q.enqueue(_queue_message, message)
My (simplified) application.py looks like this. I'm breaking convention by using "import *" in order to simplify additions there (our __init__.py in those packages dynamically import all modules):
from flask import Flask
from redis import Redis
from rq import Queue
app = Flask(__name__)
q = Queue(connection=Redis())
from project.blueprints import *
from project.forms import *
if __name__ == "__main__":
app.run()
I have an rqworker running in the same virtual environment where my application is running, and the worker detects the task. However, I'm getting the following traceback and can't figure out how to fix this:
16:41:29 *** Listening on high, normal, low...
16:43:26 low: project.form_emailer._queue_message(<flask_mail.Message object at 0x299d690>) (bd913b3a-4e7f-4efb-b51c-8ae11d37ac00)
16:43:27 ImportError: cannot import name sendemail
Traceback (most recent call last):
...
File "./project/blueprints/example_form.py", line 4, in <module>
from project.form_emailer import sendemail
ImportError: cannot import name sendemail
I suspect this has to do with Flask's application context, but my initial attempts to use with app.app_context(): are failing; the worker is not even able to import the function I want to use. What am I doing wrong here?

Related

celery 4.4.2 and django 3.0.2 raising self.notregistered error but calling the function in python manage.py shell works fine

I am trying to add celery to my django project.
everything works fine when i run it from the manage.py shell, my celery worker returns the result of the add() function.
when i call this function from my view it raises a not registered error and a module object not callable error on celery/base.py line 1253
celery/app/base.py", line 1253, in loaderreturn get_loader_cls(self.loader_cls)(app=self)
TypeError: 'module' object is not callable
raise self.NotRegistered(key)
celery.exceptions.NotRegistered: 'home.tasks.add'
both are from the apache error log
my home.tasks.py looks like this
from celery import shared_task
from celery.schedules import crontab
from django.db import connection
from django.utils import timezone, translation
#import pandas as pd
from home.models import *
from residence_management.models import *
from sqlalchemy import *
from django.conf import settings
from django.contrib.auth.models import User
from decimal import Decimal
#shared_task
def add(x, y):
return x + y
my view where i call the task has the import: from home.tasks import add
in the view itself i just call add(9, 5) and it fails with the above error (without the #shared_task decorator it works fine).
when calling the function in the shell, even with the #shared_task decorator it works fine, i can start the celery worker without problems as well.
[2020-05-13 08:47:23,862: INFO/MainProcess] Received task: home.tasks.add[f7e50f7d-4e3d-4372-bf3e-e1c7175c7a2a]
[2020-05-13 08:47:23,879: INFO/ForkPoolWorker-8] Task home.tasks.add[f7e50f7d-4e3d-4372-bf3e-e1c7175c7a2a] succeeded in 0.015277621999999713s: 14
any ideas where the problem might be? i use redis for the broker and result backend
You can check docs and comments for shared_task on github https://github.com/celery/celery/blob/9d49d90074445ff2c550585a055aa222151653aa/celery/app/init.py
I think for some reasons you do not run creating of celery app. It is better in this case use explicit app.
from .celery import app
#app.task()
def add(x, y):
return x + y

Import Erro Flask Framework

I'm trying to build a CRUD API with product and user and JWT authentication. When I try to run it shows the error -> "ImportError:cannot import name 'Item'" Could you help me. Thank you
from flask import Flask
from flask_jwt import JWT
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from resources.item import Item, ItemList
from resources.user import UserRegister
from security import authenticate, identity
app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['PROPAGATE_EXCEPTIONS'] = True
app.config['SECRET_KEY'] = 'luciano'
db = SQLAlchemy(app)
#app.before_first_request
def create_tables():
db.create_all()
jwt = JWT(app, authenticate, identity)
api.add_resource(Item, "/item/<string:nome>")
api.add_resource(ItemList, "/items")
api.add_resource(UserRegister, "/register")
if __name__ == '__main__':
from db import db
db.init_app(app)
app.run(debug=True)
In the terminal I get the following error
Traceback (most recent call last):
File "/home/luciano/Documentos/Api/app.py", line 5, in <module>
from resources.item import Item, ItemList
ImportError: cannot import name 'Item'
My folder structure
Api
/models
item.py
user.py
/resources
item.py
user.py
app.py
security.py
Add init.py which is missing in your directories
Why it is required
In addition to labeling a directory as a Python package and defining __all__, __init__.py allows you to define any variable at the package level. Doing so is often convenient if a package defines something that will be imported frequently, in an API-like fashion. This pattern promotes adherence to the Pythonic "flat is better than nested" philosophy.
What is __init__.py for?
https://docs.python.org/3/tutorial/modules.html
Add an empty __init__.py file to your resources and models directory.
https://docs.python.org/3/tutorial/modules.html#packages

Flask Application returning ImportError: No module named user_auth.views

I'm in the beginning stages of a Flask application. The problems I'm having is that whenever I attempt to run the application I get:
app/application/___init___.py, line 11 in <module>
from user_auth.views import auth
ImportError: No module named user_auth.views
I have no idea what the problem is. The import for the home.view did this as well, then it stopped and worked fine on the local server. Been trying to figure this out for the longest, there aren't that many moving parts in the application as of yet, so not sure why this is happeninng. File structure and code below:
|app
|-application
|--__ init __.py
|--home
|--user_auth
|----forms.py
|----views.py
|----templates
|----static
My application/__ init __.py file:
from flask import Flask
app = Flask(__name__)
app.config.from_object('_config')
from home.views import home
from user_auth.views import auth
app.register_blueprint(home)
app.register_blueprint(auth)
My application/user_auth/views.py
from flask import Blueprint
auth = Blueprint('auth', __name__,
url_prefix='/user_auth',
template_folder='templates',
static_folder='static')
You're missing an __init__.py file under ./user_auth/ to make user_auth a module.
There's more information about modules in the docs.

flask and passenger "TypeError: 'module' object is not callable"

I'm trying to run flask on a server with passenger. This is my passenger_wsgi.py file:
import sys, os
INTERP = os.path.join(os.environ['HOME'], 'flask_env', 'bin', 'python')
if sys.executable != INTERP:
os.execl(INTERP, INTERP, *sys.argv)
sys.path.append(os.getcwd())
from wtf import app as application
# Uncomment next two lines to enable debugging
from werkzeug.debug import DebuggedApplication
application = DebuggedApplication(application, evalex=True)
There is an app.py file under wtf folder. There is also __init__.py in there so python recognizes it as a module directory. However it gives me this error:
Traceback (most recent call last)
File "/home/hiepha19/flask_env/lib/python2.6/site-packages/werkzeug/debug/__init__.py", line 88, in debug_application
app_iter = self.app(environ, start_response)
TypeError: 'module' object is not callable
When you import app you are importing the app module (which most likely has an app name inside it which points to your Flask app. What you want to do is import that name and register it:
from wtf.app import app as application
# Note the extra app
It is worth noting that you do not need to do this manually - simply run Flask using the run method on the app and pass the argument debug=True to get the same behavior:
from wtf.app import app
if __name__ == '__main__':
app.run(debug=True)

Tests for django app produces template not found error for "render_to_string" when executed via Fabric

When I run tests on my remote server using fabric, I get an error saying:
File "/usr/local/lib/python2.7/dist-packages/django/template/loader.py", line 138, in find_template
raise TemplateDoesNotExist(name)
TemplateDoesNotExist: index.html
I am trying to render the template as a string using "render_to_string()"
If I login to the server and run tests manually (python manage.py test app), it is working properly. This error occurs while running through fabric.
Here is my fabric code:
from __future__ import with_statement
from fabric.api import local
import os
from fabric.api import *
env.hosts = ['server.com']
production_project_path = '/path/to/production/app/'
def run_remote_test():
run("python %s/manage.py test app"%production_project_path)
Did I miss something?
Note: I am not using virtual environment
Then let's make this official. ;)
In this case, the problem was the fact that manage.py expects to be ran from the project directory, so rewriting the abovestanding as:
from __future__ import with_statement
from fabric.api import local
import os
from fabric.api import *
env.hosts = ['server.com']
production_project_path = '/path/to/production/app/'
def run_remote_test():
with cd(production_project_path):
run("python manage.py test app")
has fixed the issue.