Skip to content

client

Synchronous WarmHub client.

The client owns an httpx connection pool, so it is closable:

with WarmHubClient(access_token=token) as client:
...
client = WarmHubClient(access_token=token) # also valid
client.close()

An httpx.Client passed as http_client= belongs to the caller and is never closed by the SDK.

Unlike the async client, this one accepts only synchronous token providers. An awaitable provider raises a named TypeError pointing at AsyncWarmHubClient rather than blocking a thread on someone else’s event loop. Sync owner: WarmHubClient. Async owner: AsyncWarmHubClient.

close() -> None

Close the connection pool, if this client opened it.

from_env(*, api_url: str | Unset = UNSET, http_client: httpx.Client | Unset = UNSET, access_token: AccessTokenProvider | Unset = UNSET, auth: AuthProvider | Unset = UNSET, function_logs: str | Unset = UNSET, client: Mapping[str, str] | ClientIdentity | Unset = UNSET, client_flags: Sequence[str] | Unset = UNSET, **unknown_options: NoReturn) -> WarmHubClient

Construct from WH_TOKEN and WARMHUB_API_URL.

Explicit keyword arguments win over the environment. The default constructor reads neither variable.

repository(locator: str) -> RepositoryClient

Bind a repository handle to locator.

Accepts the slug the UI shows and the wref a previous read returned:

sensors = client.repository("acme/sensors")
sensors = client.repository("wh:acme/sensors/Reading/probe-1")

Anything else raises ValueError naming the input and both accepted forms. Deliberately not a WarmHubError: no request was made, so a caller’s except WarmHubError around a network call must not swallow what is a typo in a literal.

with_access_token(access_token: AccessTokenProvider) -> WarmHubClient

A second client authenticating as access_token, on THIS pool.

The synchronous twin of AsyncWarmHubClient.with_access_token, including the pool-ownership contract: the derived client borrows this client’s httpx pool rather than opening a second one, so derived.owns_transport is False, derived.close() leaves the pool open, and a derived client outliving the owner it borrowed from raises the closed-client RuntimeError.

function_logs is deliberately not carried across; the clone reverts to the default mode, matching the reference.

aclose() -> None

Close the connection pool, if this client opened it.

from_env(*, api_url: str | Unset = UNSET, http_client: httpx.AsyncClient | Unset = UNSET, access_token: AccessTokenProvider | Unset = UNSET, auth: AuthProvider | Unset = UNSET, function_logs: str | Unset = UNSET, client: Mapping[str, str] | ClientIdentity | Unset = UNSET, client_flags: Sequence[str] | Unset = UNSET, **unknown_options: NoReturn) -> AsyncWarmHubClient

Construct from WH_TOKEN and WARMHUB_API_URL.

Explicit keyword arguments win over the environment. The default constructor reads neither variable — see the module docstring for why that distinction is load-bearing rather than stylistic.

repository(locator: str) -> AsyncRepositoryClient

Bind a repository handle to locator.

Accepts the slug the UI shows and the wref a previous read returned:

sensors = client.repository("acme/sensors")
sensors = client.repository("wh:acme/sensors/Reading/probe-1")

Anything else raises ValueError naming the input and both accepted forms. Deliberately not a WarmHubError: no request was made, so a caller’s except WarmHubError around a network call must not swallow what is a typo in a literal.

with_access_token(access_token: AccessTokenProvider) -> AsyncWarmHubClient

A second client authenticating as access_token, on THIS pool.

Ports withAccessToken (packages/sdk-ts/src/index.ts:6569), which copies exactly five things onto the clone: the backend URL, the fetch implementation, the new token, the client identity, and the client flags — so a token-scoped clone of a CLI client keeps reporting warmhub-cli/… rather than reverting to the SDK default, and stays opted into whatever the parent declared. function_logs is NOT among them, in either language: a clone reverts to the default mode.

Pool ownership. The derived client SHARES this client’s httpx connection pool, through the same http_client= injection a caller would use. That sharing is the point of the method — the alternative, constructing a second client, opens a second pool. Three consequences follow, and they are the contract:

  • derived.owns_transport is False. The pool is borrowed.
  • await derived.aclose() does not close the pool. This client remains usable, and remains the owner.
  • Once THIS client closes a pool it owns, the derived client’s calls fail the way any client on a closed injected transport fails — a RuntimeError naming a closed client, per the registered deviation client.closed_is_runtime_error. Close the derived clones first, or keep the parent alive for as long as they are.