Clients & requests¶
This chapter covers constructing the resq HTTP clients and issuing sync and async
requests. The two client flavors are Requests and Session.
resq exposes two clients with the SAME unified verb surface; the mode (sync/async) and
engine are chosen by the adapter argument:
Requests— a fresh connection per call in sync mode (module-levelrequestsbehavior).Session— one persistentrequests.Sessionreused across sync calls (shared pool and cookie jar).
In async mode both flavors behave identically: each instance owns one long-lived
httpx.AsyncClient (held internally), shared across that instance's calls and reloads;
release it via async with (preferred) or await client.close().
Construction¶
Two different timeouts
The constructor timeout is the network timeout (connect/read), set once on the
engine. It is NOT the polling window.
adapter selects the mode+engine and is fixed per instance.
from resq import Requests, Session
client = Requests("https://api.example.com", adapter="requests", timeout=5)
async_client = Session("https://api.example.com", adapter="httpx", timeout=5)
Valid adapter values are exactly 'requests' and 'httpx'; any other value raises
ValueError (before an adapter is built).
Sync requests (adapter='requests')¶
The unified verbs return the wrapper directly:
with Requests("https://api.example.com", adapter="requests", timeout=5) as client:
r = client.get("/users/42", params={"detail": "full"})
r = client.post("/users", json={"name": "ada"})
r = client.put("/users/42", json={"name": "ada"})
r = client.delete("/users/42")
r = client.patch("/users/42", json={"role": "admin"})
r = client.head("/users/42")
r = client.options("/users/42")
Any keyword arguments (params, headers, json, data, cookies, files, …) are
forwarded verbatim to the underlying engine.
Async requests (adapter='httpx')¶
The SAME verbs return a coroutine that resolves to the wrapper — await them:
async with Session("https://api.example.com", adapter="httpx", timeout=5) as client:
r = await client.get("/users/42", params={"detail": "full"})
r = await client.post("/users", json={"name": "ada"})
Release the async engine via async with (preferred) or await client.close().
Closing¶
- Sync mode:
with(or no explicit close — therequests.Sessionheld bySessionis released by garbage collection, not closed explicitly). - Async mode:
async with, orawait client.close()— releases the long-livedhttpx.AsyncClient(idempotent; a coroutine).
Behavior & preconditions¶
- One instance = one mode, fixed at construction by
adapter. - Paths are joined onto
base_url; a leading/on the path is normalized so the same path string behaves identically across modes. - The constructor
timeoutis the network timeout; the method-leveltimeout(when passed) is the polling window.delay(default 1.0) sets the seconds between polling attempts and is ignored when the methodtimeoutis not passed. - With the method
timeoutleft atNone(default), a verb issues a single request and does not auto-raise on a non-2xx status — inspectr.okor callr.raise_for_status()yourself. - The verb name is the same in both modes; in async mode it must be awaited.