title: Flask with create_app, SQLAlchemy and Celery
body: <p>I'm really struggling to the get the proper setup for Flask, SQLAlchemy and Celery. I have searched extensively and tried different approaches, nothing really seems to work. Either I missed the application context or can't run the workers or there are some other problems. The structure is very general so that I can build a bigger application. </p>
  
  <p>I'm using: Flask 0.10.1, SQLAlchemy 1.0, Celery 3.1.13, my current setup is the following:</p>
  
  <p>app/__init__.py</p>
  
  <pre><code>#Empty
  </code></pre>
  
  <p>app/config.py</p>
  
  <pre><code>import os
  basedir = os.path.abspath(os.path.dirname(__file__))
  
  class Config:
  
      @staticmethod
      def init_app(app):
          pass
  
  class LocalConfig(Config):
      DEBUG = True
      SQLALCHEMY_DATABASE_URI = r"sqlite:///" + os.path.join(basedir, 
                                   "data-dev.sqlite")
      CELERY_BROKER_URL = 'amqp://guest:guest@localhost:5672//'
  
  
  config = {
      "local": LocalConfig}
  </code></pre>
  
  <p>app/exstensions.py</p>
  
  <pre><code>from flask.ext.sqlalchemy import SQLAlchemy
  from celery import Celery
  
  db = SQLAlchemy()
  celery = Celery()
  </code></pre>
  
  <p>app/factory.py</p>
  
  <pre><code>from extensions import db, celery
  from flask import Flask
  from flask import g
  from config import config
  
  def create_before_request(app):
      def before_request():
          g.db = db
      return before_request
  
  
  def create_app(config_name):
      app = Flask(__name__)
      app.config.from_object(config[config_name])
  
      db.init_app(app)
      celery.config_from_object(config)
  
      # Register the blueprints
  
      # Add the before request handler
      app.before_request(create_before_request(app))
      return app
  </code></pre>
  
  <p>app/manage.py</p>
  
  <pre><code>from factory import create_app
  
  app = create_app("local")
  
  from flask import render_template
  from flask import request
  
  @app.route('/test', methods=['POST'])
  def task_simple():
      import tasks
      tasks.do_some_stuff.delay()
      return ""
  
  if __name__ == "__main__":
      app.run()
  </code></pre>
  
  <p>app/models.py</p>
  
  <pre><code>from extensions import db
  
  class User(db.Model):
      __tablename__ = "user"
  
      id = db.Column(db.Integer, primary_key=True)
      username = db.Column(db.String(128), unique=True, nullable=False)
  </code></pre>
  
  <p>app/tasks.py</p>
  
  <pre><code>from extensions import celery
  from celery.signals import task_prerun
  from flask import g, current_app
  
  
  @task_prerun.connect
  def close_session(*args, **kwargs):
      with current_app.app_context():
         # use g.db
         print g
  
  @celery.task()
  def do_some_stuff():
      with current_app.app_context():
         # use g.db
         print g
  </code></pre>
  
  <p>In the folder app:</p>
  
  <ul>
  <li>starting the development webserver with: <code>python.exe manage.py</code></li>
  <li>starting the workers with: <code>celery.exe worker -A tasks</code></li>
  </ul>
  
  <p>I get an import error that doesn't make any sense to me.
  Should I structure the application differently? At the end I think I want a quite basic setup, e.g. Using Flask with the factory pattern, be able to use the Flask-SQLAlchmey extension and have some worker that needs to access the database.</p>
  
  <p>Any help is highly appreciated.</p>
  
  <p>Traceback is executed when starting the celery worker.</p>
  
  <pre><code>Traceback (most recent call last):
  
    File "[PATH]\scripts\celery-script.py", line 9, in &lt;module&gt;
      load_entry_point('celery==3.1.13', 'console_scripts', 'celery')()
  
    File "[PATH]\lib\site-packages\celery\__main__.py", line 30, in main
      main()
  
    File "[PATH]\lib\site-packages\celery\bin\celery.py", line 81, in main
      cmd.execute_from_commandline(argv)
  
    File "[PATH]\lib\site-packages\celery\bin\celery.py", line 769, in execute_from_commandline
      super(CeleryCommand, self).execute_from_commandline(argv)))
  
    File "[PATH]\lib\site-packages\celery\bin\base.py", line 305, in execute_from_commandline
      argv = self.setup_app_from_commandline(argv)
  
    File "[PATH]\lib\site-packages\celery\bin\base.py", line 473, in setup_app_from_commandline
      user_preload = tuple(self.app.user_options['preload'] or ())
  AttributeError: 'Flask' object has no attribute 'user_options'
  </code></pre>
  
  <p><strong>UPDATE</strong> I change the code according to the suggestion in the comment. The worker starts now up but when test it with a get request to <code>http://127.0.0.1:5000/test</code>. I get the following traceback:</p>
  
  <pre><code>Traceback (most recent call last):
    File "[PATH]\lib\site-packages\celery\app\trace.py", line 230, in trace_task
      args=args, kwargs=kwargs)
  
    File "[PATH]\lib\site-packages\celery\utils\dispatch\signal.py", line 166, in send
      response = receiver(signal=self, sender=sender, \**named)
  
    File "[PATH]\app\stackoverflow\tasks.py", line 7, in close_session
      with current_app.app_context():
  
    File "[PATH]\lib\site-packages\werkzeug\local.py", line 338, in __getattr__
      return getattr(self._get_current_object(), name)
  
    File "[PATH]\lib\site-packages\werkzeug\local.py", line 297, in _get_current_object
      return self.__local()
  
    File "[PATH]\lib\site-packages\flask\globals.py", line 34, in _find_app
      raise RuntimeError('working outside of application context')
  RuntimeError: working outside of application context exc, exc_info.traceback)))
  </code></pre>
  
  <p><strong>UPDATE</strong> Based on the comments from Marteen, I changed the code. The current working version is under: <a href="https://gist.github.com/anonymous/fa47834db2f4f3b8b257" rel="noreferrer">https://gist.github.com/anonymous/fa47834db2f4f3b8b257</a>. 
  Any further improvements or suggestions are welcome.</p>