title: Flask, concurrent.futures and SQLAlchemy - No application found: work inside a view function or push an application context
body: <p>Im building a <code>Flask</code> app which require a background process resulting in uploads to a <code>SQLAlchemy</code> database.</p>
  
  <blockquote>
    <p>Relevant snippets:</p>
  </blockquote>
  
  <pre><code>from flask_sqlalchemy import SQLAlchemy
  import concurrent.futures
  import queue
  from models import Upload_Tracks
  
  app = Flask(__name__)
  db.init_app(app)
  
  app.config.update(
  SQLALCHEMY_DATABASE_URI= "sqlite:///%s" % os.path.join(app.root_path, 'path/to/player.sqlite3'))
  
  q = queue.Queue()
  </code></pre>
  
  <p><strong>In <code>database.py</code>:</strong></p>
  
  <pre><code>from flask_sqlalchemy import SQLAlchemy
  
  db = SQLAlchemy()
  </code></pre>
  
  <p><strong>In <code>models.py</code>:</strong></p>
  
  <pre><code>def Upload_Tracks(item):
          uri = None
          title = unidecode(item['title'])
          artist = unidecode(item['artist'])
          preview = item['preview']
          energy = item['energy']
          popularity = item['popularity']
          tempo = item['tempo']
          brightness = item['brightness']
          key = item['key']
          image = item['artist_image']
          duration = item['duration']
          loudness = item['loudness']
          valence = item['valence']
          genre = item['genre']
  
          track = Track(title=title,
                        artist=artist,
                        uri=uri,
                        track_id=None)
  
          db.session.add(track)
  
          track.preview = preview
          track.energy = energy
          track.popularity = popularity
          track.tempo = tempo
          track.genre = genre
          track.brightness = brightness
          track.key = key
          track.image = image
          track.duration = duration
          track.loudness = loudness
          track.valence = valence
  
          db.session.commit()
  </code></pre>
  
  <p><strong>first function:</strong></p>
  
  <pre><code># 1st background process
  def build_cache():
      """
      Build general cache 
      from user's streaming
      """
      tracks_and_features = spotify.query_tracks()
  
      for item in tracks_and_features:
          q.put(item)
  
      return "CACHE BUILT"               
  </code></pre>
  
  <p><strong>second:</strong>         </p>
  
  <pre><code>def upload_cache(track):
      # save to database
      Upload_Tracks(filtered_dataset=track) 
  
      return "CACHE UPLOADED"               
  </code></pre>
  
  <p><strong><code>Flask</code> view:</strong></p>
  
  <pre><code>#background cache
  @app.route('/cache')
  def cache():
      # We can use a with statement to ensure threads are cleaned up promptly
      with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
          #executor.submit(build_cache)
  
          # start a future for a thread which sends work in through the queue
          future_to_track = {
              executor.submit(build_cache): 'TRACKER DONE'}
  
          while future_to_track:
              # check for status of the futures which are currently working
              done, not_done = concurrent.futures.wait(
                                                  future_to_track, 
                                                  timeout=0.25,
                                                  return_when=concurrent.futures.FIRST_COMPLETED) 
  
              # if there is incoming work, start a new future
              while not q.empty():
  
                  # fetch a track from the queue
                  track = q.get()
  
                  # Start the load operation and mark the future with its TRACK
                  future_to_track[executor.submit(upload_cache, track)] = track
              # process any completed futures
              for future in done:
                  track = future_to_track[future]
                  try:
                      data = future.result()
                  except Exception as exc:
                      print('%r generated an exception: %s' % (track, exc))
                  else:
                      if track == 'TRACKER DONE':
                          print(data)
                      else:
                          print('%r track is nont uploaded to database') % (track)
  
                  # remove the now completed future
                  del future_to_track[future]
  
  
      return 'Cacheing playlist in the background...'
  </code></pre>
  
  <p>Database works fine with no threading. However, when I run it all, the following exception is being caught:</p>
  
  <blockquote>
    <p>FIRST CACHE BUILT
    {'brightness': 0.4293608513678877, 'energy': 0.757, 'tempo': 116.494, 'duration': 201013, 'key': 5, 'loudness': -7.607, 'genre': [u'art rock', u'dance rock', u'folk rock', u'mellow gold', u'new wave', u'new wave pop', u'power pop', u'pub rock', u'rock', u'roots rock'], 'valence': 0.435, 'artist': u'Elvis Costello &amp; The Attractions', 'popularity': 14, 'artist_image': u'<a href="https://i.scdn.co/image/c14ffeb7855625383c266c9c04faa75516a25503" rel="nofollow noreferrer">https://i.scdn.co/image/c14ffeb7855625383c266c9c04faa75516a25503</a>', 'title': u'Poor Napoleon', 'preview': u'<a href="https://p.scdn.co/mp3-preview/c0d57fed887ea2dbd7f69c7209adab71671b9e6e?cid=d3b2f7a12362468daa393cf457185973" rel="nofollow noreferrer">https://p.scdn.co/mp3-preview/c0d57fed887ea2dbd7f69c7209adab71671b9e6e?cid=d3b2f7a12362468daa393cf457185973</a>'} generated an exception: No application found. Either work inside a view function or push an application context. See <a href="http://flask-sqlalchemy.pocoo.org/contexts/" rel="nofollow noreferrer">http://flask-sqlalchemy.pocoo.org/contexts/</a>.</p>
  </blockquote>
  
  <p>but the process, to my knowledge, is running within <code>@app.route</code>. how is this out of context? how do I fix this?</p>