Running new routines from a flask request

I have a request going through a function decorated @app.route('/url/path/to/view')

.

It does a few things to find some data and do some calculations, and the function works fine during that. However, at the end, I want to start a new process (from a python function currently using multiprocessing.Process

). Once this process is started, I want the function to return while the new process continues to run independently.

Pseudocode for my current approach

def start_process(arguments):
    # some code here that the process will run

p = multiprocessing.Process(target=start_process, args=(...))
p.start()

return app.response("{ 'status': 'ok' }", mimetype='application/json')

      

Will this approach work and can the Flask application continue to run without affecting the new process?

+3


source to share


1 answer


Starting a subprocess with multiprocessing is perfectly acceptable. Here is a minimal working example that uses multiprocessing to update the database in the background. Ultimately, you will probably need a proper task queue , as Audrius states .

from flask import Flask, jsonify
import multiprocessing
import dataset
import time
import random

app = Flask(__name__)
DATABASE_URL = 'sqlite:///dev.db'

def add_person(name):
    """ Add a person to the db. """
    person = {'name': name, 'age': -1, 'status': 'processing'}
    db = dataset.connect(DATABASE_URL)
    db['people'].insert(person)
    return True

def update_person(name):
    """ Update a person in db with a fake long running process 
    that guesses a random age. """
    time.sleep(10)  # simulate a long running process
    age = random.randint(1, 120)
    person = {'name': name, 'age': age, 'status': 'finished'}
    db = dataset.connect(DATABASE_URL)
    db['people'].update(person, ['name'])
    return True

def get_person(name):
    """ Retrieve a person from the db. """
    db = dataset.connect(DATABASE_URL)
    person = db['people'].find_one(name=name)
    return person

@app.route('/<name>')
def index(name):
    """ Get person. If name not found, add_person to db and start update_person. """
    if not get_person(name):
        add_person(name)
        thread = multiprocessing.Process(target=update_person, args=(name,))
        thread.start()
    person = get_person(name)
    return jsonify(person)

if __name__ == '__main__':
    app.run(debug=True)

      

Visit localhost:5000/bert

while the subprocess is running:



{
    "status": "processing",
    "age": -1,
    "name": "bert",
    "id": 1
}

      

Wait, then refresh and you can see the subprocess is complete:

{
    "status": "finished",
    "age": 28,
    "name": "bert",
    "id": 1
}

      

+1


source







All Articles