שליחת מייל עם FastApi עבודה עם פונקציה א-סינכרונית

מחבר:
בתאריך:

השתמשתי באפליקציה מבוססת FastApi לשליחת מייל (הסבר תהליך השליחה). הפונקציה לשליחת מייל היא א-סינכרונית. הפונקציה testAsync קוראת לפונקציה sendAsync:

from fastapi import FastAPI
from starlette.responses import JSONResponse
from fastapi_mail import FastMail, MessageSchema, ConnectionConfig, MessageType
 
async def sendAsync(to, id):
   now = datetime.now() # current date and time
   now_str = now.strftime("%Y-%m-%d %H:%M:%S")
 
   title = f'test email : {now_str}, id : {id}'
 
   message = MessageSchema(
       subject=title,
       recipients=[to],
       body=title,
       subtype=MessageType.html)
 
   fm = FastMail(conf_email)
   await fm.send_message(message)
   
@app.get('/test-async')
def testAsync():
   sendAsync("[email protected]", 1)

הרצתי את הקוד, וקיבלתי הודעה אזהרה:

$ RuntimeWarning: coroutine 'sendAsync' was never awaited

הסיבה להודעה היא שאנחנו צריכים להפעיל event loop שישאר בהאזנה לפונקציה הא-סינכרונית עד שתסיים. event loop הוא תהליך שבודק האם יש תהליכים או פונקציות א-סינכרוניות שסיימו לרוץ. כדי להתחיל את תהליך ה-event loop אנחנו צריכים להוסיף לקריאה לפונקציה א-סינכרונית את הקוד שפותח event loop, ממתין לו עד שיסיים, ובסוף סוגר את ה-event.

עושים את זה באמצעות ספרייה של פייתון:

import asyncio

אפשר להשתמש בקוד הבא כדי להפעיל event loop שיאזין לפונקציה עד שתסיים:

loop = asyncio.get_event_loop()
loop.run_until_complete(call_to_func())
loop.close()

אבל עדיף שלא כי עד כמה שהוא מפורט הוא לא תמיד עובד.

דרך טובה יותר היא להשתמש במתודה asyncio.run() ומתוכה לקרוא לפונקציה:

@app.get('/test-async')
def testAsync():
    asyncio.run(sendAsync("[email protected]", 1))
    # print(type(response))
    # print(dir(response))
    msg = json.loads(response.body)
    print(msg["message"])

התוצאה:

email 1 has been sent

 

אפשר לשלוח לרשימה של מיילים באמצעות לולאה:

@app.get('/test-async')
def testAsync():
    start_time = time.process_time()
    
    emails = ["[email protected]", "[email protected]","[email protected]"]
    for idx, email in enumerate(emails):
        response = asyncio.run(sendAsync(email, idx))
        msg = json.loads(response.body)
        print(msg["message"])
    
    end_time = time.process_time()
    
    print("Ran %s seconds" % (end_time - start_time))

תוצאה:

email 0 has been sent
email 1 has been sent
email 2 has been sent
Ran 0.09052418200000001 seconds

מדריכים נוספים בסדרה ללימוד FastApi

  1. FastAPI - היכרות עם ספרית הקוד הטובה ביותר של פיתון להקמת אפליקציות אינטרנט
  2. אפליקצית אינטרנט עם FastApi - הקמת מסד הנתונים
  3. קלאס לניהול משתמשים באפליקציית FastApi

 

לכל המדריכים בסדרה ללימוד פייתון

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

הוסף תגובה חדשה

 

= 9 + 8