Repository navigation
Add transport injection, error policies, and session renewal to clients #329
Copy link
Copy link
Closed
Copy link
Labels
enhancementNew feature or requestNew feature or requestready-for-agentFully specified and ready for an AFK agentFully specified and ready for an AFK agent
Description
Problem Statement
Users and automated systems operating the CANFAR Science Platform encounter three key limitations in the existing client and CLI:
- Connection Pool Sharing & Multi-User Service Inefficiency: Services running on behalf of multiple users (e.g. Science Portal, workflow orchestrators) cannot share a connection pool across users. Injected transports were previously handled via private overrides that were removed, and client shutdown previously closed caller-owned transports. Furthermore, using transports with per-user X.509 client certificates leads to silent credential dropping because underlying HTTP libraries bypass client certificates when custom transports are set.
- Error Ambiguity in Session Lifecycle Methods: Session operations (
create,info,logs,events,destroy) fail silently to[],None, orFalseunder default behavior. Callers cannot differentiate between transient platform outages (5xx, connection timeouts) and request rejections (4xx, quota limits, authorization failures). When operating on batches of sessions, callers need both the successfully processed session identifiers and the specific errors for failed ones. - Inability to Renew Interactive Sessions Programmatically or via CLI: Interactive Sessions on a Science Platform Server expire after their configured lifetime (typically 4 days). While the Science Platform backend and Science Portal support session renewal via
POST session/{id}?action=renew, the CANFAR Python client and CLI have no renewal mechanism, forcing users to manually interact with the web interface to prevent session expiration. - Code Maintainability: The core Session management client module has grown excessively large, mixing top-level client facades, batch task dispatching, regex matching, URL formatting, and error-handling utilities.
Solution
Deliver a unified enhancement covering:
- Public Transport Injection on HTTP Client: Support
transporton the HTTP client configuration, enabling shared connection pools for Bearer token requests, preserving caller ownership by preventing client closes from destroying injected pools, and validating against invalid sync/async or X.509 pairings. - Standardized Error Handling Policy (
errors="ignore" | "raise"): Introduce a configurable error mode at both the client instance level (defaulting to"ignore"and overridable via environment variable) and per-method keyword overrides, raising a structured exception containing partial results and per-item HTTP errors on failure. - Consolidated Session Helpers: Extract internal session-management utilities, batch executors, URL builders, and failure handlers into a consolidated helper module, keeping the Session client lean and modular.
- Interactive Session Renewal API & CLI: Add
renew()to both synchronous and asynchronous Session clients returning per-session success booleans, alongside a dedicatedcanfar renewCLI command that extends session lifetimes immediately with clear human-readable status.
Implementation Decisions
1. Transport Injection on HTTPClient
HTTPClientgains an optionaltransportsetting accepting either a synchronous or asynchronoushttpx2transport.- The transport field is excluded from serialization and environment variable binding.
- Client factory logic validates transport compatibility:
- Synchronous
clientrequires a synchronousBaseTransport. - Asynchronous
asynclientrequires anAsyncBaseTransport. - Mismatches raise
TypeError.
- Synchronous
- Combining
transportwith X.509 client credentials (runtimecertificateor active X.509 Authentication Record) raisesValueErrorat construction, because custom transports bypass client SSL verification contexts. - Injected transports are wrapped so that
client.close()andclient.aclose()leave the underlying transport open; caller retains ownership and responsibility for closing the pool. - Request timeouts continue to be enforced per request; connection limits are managed directly on the injected transport.
2. Error Mode Policy (errors="ignore" | "raise")
SessionandAsyncSessionsupport anerrorsfield taking"ignore"or"raise", defaulting to"ignore", configurable via environment variableCANFAR_ERRORS.- All session lifecycle methods (
create,info,logs,events,destroy,destroy_with, andrenew) accept an optional keyword-onlyerrors: Literal["ignore", "raise"] | None = Noneparameter. WhenNone, the instance-levelself.errorsapplies. - Under
errors="raise":- All requests in a batch run to completion first.
- If any request encountered an
httpx2.HTTPError, a newSessionRequestErrorexception is raised. - Prototype exception contract:
class SessionRequestError(Exception): operation: str results: Any errors: dict[str | int, HTTPError]
- The first failure is attached as
__cause__. - Authentication errors and parameter validation errors continue to raise immediately regardless of error mode.
fetch()andstats()retain their existing behavior of raising immediately on HTTP error.
3. Helper Consolidation
- Extract internal helpers from the session client into a dedicated session helper module under the
canfar/helpers/namespace. - Relocated utilities include URL path construction, identifier normalization, task result filtering, regex compilation, connection URL resolution, deletion failure handling, and renewal failure handling.
- Private failure helper prototype:
def _renew(session_id: str, exc: BaseException | None = None) -> bool: ...
4. Interactive Session Renewal
- Add
renew(ids, *, errors=None) -> dict[str, bool]to bothSessionandAsyncSession. - HTTP request uses
POST session/{session_id}with form parameteraction=renew. - Returns a mapping of session ID to boolean indicating whether renewal succeeded.
- Under
errors="raise", failures populateresults[session_id] = Falseand record the exception inSessionRequestError.errors. - Sync and async method signatures remain strictly parallel and are tracked in the lifecycle signature suite.
5. CLI Command canfar renew
- Implement
canfar.cli.renew:renew_sessionsaccepting one or more session IDs. - Registered lazily in root CLI command dictionary under the
"Session Management"panel withno_args_is_help=True. - Non-destructive operation: executes immediately without interactive confirmation prompts.
- Emits active server banner and prints formatted human-readable success and error summaries.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestready-for-agentFully specified and ready for an AFK agentFully specified and ready for an AFK agent
Activity
shinybrar commentedon Oct 7, 2026
Jira: CADC-16204. This issue holds the authoritative spec.
shinybrar commentedon Oct 8, 2026
@sipho-sarao Here is the proposed plan for implementing support for custom transports and a regimen to re-raise errors in the canfar clients. Any feedback from you and your team would be welcomed, especially if this implementation checks all your goals. Let us know
[-]Add public transport and errors options to Session clients[/-][+]Add transport injection, error policies, and session renewal to Session clients[/+]shinybrar commentedon Oct 9, 2026
Implemented in #331.
[-]Add transport injection, error policies, and session renewal to Session clients[/-][+]Add transport injection, error policies, and session renewal to clients[/+]