Сохранить и изменить запрос перед отправкой#
Метод request(...) создаёт неизменяемое значение операции без сети. Сохраните его в очереди,
измените через evolve(...), затем отправьте методом send(...).
→ Request · GET /items?page=1&perPage=2
← Response · 200 OK
{"items": ["keyboard", "mouse"], "next_page": 2}
# examples/request_values.py
@dataclass(frozen=True, slots=True, kw_only=True)
class ListItems(HttpOperation[Page]):
"""Every field of the request is a field of this class, defaults included."""
__http__ = Http.get("/items", operation_id="listItems")
page: Query[int] = 1
per_page: Annotated[int, markers.Query("perPage")] = 2
class CatalogApi(SyncApi):
list_items = op(ListItems)
request(...) использует конструктор ListItems, поэтому применяет те же значения по умолчанию
и проверяет те же обязательные поля, что прямой вызов list_items(...).
# examples/request_values.py
# One value, evolved per page: no Pages helper, no cursor object, no callback.
request = catalog.list_items.request(per_page=2)
collected: list[str] = []
while True:
page = catalog.list_items.send(request)
collected.extend(page.items)
if page.next_page is None:
break
request = catalog.list_items.evolve(request, page=page.next_page)
print(f"collected: {', '.join(collected)}")
# A queue of requests is a list of values; nothing is sent until it is.
pending = [catalog.list_items.request(page=number, per_page=2) for number in (3, 1)]
for item in pending:
print(f"queued page: {catalog.list_items.send(item).items[0]}")
evolve(request, page=...) возвращает новое значение через адаптер модели. Исходный запрос не
меняется. send(request) выполняет его, а обычный список хранит очередь без отдельной абстракции.
Файл примера целиком
"""Treat a request as a value: build it once, change one field, send it again.
Paging is the example everyone has: the same call, one number apart. With the request as a
value there is no paging abstraction to learn — ``request()`` builds it, ``evolve()`` copies
it with the next page, ``send()`` sends it, and a queue of pending requests is a plain list.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Annotated
from eazy_sdk import Http, HttpOperation, Query, SyncApi, op
from eazy_sdk.request import markers
from examples.docs.request_site import request_client
@dataclass(frozen=True, slots=True)
class Page:
items: tuple[str, ...]
next_page: int | None
# docs:operation:start
# examples/request_values.py
@dataclass(frozen=True, slots=True, kw_only=True)
class ListItems(HttpOperation[Page]):
"""Every field of the request is a field of this class, defaults included."""
__http__ = Http.get("/items", operation_id="listItems")
page: Query[int] = 1
per_page: Annotated[int, markers.Query("perPage")] = 2
class CatalogApi(SyncApi):
list_items = op(ListItems)
# docs:operation:end
def main() -> None:
with request_client() as client:
catalog = CatalogApi(client)
# docs:flow:start
# examples/request_values.py
# One value, evolved per page: no Pages helper, no cursor object, no callback.
request = catalog.list_items.request(per_page=2)
collected: list[str] = []
while True:
page = catalog.list_items.send(request)
collected.extend(page.items)
if page.next_page is None:
break
request = catalog.list_items.evolve(request, page=page.next_page)
print(f"collected: {', '.join(collected)}")
# A queue of requests is a list of values; nothing is sent until it is.
pending = [catalog.list_items.request(page=number, per_page=2) for number in (3, 1)]
for item in pending:
print(f"queued page: {catalog.list_items.send(item).items[0]}")
# docs:flow:end
if __name__ == "__main__":
main()
Запуск: uv run python examples/request_values.py.
collected: keyboard, mouse, monitor, cable, lamp
queued page: lamp
queued page: keyboard
Для настроек одного вызова передайте options= в send. Метод send_with_response вернёт
ResponseEnvelope вместе с типизированным значением, как и .with_response у прямого вызова.