API барои рӯйхати корҳо
Аз масирҳо то API-и мукаммал
Вақте барнома хондану тағйир додани сабтҳоро меомӯзад, саволҳои нав пайдо мешаванд: кадом тарзҳои ҷобаҷогузорӣ иҷозатанд, ҷамъбастро чӣ гуна нишон диҳем ва файли калонро чӣ гуна ҷудо кунем. Мавзӯи охирин воситаҳои ташкили API-ро якҷо мекунад. Корбар новобаста аз масири интихобкардааш бояд қоидаҳои якхела гирад.
Дар ин ҷо қиматҳои маҳдуд, калиди ҷобаҷогузорӣ, ҷамъбаст ва роутерро меомӯзем. Код маҷмӯаҳои хурди берун аз рӯйхати корҳоро истифода мекунад, то усулҳоро бе ҳалли тайёри машқҳои ниҳоӣ нишон диҳад. Ҳамаи мисолҳо мустақиланд.
Literal маҷмӯи фармонҳоро маҳдуд мекунад
Literal аз typing маънои «танҳо ҳамин қиматҳо»-ро дорад. Бар хилофи str, он матни дилхоҳро қабул намекунад. FastAPI қиматро пеш аз даъвати функсия месанҷад ва /docs рӯйхати интихобҳоро нишон медиҳад. Барои маҷмӯаҳои номдор Enum низ истифода мешавад; барои қиматҳои сатрӣ синфи вориси str ва Enum қулай аст. Дар мисол режим дақиқ, бо назардошти ҳарфҳои калону хурд, интихоб мешавад.
from typing import Literal
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
@app.get("/view")
def view(mode: Literal["short", "full"] = "short"):
return {"full": mode == "full"}
client = TestClient(app)
print(client.get("/view").json())
print(client.get("/view?mode=full").json())
print(client.get("/view?mode=FULL").status_code)
Баромад:
{'full': False}
{'full': True}
422
Калиди ҷобаҷогузорӣ ва ҳалли баробарӣ
sorted рӯйхати нав сохта, барои ҳар ҷузъ key-ро даъват мекунад. Калиди кортежӣ аз чап ба рост муқоиса мешавад: ҷузъи дуюм танҳо ҳангоми баробарии якум лозим аст. Манфӣ кардани адад самти як меъёрро иваз мекунад; reverse=True самти тамоми муқоисаро дигар мекунад. Дар поён аввал рӯзҳои барвақт ва дар дохили рӯз баҳои калонтар меоянд. Ин тартиб аз тартиби масъалаҳои курс фарқ мекунад.
rows = [(2, 8), (1, 3), (1, 9)]
ordered = sorted(rows, key=lambda row: (row[0], -row[1]))
print(ordered)
print(rows)
print(sorted(["b", "A", "a"], key=str.lower))
Баромад:
[(1, 9), (1, 3), (2, 8)]
[(2, 8), (1, 3), (1, 9)]
['A', 'a', 'b']
Ҷамъбаст: ҳисоб ва сериализатсия
Ҷамъбаст (aggregation) чанд сабтро ба хулосаи кӯтоҳ табдил медиҳад. sum ададҳоро ҷамъ мекунад ва Counter қиматҳои якхеларо мешуморад. Пеш аз тақсим ҳолати маҷмӯаи холиро алоҳида баррасӣ кунед. Амали // натиҷаи тақсимро ба поён гирд мекунад; барои қиматҳои ғайриманфӣ ин дар фоизҳои бутун қулай аст. Дар JSON калидҳои объект ҳамеша сатранд, ҳатто агар дар Python адад бошанд. Дар поён гурӯҳҳои баҳоро мешуморем, на фоизҳои ниҳоии корҳоро.
from collections import Counter
from fastapi import FastAPI
from fastapi.testclient import TestClient
scores = [2, 2, 5]
print(sum(scores), 8 // 3)
print(sum([]), bool([]))
app = FastAPI()
@app.get("/groups")
def groups():
return dict(Counter(scores))
print(TestClient(app).get("/groups").json())
Баромад:
9 2
0 False
{'2': 2, '5': 1}
APIRouter масирҳои вобастаро ҷамъ мекунад
Роутер гурӯҳи масирҳоест, ки ба барнома пайваст мешавад. prefix ба ҳар роҳи маҳаллӣ илова мешавад; tags сабтҳоро дар /docs гурӯҳбандӣ мекунад, вале URL-ро тағйир намедиҳад. Аввал масирҳоро дар роутер сабт карда, баъд include_router-ро даъват мекунанд. Дар лоиҳаи калон коди роутерро дар модули ҷудо гузошта, ба файли асосӣ ворид мекунанд. Мисол дар як файл аст, то фавран иҷро шавад.
from fastapi import FastAPI, APIRouter
from fastapi.testclient import TestClient
router = APIRouter(prefix="/library", tags=["library"])
@router.get("/count")
def count_books():
return {"count": 3}
app = FastAPI()
app.include_router(router)
client = TestClient(app)
print(client.get("/library/count").json())
print(client.get("/count").status_code)
Баромад:
{'count': 3}
404
async def ва интизории вуруду баромад
async def функсияи асинхронӣ месозад. Дар нуқтаи await он ҳангоми интизории амали асинхронӣ метавонад иҷроро ба дархостҳои дигар диҳад. Ин бо муштарии асинхронии API ё пойгоҳи додаҳо муфид аст, вале худ аз худ ҳисобро тез намекунад. Барои мисоли такроршавандаи бе шабакаи беруна asyncio.sleep(0) истифода мекунем: он навбатро ба даври рӯйдодҳо медиҳад, на натиҷаи сохтаи шабакаро.
import asyncio
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
@app.get("/ready")
async def ready():
await asyncio.sleep(0)
return {"ready": True}
r = TestClient(app).get("/ready")
print(r.status_code, r.json())
Баромад:
200 {'ready': True}
Дар дохил чӣ рӯй медиҳад
Ҳангоми пайваст кардани роутер барнома масирҳои онро бо префикс ва маълумоти иловагӣ меафзояд. Барои дархост аввал масир интихоб шуда, баъд параметрҳо санҷида, вобастагиҳо ҳисоб ва коркардкунанда иҷро мешавад. Навъи Literal дар ҳамон санҷише иштирок мекунад, ки int ё модел истифода мебаранд. Ҷобаҷогузорӣ ва ҷамъбаст амалҳои одии Python дар дохили коркардкунандаанд; FastAPI сарҳади HTTP ва сериализатсияро идора мекунад.
Коркардкунандаҳои асинхронӣ дар даври рӯйдодҳо иҷро мешаванд, FastAPI коркардкунандаҳои одии def-ро ба риштаҳои корӣ медиҳад. Даъвати боздоранда дар async def даври рӯйдодҳоро ба таъхир меандозад; ҳамтои асинхронӣ ё берун бурдани кори боздоранда лозим аст. Луғати умумии барномаи таълимӣ дар як раванд зиндагӣ карда, пас аз азнавоғозкунӣ гум мешавад. Барои додаҳои доимӣ ва чанд раванд пойгоҳи додаҳо бо тағйироти ҳамоҳангшуда лозим аст.
Хатоҳои маъмул ва ислоҳи онҳо
mode: strғалатнависиро ҳам мисли интихобҳои дуруст қабул мекунад.Literal[...]ёEnum-и мувофиқ истифода кунед.sorted(rows, key=..., reverse=True)меъёри дуюмро ҳам чаппа мекунад. Самтҳоро дар калиди кортежӣ алоҳида диҳед.@router.get("/library/count")боprefix="/library"оғози роҳро такрор мекунад. Дар роутер танҳо қисми маҳаллии/count-ро нависед.- Танҳо сохтани
APIRouter()кофӣ нест: беapp.include_router(router)масирҳои он дар барнома дастрас намешаванд. time.sleep(1)дарasync defдаври рӯйдодҳоро бозмедорад. Барои таваққуфи асинхронӣawait asyncio.sleep(1)ва барои амалҳои дигар роҳи мувофиқи иҷроро истифода кунед.
Ёддошт
| Мақсад | Усул |
|---|---|
| Интихобҳои муайян | Literal[...], Enum |
| Чанд меъёр | key=lambda x: (first, second) |
| Нигоҳ доштани рӯйхати аввал | sorted(...) |
| Ҷамъбаст | sum, Counter, санҷиши додаҳои холӣ |
| Тақсим кардани API | APIRouter(prefix=...), include_router |
| Интизории вуруду баромади асинхронӣ | async def ва await |