Асинхронный вызов API¶
Клиенты ресурсов (tracker.issues.get(...)) синхронные. Для кода на asyncio используйте слой,
на котором они построены: у каждого ресурса есть модуль endpoints, который описывает его
запросы и ничего не отправляет, а асинхронная сессия отправляет любой из них.
import asyncio
from pydantic import SecretStr
from ycli.yandex import tracker
from ycli.yandex.core.auth import OAuthTokenAuth
from ycli.yandex.core.session import connect_async
from ycli.yandex.tracker.boards import endpoints as boards
from ycli.yandex.tracker.issues import endpoints as issues
from ycli.yandex.tracker.issues.models import IssueSearch
async def main() -> None:
session = connect_async(
tracker.SERVICE.profile,
auth=OAuthTokenAuth(SecretStr("…")),
organization_id="…",
)
try:
board = await session.send(boards.get(31)) # один запрос
search = issues.search(IssueSearch(filter={"queue": "DE"}), expand=None)
async for issue in session.iterate(search, limit=500): # все страницы
print(issue.key, issue.summary)
finally:
await session.aclose()
asyncio.run(main())
Что вызывать¶
| Нужно | Вызов | Что возвращает |
|---|---|---|
| сессия сервиса | connect_async(<service>.SERVICE.profile, auth=…, organization_id=…) |
AsyncSession |
| один запрос | await session.send(endpoints.<operation>(…)) |
разобранную модель, как метод клиента |
| листание | async for item in session.iterate(endpoints.<operation>(…), limit=N) |
элементы, страница за страницей; limit=None читает все |
| завершить | await session.aclose() |
закрывает соединения |
- Сервис —
ycli.yandex.tracker,ycli.yandex.wikiилиycli.yandex.forms; в егоSERVICE.profileлежат базовый адрес и имя заголовка организации. - Функция в
endpointsназывается так же, как метод клиента, который её отправляет:tracker.boards.update(...)отправляетboards.endpoints.update(...). Имя, совпадающее со встроенным в Python, получает подчёркивание:endpoints.list_. Методы перечислены в справочнике SDK; функция принимает те же значения, но может требовать аргумент, у которого в методе есть значение по умолчанию (expand=Noneвыше). - Эндпоинт, который возвращает листание (
Paged), передаётся вiterate, любой другой — вsend. auth—OAuthTokenAuthдля OAuth-токена илиIAMTokenAuthдля IAM-токена, оба изycli.yandex.core.auth.
Ошибки, повторы и журнал — те же, что у синхронных клиентов: неудачный вызов поднимает
типизированную ошибку из ycli.yandex.errors, а запрос, который безопасно повторить,
повторяется.
Много вызовов сразу¶
Одна сессия обслуживает параллельные вызовы:
from ycli.yandex.wiki.pages import endpoints as pages
found = await asyncio.gather(
*(
session.send(pages.get(slug, fields=None, revision_id=None, raise_on_redirect=False))
for slug in ("team/a", "team/b", "team/c")
)
)
Чего это не даёт¶
У метода клиента, который делает больше одного запроса, асинхронной пары нет: ожидание конца долгой операции, загрузка файла частями, сборка тела запроса из нескольких аргументов. В асинхронном коде эти шаги вы делаете сами из тех же эндпоинтов. Асинхронный клиент с полным набором методов отслеживается в #321.