title: Return HTTP status code from Flask without "returning"
body: <h2>Context</h2>
  
  <ul>
  <li>I have a server called <code>"server.py"</code> that functions as a post-commit webhook from GitLab.</li>
  <li>Within <code>"server.py"</code>, there is a long-running process (~40 seconds)</li>
  </ul>
  
  <h2>SSCCE</h2>
  
  <pre><code>#!/usr/bin/env python
  
  import time
  from flask import Flask, abort, jsonify
  
  debug = True
  
  app = Flask(__name__)
  
  
  @app.route("/", methods=['POST'])
  def compile_metadata():
      # the long running process...
      time.sleep(40)
      # end the long running process
      return jsonify({"success": True})
  
  if __name__ == "__main__":
      app.run(host='0.0.0.0', port=8082, debug=debug, threaded=True)
  </code></pre>
  
  <h2>Problem Statement</h2>
  
  <p>GitLab's webhooks expect return codes to be returned quickly.  Since my webhook returns after or around 40 seconds; GitLab sends a retry sending my long running process in a loop until GitLab tries too many times.</p>
  
  <h2>Question</h2>
  
  <p>Am I able to return a status code from Flask back to GitLab, but still run my long running process?</p>
  
  <p>I've tried adding something like:</p>
  
  <pre><code>...
  def compile_metadata():
      abort(200)
      # the long running process
      time.sleep(40)
  </code></pre>
  
  <p>but <code>abort()</code> only supports failure codes.</p>
  
  <p>I've also tried using <code>@after_this_request</code>:</p>
  
  <pre><code>@app.route("/", methods=['POST'])
  def webhook():
      @after_this_request
      def compile_metadata(response):
          # the long running process...
          print("Starting long running process...")
          time.sleep(40)
          print("Process ended!")
          # end the long running process
      return jsonify({"success": True})
  </code></pre>
  
  <p>Normally, flask returns a status code only from python's <code>return</code> statement, but I obviously cannot use that before the long running process as it will escape from the function.</p>
  
  <p><em>Note: I am not actually using <code>time.sleep(40)</code> in my code.  That is there only for posterity, and for the SSCCE.  It will return the same result</em></p>