Skip to content

Add an asynchronous aiohttp Redfish client - #190

Open
jyundt wants to merge 7 commits into
DMTF:mainfrom
jyundt:feat/aiohttp-client
Open

Add an asynchronous aiohttp Redfish client#190
jyundt wants to merge 7 commits into
DMTF:mainfrom
jyundt:feat/aiohttp-client

Conversation

@jyundt

@jyundt jyundt commented Aug 10, 2026

Copy link
Copy Markdown

Summary

Add a separate, resource-neutral asynchronous Redfish client implemented with aiohttp while leaving the existing synchronous API unchanged.

The new redfish.aio package supports caller-owned sessions, Redfish session authentication, HTTP Basic authentication, cached responses, configurable timeouts, and same-origin URL validation.

Closes #189.

Motivation

Asyncio applications need nonblocking Redfish communication without maintaining a separate transport implementation. In particular, Home Assistant requires integrations to use its shared aiohttp.ClientSession so connection pooling, TLS configuration, proxy behavior, and session lifecycle remain under application control.

This work supports the generic Redfish integration proposed in home-assistant/core#177991.

Implementation

The asynchronous transport:

  • Requires a caller-provided aiohttp.ClientSession.
  • Never creates or closes the caller's session.
  • Provides coroutine-based get, head, post, put, patch, and delete methods.
  • Provides a convenience method for retrieving and validating the standard Redfish service root.
  • Supports default and per-request timeouts.
  • Fully reads and caches responses before returning them.
  • Does not follow redirects.
  • Accepts relative, scheme-relative, and absolute advertised targets only when they resolve to the configured Redfish origin.
  • Treats implicit and explicit default ports as the same origin.
  • Prevents caller-provided headers from replacing or duplicating the configured authentication credentials.
  • Translates aiohttp connection and timeout failures into Redfish-specific exceptions.
  • Classifies authentication, HTTP, and protocol failures during authentication and service-root retrieval.
  • Is available through the optional redfish[aiohttp] dependency.

Authentication and session lifecycle support:

  • Uses Redfish session authentication by default and also supports HTTP Basic authentication.
  • Requires HTTPS whenever credentials or a session token are used.
  • Discovers the session collection through the service root.
  • Uses the standard session collection fallback when a nonconforming service rejects unauthenticated service-root access.
  • Captures the session token and advertised session location returned by the service.
  • Accepts an existing session token and optional session location supplied by the caller.
  • Serializes login, logout, and session-refresh operations so concurrent operations cannot leak or resurrect sessions.
  • Terminates the advertised Redfish session without closing the caller-owned ClientSession.
  • Preserves restricted sessions returned with PasswordChangeRequired, including the advertised account URI, so callers can change the password before logging out.
  • Cleans up a restricted session if asynchronous context-manager entry cannot complete.
  • Re-establishes an expired session once for authenticated GET and HEAD requests when credentials are available.
  • Never automatically retries POST, PUT, PATCH, or DELETE requests.
  • Treats HTTP Basic login as authentication configuration; credentials are validated by the service on the next request.

The asynchronous API deliberately remains resource-neutral, matching the abstraction of the existing synchronous REST client. Consumers follow advertised Redfish links and interpret resource payloads according to their application requirements.

Documentation and a generic asynchronous service-root example are included.

Backward compatibility

The existing synchronous client and public API are unchanged. aiohttp, multidict, and yarl are optional and are not installed unless the aiohttp extra is selected.

A base-wheel installation was verified to import successfully without aiohttp installed.

Validation

  • The complete test suite passes on Python 3.8, 3.11, 3.12, 3.13, and 3.14.
  • Each supported Python environment passes 63 tests and 35 subtests.
  • The asynchronous package has 100% coverage across 290 statements; 52 async tests and 35 subtests pass.
  • The new asynchronous source, tests, and example pass Flake8.
  • Source distribution and wheel artifacts build successfully.
  • Both artifacts pass twine check.
  • An isolated installation with redfish[aiohttp] exposes the complete asynchronous API.
  • An isolated base-wheel installation imports successfully without aiohttp present.
  • Every commit includes the required DCO sign-off.

Live validation

The asynchronous transport was validated against a physical Redfish BMC using a caller-owned ClientSession with SHA-256 certificate fingerprint verification.

Session authentication successfully:

  1. Retrieved the service root without authentication.
  2. Created a Redfish login session at the advertised session collection.
  3. Retrieved the authenticated service root.
  4. Issued authenticated requests to advertised Redfish resources.
  5. Deleted the advertised session resource using the session token.
  6. Confirmed that Redfish logout did not close the caller-owned ClientSession.

Add a caller-owned aiohttp transport with Basic authentication, timeout handling, same-origin target validation, and cached responses. Include standard ComputerSystem discovery and advertised reset support for asynchronous consumers.

Signed-off-by: Jacob Yundt <me@jyundt.com>
jyundt added 6 commits August 15, 2026 11:11
Support standard Redfish login sessions, explicit Basic authentication, safe session cleanup, and read-only session recovery. Protect credentials and avoid retrying state-changing requests automatically.

Signed-off-by: Jacob Yundt <me@jyundt.com>
Document session authentication, Basic authentication, explicit cleanup, session recovery, and caller-owned transport behavior.

Signed-off-by: Jacob Yundt <me@jyundt.com>
Preserve restricted password-change sessions, serialize login and logout operations, and retain the existing service-root authentication workaround. Preserve all advertised reset types for forward compatibility.

Signed-off-by: Jacob Yundt <me@jyundt.com>
Clarify Basic authentication validation, password-change sessions, service-root fallback behavior, and forward-compatible reset discovery. Declare direct async dependencies explicitly.

Signed-off-by: Jacob Yundt <me@jyundt.com>
Remove ComputerSystem discovery, parsing, pagination, and reset helpers so the asynchronous API matches the generic abstraction of the existing REST client. Update documentation, examples, and tests to exercise resource-neutral operations.

Signed-off-by: Jacob Yundt <me@jyundt.com>
Exercise successful service-root decoding and rejection of malformed or non-object JSON after removing the resource-specific discovery tests.

Signed-off-by: Jacob Yundt <me@jyundt.com>
@jyundt
jyundt marked this pull request as ready for review August 15, 2026 18:21
@jyundt

jyundt commented Aug 15, 2026

Copy link
Copy Markdown
Author

@mraineri take a look when you get a chance, full disclosure: there was a lot of AI for this. Happy to make any changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Add an asynchronous aiohttp client with injectable ClientSession

1 participant