flask中协程发送邮件问题?

写了一个获取邮箱验证码的视图函数,因为邮箱发送是阻塞操作,我准备使用协程来完成这个操作,但是我都写好了后却出现了这个报错是怎么回事?

报错如下

很奇怪的就是,协程报错之后邮件是以同步形式发送的,相当于报错了也能发送邮件验证码。用的是flask

以下为代码

async def task_email(email2,verify_code):
    task_list = []
    message = Message(subject='验证码',recipients=[email2],body=verify_code,sender=('秋零','work1145141919@outlook.com'))
    task = asyncio.create_task(mail.send(message))
    task_list.append(task)
    await asyncio.gather(*task_list)

# 验证码模块获取视图函数
@bp.post('/get_verifycode')
def get_verifycode():
    data = request.get_json()
    email1 = decrypt_AES(data['email'])
    email2 = remove_padding(email1)

    email_data = registe_email(email=email2)
    if email_data.validate():        
        verify_code = secrets.token_urlsafe(4)
        # print(verify_code)
        # message = Message(subject='验证码',recipients=[email2],body=verify_code,sender=('秋零','work1145141919@outlook.com'))
        # mail.send(message)
        
        # asyncio.run(task_email(email2,verify_code))
        loop = asyncio.new_event_loop()
        loop.run_until_complete(task_email(email2,verify_code))

        code_task = verify_codetable(code=verify_code)
        db.session.add(code_task)
        db.session.commit()

        return jsonify({'code': 200, 'message': '验证码发送成功', 'data': 'null'})
    else:
        return jsonify({'code': 200, 'message': f'{email_data.errors}', 'data': 'null'})
阅读 1.7k
1 个回答

我写了个demo,利用 time.sleep() 模拟同步耗时函数,利用 asynciorun_in_executor 包裹那些同步函数,然后实现异步执行。你参考一下:

import asyncio
import time


def fetch_data():
    print("同步任务1 start")
    time.sleep(5)  # Suspend coroutine for 2 seconds
    print("同步任务1 done")


def fetch_data2():
    print("同步任务2 start")
    time.sleep(3)
    print("同步任务2 done")


def start_thread(func, *args):
    loop = asyncio.get_event_loop_policy().get_event_loop()
    return loop.run_in_executor(None, func, *args)


def main1():
    task_list = [start_thread(fetch_data), start_thread(fetch_data2)]
    loop = asyncio.get_event_loop_policy().get_event_loop()
    tasks = asyncio.gather(*task_list)

    try:
        loop.run_until_complete(tasks)
    except KeyboardInterrupt:
        print("caught KeyboardInterrupt while loop.run_until_complete")
        tasks.cancel()
        loop.stop()
    finally:
        loop.close()


t = time.time()
main1()
print(f"Total time: {time.time() - t}")

输出:

同步任务1 start
同步任务2 start
同步任务2 done
同步任务1 done
Total time: 5.003772497177124
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题