ADR-0021: Microsoft Graph SDK Choice — httpx + msal¶
Status¶
| Field | Value |
|---|---|
| Status | Accepted |
| Supersedes | — |
| Superseded by | — |
| Amends | — |
Revised 2026-06-03 in place rather than superseded — by the time the rewrite landed the ADR was unimplemented against, so there was no caller state to preserve and a superseding ADR would have added a level of indirection without aiding any reader. Per project rule, materially-changing ADRs would normally be superseded; this one was a user-authorised exception scoped to the four Graph ADRs (0021..0024).
Context¶
ID-127 adds a Microsoft Graph backend covering OneDrive (personal and business), SharePoint document libraries, and Teams files. Three credible options exist for the HTTP transport and auth library:
- Direct REST via
httpx+msal. Call the Graph HTTP surface ourselves; use Microsoft's MSAL library for token acquisition and caching. msgraph-sdk(Kiota-generated). Microsoft's official Python SDK for Graph. Async-only client. Transitive dependency onkiota-abstractions,kiota-http,kiota-authentication-azure, andazure-identity.Office365-REST-Python-Client. Third-party library that mixes Graph and legacy SharePoint REST patterns.
The surface this backend needs is narrow: a dozen Graph endpoints
covering item metadata, children listing, range download via
@microsoft.graph.downloadUrl, small-file PUT /content, resumable
upload sessions, async copy with monitor-URL polling, and delete. The
non-trivial work — upload-session chunking with resume, async-operation
polling, URL-expiry-mid-read handling — is not carried by any of these
SDKs; the backend has to write it regardless.
httpx is already in the project as an optional runtime
dependency: pip install remote-store[httpx] selects it as the HTTP
adapter for ReadOnlyHttpBackend. It is not in the base install and
no other backend pulls it transitively. msal is Microsoft's
supported auth library, lightweight, stable, and used by
azure-identity internally.
Decision¶
- Build on
httpx+msal. Usehttpx's async client for the HTTP transport andmsalfor token acquisition and cache serialization.httpxis already an optional runtime dependency, andmsalis Microsoft's supported, lightweight auth library. - Hand-written REST surface. Construct an
httpx.AsyncClientinternally and treat Graph as a narrow REST surface with hand-written request helpers, pagination, and error mapping. - Reject
msgraph-sdk. Adopting an SDK adds transitive weight (the Kiota runtime plusazure-identity) without removing the hard parts the backend must hand-write against this narrow surface regardless: resumable uploads, async-operation polling, mid-read URL refresh. Reverse if the backend later grows to a materially broader Graph surface (mail, calendar, groups), where the SDK's coverage would start to earn its weight. Office365-REST-Python-Clientout of scope. Legacy SharePoint REST is not a goal (RFC-0010).
Consequences¶
- Narrow dependency footprint.
httpx+msal+msal-extensions+platformdirsis lighter thanmsgraph-sdk+ Kiota runtime +azure-identity.httpxis not in the base install — users who install only thegraphextra pay for it once; users who already hadremote-store[httpx]forReadOnlyHttpBackendpay for nothing extra. Thegraphextra pins the exact versions inpyproject.toml, their authoritative home. - Full control of request layer. Error mapping, retry,
Retry-Afterhandling, and monitor-URL polling are written directly againsthttpx.Responseand raw status codes. No Kiota-shaped abstractions in the way. - Async-native fit.
httpx.AsyncClientis the transport; the backend implementsAsyncBackendper ADR-0012. Sync callers bridge throughAsyncBackendSyncAdapter(ADR-0025) — already landed and the conformance suite is parameterised for it. - Maintenance responsibility stays with us. The Graph drives /
items v1.0 surface is stable; ongoing churn is expected to be low.
Re-evaluating
msgraph-sdkbegins at the Decision's reverse trigger (a materially broader Graph surface) and would supersede this ADR.
References¶
- RFC-0010: Microsoft Graph Backend (SDK evaluation section)
sdd/specs/044-graph-backend.md- ADR-0012: Async Store / Backend API
- ADR-0025: Async-to-Sync Backend Adapter
httpxproject: https://www.python-httpx.org/- MSAL for Python: https://learn.microsoft.com/entra/msal/python/
- Microsoft Graph v1.0 reference: https://learn.microsoft.com/graph/api/overview