I'm trying to schedule sending email from my flask application with this function :
from apscheduler.scheduler import Scheduler
scheduler = Scheduler()
scheduler.start()
def email_job_scheduling():
to="abdellah.ala#gmail.com"
subject="summary projects"
message="your summary projects"
send_email(to,subject,message)
scheduler.add_cron_job(email_job_scheduling, day_of_week='tue', hour=12, minute=55)
this is how i declare app in my file init.py, is there any relationship or must i add schedule function in this file.
login_manager = LoginManager()
db = SQLAlchemy()
mail = Mail()
def create_app(config_name):
app = Flask(__name__, instance_relative_config=True)
app.config.from_object(app_config[config_name])
app.config.from_pyfile('config.py')
app.permanent_session_lifetime = timedelta(minutes=10)
db.init_app(app)
mail.init_app(app)
login_manager.init_app(app)
return app
but I receive this error,
Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to
quit) Job "email_job_scheduling (trigger: cron[day_of_week='wed',
hour='9', minute='57'], next run at: 2019-12-11 09:57:00)" raised an
exception Traceback (most recent call last): File
"/home/abdellah/Documents/venv/lib64/python3.6/site-packages/apscheduler/scheduler.py",
line 512, in _run_job
retval = job.func(*job.args, **job.kwargs) File "/home/abdellah/Documents/SUPPORT-STS/project/app/admin/views.py",
line 29, in email_job_scheduling
send_email(to,subject,message) File "/home/abdellah/Documents/SUPPORT-STS/project/app/emails.py",
line 11, in send_email
mail.send(msg) File "/home/abdellah/Documents/venv/lib64/python3.6/site-packages/flask_mail.py",
line 491, in send
with self.connect() as connection: File "/home/abdellah/Documents/venv/lib64/python3.6/site-packages/flask_mail.py",
line 508, in connect
return Connection(app.extensions['mail']) File "/home/abdellah/Documents/venv/lib64/python3.6/site-packages/werkzeug/local.py",
line 348, in getattr
return getattr(self._get_current_object(), name) File "/home/abdellah/Documents/venv/lib64/python3.6/site-packages/werkzeug/local.py",
line 307, in _get_current_object
return self.__local() File "/home/abdellah/Documents/venv/lib64/python3.6/site-packages/flask/globals.py",
line 52, in _find_app
raise RuntimeError(_app_ctx_err_msg) RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that
needed to interface with the current application object in some way.
To solve this, set up an application context with app.app_context().
See the documentation for more information.
Yes if you have not specified an application context you should create it.
This is because it is necessary to define all the necessary resources within the Flask application.
The documentation explains perfectly in which cases and how you should use a context application in Flask.
https://flask.palletsprojects.com/en/1.0.x/appcontext/
If you post more code I could be more helpful.
I will try to find a solution by the way:
from flask import g
def email_job_scheduling():
a = "abdellah.ala#gmail.com"
subject = "summary projects"
message = "your summary projects"
send_email (to, subject, message)
def get_scheduler():
if "scheduler" is not in g:
g.scheduler = Scheduler()
g.scheduler.start()
returns g.scheduler
with app.app_context(): #add the necessary resources
scheduler = get_scheduler()
#add another code if you need to set another resource
#This piece of code I think is in the main
scheduler.add_cron_job (email_job_scheduling, day_of_week = 'tue', now = 12, minute = 55)
Related
In Flask I'm attempting to run several jobs concurrently. But I'm faced with this issue:
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
Job "chron (trigger: interval[0:00:05], next run at: 2020-05-19 16:03:46 IST)" raised an exception
Traceback (most recent call last):
File "C:\Users\mithi\AppData\Local\Programs\Python\Python37\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job
retval = job.func(*job.args, **job.kwargs)
File "c:\Users\mithi\Desktop\appengineering\server.py", line 128, in chron
return jsonify({})
File "C:\Users\mithi\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\json\__init__.py", line 358, in jsonify
if current_app.config["JSONIFY_PRETTYPRINT_REGULAR"] or current_app.debug:
File "C:\Users\mithi\AppData\Local\Programs\Python\Python37\lib\site-packages\werkzeug\local.py", line 348, in __getattr__
return getattr(self._get_current_object(), name)
File "C:\Users\mithi\AppData\Local\Programs\Python\Python37\lib\site-packages\werkzeug\local.py", line 307, in _get_current_object
return self.__local()
File "C:\Users\mithi\AppData\Local\Programs\Python\Python37\lib\site-packages\flask\globals.py", line 52, in _find_app
raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
Here is my schedular object:
job_defaults = {
'coalesce': False,
'max_instances': 100
}
sched = BackgroundScheduler(daemon=True, job_defaults=job_defaults)
sched.start()
I'm creating multiple jobs by defining the following function:
def etl():
# read app config
with open('appConfig.json', encoding="utf-8") as json_file:
configData = json.load(json_file)
for obj in configData:
sched.add_job(chron, 'interval', seconds=5, args=[obj], id=obj)
Basically the function is adding jobs as a call to the function "chron" but args and id are different which creates unique jobs, running at intervals of five seconds. I get the app_context issue in the chron function. I have read about app_context but still unable to grasp the concept.
Your "chron" function is calling Flask current_app and jsonify() but it seems you haven't pushed a Flask context yet thus having this outside app context runtime error.
Before you can call a "contexted" func, you need to push your Flask app context.
Two ways of doing so,
app = Flask(__name__)
# do some stuff on your app if you need
app.app_context().push()
# do some other stuff
or in your chron func,
with app.app_context():
# do something
You can refer to manually pushing a context for more details
Good day.
I have one question. How to access a configuration item from another .py file
For example.
app/__init__.py
def create_app(config=None):
app = Flask(__name__, instance_relative_config=True)
app._static_folder = './static'
app.config.from_pyfile('flask.cfg')
app.app_context().push()
return app
wsgi.py
from app import create_app
from werkzeug.debug import DebuggedApplication
if __name__ == "__main__":
app = create_app()
application = DebuggedApplication(app, evalex=True)
app.logger.info("Debug status is: " + str(app.config['DEBUG']))
app.run(use_reloader=True, debug=True)
app/core/helper.py
from flask import current_app as app
def get_dir():
return app.config["PATH_CACHE_DIR"]
Try to call method app/core/cached.py
from flask_caching import Cache
from flask import current_app as app
from app.core.helper import get_dir
print get_dir()
So, i receive the following error
Traceback (most recent call last):
File "/home/stanislav/Python/mbgp/wsgi.py", line 1, in <module>
from app import create_app
File "/home/stanislav/Python/mbgp/app/__init__.py", line 4, in <module>
from app.core.cached import cache
File "/home/stanislav/Python/mbgp/app/core/cached.py", line 5, in <module>
print get_dir()
File "/home/stanislav/Python/mbgp/app/core/helper.py", line 14, in get_dir
return app.config["PATH_CACHE_DIR"]
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 306, in _get_current_object
return self.__local()
File "/usr/local/lib/python2.7/dist-packages/flask/globals.py", line 51, in _find_app
raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current applicat`enter code here`ion object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
Please tell me how to fix this, thank you very much.
[2018-05-29 14:25:35,490: ERROR/ForkPoolWorker-1] Task utils.send_mail[cffafdb2-f242-4ecd-b42c-03f701d700d8] raised unexpected: RuntimeError('Working outside of application context.\n\nThis typically means that you attempted to use functionality that needed\nto interface with the current application object in a way. To solve\nthis set up an application context with app.app_context(). See the\ndocumentation for more information.',)
Traceback (most recent call last):
File "/Users/luklas/Code/GitHub/ctflearn-flask/venv/lib/python3.6/site-packages/celery/app/trace.py", line 375, in trace_task
R = retval = fun(*args, **kwargs)
File "/Users/luklas/Code/GitHub/ctflearn-flask/venv/lib/python3.6/site-packages/celery/app/trace.py", line 632, in __protected_call__
return self.run(*args, **kwargs)
File "/Users/luklas/Code/GitHub/ctflearn-flask/utils.py", line 25, in send_mail
msg = Message(subject, recipients=recipients)
File "/Users/luklas/Code/GitHub/ctflearn-flask/venv/lib/python3.6/site-packages/flask_mail.py", line 273, in __init__
sender = sender or current_app.extensions['mail'].default_sender
File "/Users/luklas/Code/GitHub/ctflearn-flask/venv/lib/python3.6/site-packages/werkzeug/local.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/luklas/Code/GitHub/ctflearn-flask/venv/lib/python3.6/site-packages/werkzeug/local.py", line 306, in _get_current_object
return self.__local()
File "/Users/luklas/Code/GitHub/ctflearn-flask/venv/lib/python3.6/site-packages/flask/globals.py", line 51, in _find_app
raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in a way. To solve
this set up an application context with app.app_context(). See the
documentation for more information.
utils.py
from ctflearn import db, celery, app, mail
#celery.task
def send_mail(subject, body, recipients):
msg = Message(subject, recipients=recipients)
msg.html = body
with app.app_context():
mail.send(msg)
init.py
from flask import Flask, Blueprint
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_mail import Mail
from flask_pagedown import PageDown
from celery import Celery
app = Flask(__name__, static_url_path='/static', template_folder='static/templates')
app.config.from_object('config')
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "signin"
db = SQLAlchemy(app)
mail = Mail(app)
pagedown = PageDown(app)
...
Why am i still getting this error even though I get an app context? I would rather stay away from the flask factory design. The celery worker picks up this task without a problem, but it throws an exception saying the code is running outside of an application context, even though I run it inside an app context.
I have the following very simple app:
from lib.flask import Flask
from lib.flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class TestResource(Resource):
def get(self):
return {"a":"b","c":"d"}
api.add_resource(TestResource, "/")
When I run this, I get the following Exception:
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/runtime/wsgi.py", line 266, in Handle
result = handler(dict(self._environ), self._StartResponse)
File "/Users/me/dev/project/src/main.py", line 22, in do_in_request
app(*args, **kwargs)
File "/Users/me/dev/project/src/lib/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/me/dev/project/src/lib/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/me/dev/project/src/lib/flask_restful/__init__.py", line 249, in error_router
if self._has_fr_route():
File "/Users/me/dev/project/src/lib/flask_restful/__init__.py", line 230, in _has_fr_route
if self._should_use_fr_error_handler():
File "/Users/me/dev/project/src/lib/flask_restful/__init__.py", line 211, in _should_use_fr_error_handler
adapter = self.app.create_url_adapter(request)
File "/Users/me/dev/project/src/lib/flask/app.py", line 1601, in create_url_adapter
return self.url_map.bind_to_environ(request.environ,
File "/Users/me/dev/project/src/lib/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/me/dev/project/src/lib/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/Users/me/dev/project/src/lib/flask/globals.py", line 20, in _lookup_req_object
raise RuntimeError('working outside of request context')
RuntimeError: working outside of request context
So I tried to put my entire app into what I thought would be the request context. In the code above, both the Flask object and the Api object are being instantiated once, and can be called by the server multiple times. From the traceback, it looks like the instantiation should happen within a request context, so I wrapped it like this:
def do_in_request(*args, **kwargs):
from lib.flask import Flask
from lib.flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class TestResource(Resource):
def get(self):
return {"a":"b","c":"d"}
api.add_resource(TestResource, "/")
app(*args, **kwargs)
app = do_in_request
That still raises the same error. What's going on, what do they mean by 'request context', and how do I fix this?
I started from scratch using the App Engine Flask Skeleton and added flask-restful as a dependency in requirements.txt and then just added more or less the code you have above and it worked without an issue. I added the repository to my github here if you want to use it - you can see the changes I made to the skeleton in this commit.
I'm not sure why your example isn't working, but one thing I noticed that could be causing issues is that you're doing from lib.flask .... It seems your third-party packages live in lib and you haven't necessarily "lifted" lib into your sys.path. The skeleton includes a vendoring library that makes sure that this is handled properly. It might be a potential source of the problem.
Either way, I hope the forked skeleton can help you get up and running.
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