Async Python үндэс
Та вэб сайтаас өгөгдөл татахдаа хариу ирэхийг хүлээж суудаг — энэ хугацаанд компьютер юу ч хийхгүй байна. Async programming нь хүлээх хугацаанд өөр ажил хийх боломж олгодог. FastAPI нь async дээр суурилсан тул энэ ойлголт маш чухал.
Синхрон ба асинхрон харьцуулбал
Ресторанд захиалга хийхтэй зүйрлэвэл: синхрон зөлөг нэг хүний захиалгыг хүлээж аваад гал тогоонд өгч, хоол бэлэн болтол зогсоод, авч ирнэ — дараагийн зочинд ойртдоггүй. Асинхрон зөлөг олон хүний захиалгыг зэрэг авч, хоол бэлэн болох зуур өөр зочинд үйлчилнэ.
import asyncio
import time
# Синхрон — нэг нэгээр хүлээнэ
def синхрон_татах(url):
time.sleep(2) # хүлээлтийг дуурайлгав
return f"{url} — татагдлаа"
эхлэл = time.time()
print(синхрон_татах("сайт-А"))
print(синхрон_татах("сайт-Б"))
print(f"Нийт хугацаа: {time.time() - эхлэл:.1f}с") # ~4 секунд
# Асинхрон — зэрэгцүүлэн хүлээнэ
async def асинхрон_татах(url):
await asyncio.sleep(2) # хүлээх үед өөр ажил хийнэ
return f"{url} — татагдлаа"
async def гол():
эхлэл = time.time()
а, б = await asyncio.gather(
асинхрон_татах("сайт-А"),
асинхрон_татах("сайт-Б"),
)
print(а)
print(б)
print(f"Нийт хугацаа: {time.time() - эхлэл:.1f}с") # ~2 секунд
asyncio.run(гол())
Хоёр татах үйлдэл зэрэгцэн гүйцэтгэгдсэн тул 4 биш 2 секунд л зарцуулна — async-ийн гол давуу тал энэ.
async ба await түлхүүр үгс
import asyncio
# async def — асинхрон функц тодорхойлно
async def мэндлэх(нэр: str, хугацаа: float):
await asyncio.sleep(хугацаа) # await — дуусахыг хүлээнэ
print(f"Сайн уу, {нэр}!")
async def гол():
# gather — олон coroutine-ийг зэрэг ажиллуулна
await asyncio.gather(
мэндлэх("Болд", 1.0),
мэндлэх("Сарнай", 0.5),
мэндлэх("Төгс", 1.5),
)
asyncio.run(гол())
# Сайн уу, Сарнай! (0.5с дараа)
# Сайн уу, Болд! (1.0с дараа)
# Сайн уу, Төгс! (1.5с дараа)
async def функцийг шууд дуудаж болохгүй — await эсвэл asyncio.run() шаарддаг.
FastAPI-д async ашиглах
FastAPI нь async def болон энгийн def хоёуланг дэмждэг:
from fastapi import FastAPI
import asyncio
import httpx # async HTTP client — pip install httpx
app = FastAPI()
@app.get("/нэгэн_зэрэг")
async def олон_эх_сурвалж():
async with httpx.AsyncClient() as client:
# Хоёр хүсэлтийг зэрэгцүүлэн илгээнэ
хариу_а, хариу_б = await asyncio.gather(
client.get("https://httpbin.org/delay/1"),
client.get("https://httpbin.org/delay/1"),
)
return {
"А_статус": хариу_а.status_code,
"Б_статус": хариу_б.status_code,
"тайлбар": "хоёулаа зэрэг дууслаа"
}
@app.get("/энгийн")
def энгийн_endpoint():
# IO-гүй, тооцооллын endpoint — энгийн def хангалттай
return {"утга": sum(range(1_000_000))}
IO хүлээдэг (сүлжээ, файл, өгөгдлийн сан) endpoint-т async def ашиглах нь FastAPI-г хамгийн үр дүнтэй ажиллуулна.
asyncio.timeout — хугацааны хязгаар
Хэт удаан хариу буцаадаг хүсэлтэд хугацааны хязгаар тогтоох нь чухал:
import asyncio
async def удаан_ажил():
await asyncio.sleep(10)
return "дууслаа"
async def гол():
try:
async with asyncio.timeout(3): # 3 секундаас илүүгүй
үр_дүн = await удаан_ажил()
print(үр_дүн)
except asyncio.TimeoutError:
print("Хугацаа дуусав — хариу ирсэнгүй")
asyncio.run(гол())
# Хугацаа дуусав — хариу ирсэнгүй
Async нь эхэндээ шинэ сэтгэлгээ шаарддаг боловч FastAPI, вэб хусах, өгөгдлийн сангийн ажиллагааг ойлгоход маш хэрэгтэй суурь мэдлэг.
Дараагийн хичээлд:
NumPy үндэс — тоон тооцоолол, массив үйлдлүүд, өгөгдлийн шинжилгээний суурь болох NumPy-г эхлэгчдэд ойлгомжтойгоор сурна.