0

I have written a Flask app where a user can input a date and time. This information is stored locally on a SQL server. Once the datetime the user specifies occurs, a function which sends a text message is executed.

I expected the user to click on the submit form and trigger the async 'schedule_hello()' function, and be redirected right away to the blog's index. However, the code below 'schedule_hello()' doesn't run until the time specified by the user, and they aren't redirected until that time. Am I misunderstanding what async does, or have I implemented it incorrectly?

The code for the endpoint:

@bp.route('/calendar', methods=('GET', 'POST'))
def calendar():
    if request.method == 'POST':
        date = request.form['date']
        time = request.form['time']
        error = None
        if not date:
            error = 'Date is required.'
        if not time:
            error = 'Time is required.'

        if error is not None:
            flash(error)
        else:
            db = get_db()
            db.execute(
                'INSERT INTO post (title, body, author_id)'
                ' VALUES (?, ?, ?)',
                (date, time, g.user['id'])
            )
            db.commit()
            asyncio.run(schedule_hello(date, time))
            return redirect(url_for('blog.index'))

    return render_template('blog/calendar.html')

Here is my code for the async function:

async def schedule_hello(date, time):
    datetime_str = str(date) + " " + str(time)
    delta = (datetime.strptime(datetime_str, '%m/%d/%y %H:%M:%S') - datetime.now()).total_seconds() // 1
    await asyncio.sleep(delta)   
    "Some code which will send a text message" 
    print('Message sent')
NickS
  • 31
  • 3
  • [`asyncio.run`](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run) is not an async function, and its goal is to run a coroutine until it exits, i.e. it will wait (block execution) until the coroutine is done, in your case, it functions as if calling a standard `sleep` function. You may need to investigate whether [async views](https://flask.palletsprojects.com/en/2.2.x/async-await/) will address your particular use case. – metatoaster Mar 30 '23 at 00:12
  • Though that being said, I don't think what you are trying to do actually can be done directly from a standard flask endpoint, because the code will run but it won't get to send whatever back in the same request over HTTP, see [thread](https://stackoverflow.com/questions/21259553/flask-asynchronous-response-to-client). – metatoaster Mar 30 '23 at 00:14
  • Now if you were to readjust your technique to make use of websockets, you may be able to achieve what you want, see [thread](https://stackoverflow.com/questions/47514340/send-websocket-message-from-flask-view). – metatoaster Mar 30 '23 at 00:16

0 Answers0