Skip to main content

Client

Client is the only class most users ever touch. It holds a requests.Session, applies the retry policy, calls user-supplied hooks, and raises typed exceptions. Extension is done by passing callables at construction — not by subclassing.

Constructing a client​

from beavercore import Client, RetryPolicy

client = Client(
base_url="https://api.example.com",
auth=my_auth,
refresh=my_refresh,
retry=RetryPolicy(max_attempts=4),
throttle=my_throttle,
observer=my_observer,
timeout=15.0,
verify_ssl=True,
session=None,
)

Only base_url is required. Every other argument has a sensible default and can be omitted.

Constructor options​

argdefaultnotes
base_urlrequiredTrailing slash optional. Paths passed to request methods are joined onto this.
authNone(request_kwargs) -> None. Mutate the dict to attach credentials.
refreshNone() -> bool. Called once on the first 401; return True to retry.
retryRetryPolicy()See Retries & Errors.
throttleNone() -> None. Called before every attempt — bring your own rate limiter.
observerNone(event_dict) -> None. Receives lifecycle events.
timeout30Seconds. Applied to every request unless overridden per-call.
verify_sslTrueSet False for self-signed internal endpoints.
sessionNoneProvide a preconfigured requests.Session for custom adapters.

HTTP methods​

Each verb takes a path and the same keyword arguments as requests.Session.request:

client.get("/items", params={"page": 1})
client.post("/items", json={"name": "widget"})
client.put("/items/42", json={"name": "renamed"})
client.patch("/items/42", json={"status": "archived"})
client.delete("/items/42")

Every method returns a requests.Response. The response is only returned when the status is 2xx — any other status either raises or triggers the retry loop.

Context manager usage​

The recommended pattern is a with block, which guarantees the underlying session is closed:

with Client("https://api.example.com") as client:
data = client.get("/thing").json()
# session is closed here

Manual lifecycle management is also supported:

client = Client("https://api.example.com")
try:
data = client.get("/thing").json()
finally:
client.close()

Supplying a custom session​

For adapter-level customization — custom TLS, SOCKS proxies, retry handling at the transport layer — provide a preconfigured requests.Session:

import requests
from requests.adapters import HTTPAdapter

session = requests.Session()
session.mount("https://", HTTPAdapter(pool_connections=20, pool_maxsize=100))

client = Client("https://api.example.com", session=session)

BeaverCore does not configure urllib3's retry layer — all retry behavior is handled above the session. The session is used purely as a transport.

Overriding timeout per-call​

The timeout passed at construction becomes the default. Any single request can override it:

client.get("/slow-endpoint", timeout=120.0)

The same applies to headers, params, and any other keyword accepted by requests.